Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Calvin Alkan
    @calvinalkan

    cool. Starting tomorrow I will have very limited availability for a few weeks and I could not prepare a proper PR yet. Im sure there will be some unit tests that fail because you most probably mocked the container everywhere etc.

    In the meantime I will pass you the link to the updated repository so you can have a look and let me now what you think.

    https://github.com/calvinalkan/wpemerge

    I had to do some more changes but now everything is integrated.
    The main changes are:

    • replacement of the pimple container for an interface called containerAdapater. Every container can be implemented in wpemerge now as long as the interface is implemented correctly. I already made to adapters, one for pimple which is included in the repo and one for laravel which I will share as a composer package aswell. Its really awesome. All the features work now. Autoresolving dependencies without a service container, autoresolving controller methods etc.
    • The HTPP Kernel class has some small additions. It passes a closure to the execute function of the handler class that gives very limited access to resolve a controller method from the container adapter. The closure gets received from the adapter interface. In case of the pimple adapter the default implementation was just moved from the handler into the adapter closure.
    • The generic factory now receives an instance of the container adapter instead of the container instance.
    • The App::make facade now accepts an optional implementation of the adapter interface and will default to the pimple adapter if nothing is provided.
    • In the config.php the wpermerge.some.random.value constants have been changed for keys that resolve object from the container. Where possible an interface:class value is used now and if not the classname:class value. This does not affect wpemerge internals but its making creating container adapters way easier since translating these random strings into classes is a pain with auto resolving containers. This also follows common container usage where an interface is defined as the key and later an concrete implementation is registered in a service provider.
    Let me know what you think
    Jennifer Eberlei
    @jennifer.eberlei_gitlab

    Hi there, I just found wpemerge yesterday and I am trying to get my hands on that. I have never really worked with MVCs before, so I am trying to understand as much as possible from the documentation, but right now I am facing the following challenge:

    I have downloaded the starter theme and I am trying to register custom routes.

    From the documentation I thought it might be best to add a new route to the configuration instead of working inside the "web" part.

    So I altered this part:

    \App::make()->bootstrap( [
        'routes' => [
            // Assuming your route files are created in /wp-content/themes/my-theme/routes/
            'web'   => [
                'definitions' => get_template_directory() . '/routes/web.php',
            ],
            'admin' => [
                'definitions' => get_template_directory() . '/routes/admin.php',
            ],
            'ajax'  => [
                'definitions' => get_template_directory() . '/routes/ajax.php',
            ],
            'directory' => [
                 'definitions' => get_template_directory() . '/routes/directory.php';
            ]
        ],
        // ... other options go here
    ] );

    I added my directory Controller and in my directory.php I have the following:

    \Racom::route()->get()->url( '/verzeichnis' )->handle( 'Directory_Controller@index' );;

    And this is my Controller:

     namespace Racom\Controllers\Directory;
    
    class DIRECTORY_CONTROLLER {
        public function index( $request, $view ) {
            return \Racom::view( 'templates/directory/index.php' );
            // return \Racom::redirect()->to( home_url( '/' ) );
            // return \Racom::error( 404 );
            // return \Racom::output( 'Hello World!' ); // same as returning a string
            // return \Racom::json( ['foo' => 'bar'] ); // same as returning an array
            // return \Racom::response(); // a blank response object
        }
    }

    but when I open '/verzeichnis' on my localhost I still get a 404 :/

    Did I miss something or maybe have to add something somewhere else? Can I wonly work within web, admin and ajax or ... am I just not getting the point ? lol
    Calvin Alkan
    @calvinalkan
    The routes are hardcoded, ( @atanas-dev pls confirm ) you can use web,admin and ajax and tbh I dont see why you would need another one. Your route /verzeichnis is handled by the *web group" which by default will look for controllers in the Racom\Controllers\Web namespace so its not finding your Controller since you have a Different namespace. You can change the default namespace for every group in the config using the namespace key.
    Jennifer Eberlei
    @jennifer.eberlei_gitlab

    so instead of

     \Racom::route()->all();

    i do this in web.php?
    \Racom::route()->get()->url( '/verzeichnis' )->handle( 'DirectoryController@index' );

    Jennifer Eberlei
    @jennifer.eberlei_gitlab

    Basically my Idea was to do routes like...
    /directory -> display a list of all countries that are assigned to a user (data is available)
    /directory/{country}/ -> display a list of all users within that country
    /directory/{country}/{city} -> display a list of all users within that city

    in my DirectoryController I wanted to have one view with different outputs dependent on the country or city

    But I wonder if it makes sense to always direct to the same view and handle the output in the view or make different views per request
    Jennifer Eberlei
    @jennifer.eberlei_gitlab
    So I did this...
    \Racom::route()->get()->url( '/verzeichnis/{country?}/{city?}' )->handle( 'DirectoryController@index' );
    but I am stuck thinking: Ok how do I check that country is actually a country and city is actually a city
    Atanas Angelov
    @atanas-dev

    Hi @jennifer.eberlei_gitlab ,

    What Calvin said is right - there are 3 main groups of routes that are supported in WP Emerge - Web (front end if you will), Admin (under /wp-admin/) and AJAX (handled via WordPress' AJAX hooks).
    For your use case (and most) web.php is the file to use so you'd want to place \Racom::route()->get()->url( '/verzeichnis/{country?}/{city?}' )->handle( 'DirectoryController@index' ); in that file but above the \Racom::route()->all(); line as the comment warns.

    Ok how do I check that country is actually a country and city is actually a city

    This type of validation you can do inside your controller method, so something like this is what I imagine you'd need:

    // Note that URL parameters are automatically passed to your controller method as extra arguments.
    // You can check out the docs which mention this here: https://docs.wpemerge.com/#/framework/routing/conditions?id=url
    public function index( $request, $view, $country, $city ) {
        // Assuming you have an is_city_valid() function:
        if ( ! empty( $city ) && ! is_city_valid( $city ) ) {
            return \Racom::error( 404 );
        }
    
        // Assuming you have an is_country_valid() function:
        if ( ! empty( $country ) && ! is_country_valid( $country ) ) {
            return \Racom::error( 404 );
        }
    
        // Assuming you'll need both $country and $city in your view:
        return \Racom::view( 'templates/directory/index.php' )
            ->with( [
                'country' => $country,
                'city' => $city,
            ] );
    }
    Calvin Alkan
    @calvinalkan
    @atanas-dev btw, I forgot it, I also have created a WpEmerge facade class (not included in the repo) that has that behaves exactly like laravel facades buts its just one class without any illuminate dependecies at all. Every feature forks tho including the mocking and spying of facades although they are static. Might be something thats worth considering aswell
    Atanas Angelov
    @atanas-dev
    Multiple facades were previously used but removed as they only make sense in a one-app environment which WordPress is not as multiple plugins can use WP Emerge simultaneously and must not conflict.
    Note that your main App class is itself a sort of facade to your app and has magic methods. All App::*() methods are aliases and you can add your own in your service providers e.g. https://github.com/htmlburger/wpemerge/blob/master/src/Routing/RoutingServiceProvider.php#L94-L96
    Aliasing is how you can stub out App::*() methods or the entire app during unit tests as well (examples can be seen in the scaffolded tests or in the changelog for 0.16.0 - https://github.com/htmlburger/wpemerge/releases/tag/0.16.0)
    Calvin Alkan
    @calvinalkan
    I was aware of the aliasing, and as I understand it its neccesary to bin the aliases to the app class his multiple plugins can use wpemerge without conflicting like App1::route , App2::route. Im using this to create facades for some of my own classes in the Service container. App::database::doSomething is just not quite as nice as calling DB::doSomething. But yea its not necessary, just personal perference I guess.
    Jennifer Eberlei
    @jennifer.eberlei_gitlab

    So I created a folder templatesin the root folder of the theme and a subfolder called directoryand then in my route I want to do this like suggested:

       return \Racom::view( 'templates/directory/index.php' )
            ->with( [
                'country' => $country,
                'city' => $city,
            ] );

    but when I var_dump $view in my route it still gives me the 404 template.

    even though it shouldn't
    class DirectoryController {
        public function index( $request, $view, $country, $city ) {
            var_dump($view);
            var_dump($country);
            if (!empty($country) && !is_country_valid($country)) {
                return \Racom::error(404);
            }
            return \Racom::view( 'templates/directory/index.php' )->with(['country' => $country, 'city' => $city]);
        }
    }
    I checked if my if condition is correct (which it is)
    Atanas Angelov
    @atanas-dev
    $view is what WordPress thinks it should load - by returning \Racom::view( 'some-template.php' ) you are overriding that.
    (since your custom URL structure is not known to WordPress it defaults to 404)
    Calvin Alkan
    @calvinalkan
    @jennifer.eberlei_gitlab you have some misconceptions about how this works. And it was the same for me (check the amount of questions I bothered @atanas-dev with a little more up the chat). To be honest the best advise I could give you is to get a subscriptions of laracasts and watch the laravel from scratch series. Its about laravel but explains all the core concepts of the MVC pattern and the syntax is almost the same because wpemerge is so heavily inspired by laravel.
    Thats what made it click for me
    Jennifer Eberlei
    @jennifer.eberlei_gitlab
    Thank you @calvinalkan I will take a look at that
    I got the basics working so far, thank you for your help
    Calvin Alkan
    @calvinalkan

    @atanas-dev Could you explain a use case for an admin route? I always thought what happens is that you could override the callback function defined in add_menu_page for a specific admin page. However, after studying the code this it seems like this is not the case but instead we send headers from the request and the body from or view (if there is any view loaded ) straight to the client. When I tried some routes it seems like nothing is happening at all. (Might be because WordPress still loads the default admin view. )

    Maybe I'm not getting the admin routes quite right. Hope you can share some insights.

    Atanas Angelov
    @atanas-dev

    Admin routes check for the registered page slug. The request is then split - headers are sent during do_action( "load-{$hook_suffix}" ) and the view is output during do_action( $hook_suffix ) where $hook_suffix is a hook name that WordPress generates based on your admin page slug.
    The above means that headers will be sent correctly before any output and your view will be embedded inside the default admin page (where the usual add_menu_page callback runs).

    An important note: Admin routes are currently only meant to be used with custom admin pages i.e. ones registered using add_menu_page and add_submenu_page, not core admin pages.

    Calvin Alkan
    @calvinalkan

    Ah ok got it, so the do_action( $hook_suffix )takes care of the placing the content in the correct place I assume.

    Btw, is there any reason that im missing for why admin/ajax handlers do need to get passed a $view variable. Its always empty since only the "web function" inside the kernel passes the view as an optional argument to the handle method.

    Atanas Angelov
    @atanas-dev
    There's no default view that WordPress tries to load during ajax requests. The empty value is passed for consistency.
    Calvin Alkan
    @calvinalkan

    got it. I'll strip it out in the container implementation since every controller, middleware, etc gets resolved automatically.

    Another thing, is there a way we could allow for the extension of the error handler in a custom service provider?
    So far there are only CsrfException and NotFoundException that we can catch when we push something through the HTTP-Kernal process

    protected function toResponse( $exception ) {
    
            // @codeCoverageIgnoreStart
    
            if ( $exception instanceof InvalidCsrfTokenException ) {
    
                wp_nonce_ays( '' );
    
            }
    
            // @codeCoverageIgnoreEnd
    
    
    
            if ( $exception instanceof NotFoundException ) {
    
                return $this->response_service->error( 404 );
    
            }
    
    
    
            return false;
    
        }
    Atanas Angelov
    @atanas-dev
    You are free to extend it or write your own to fit your needs and replace it in the container :) It wasn't meant as an extension point, rather a minimal useful handler that is replaceable.
    Calvin Alkan
    @calvinalkan
    Ahh , yea I did not think about replacing in the comtainer. Ty.
    Jennifer Eberlei
    @jennifer.eberlei_gitlab

    Hey there, if I wanted to add acf to wpemerge, would i do that with its own service provider? would that make sense?

    I was thinking that widgets, and sidebars, and menus and such are provided via a service provider so I was wondering if it would make sense to do the same for registering custom fields with acf

    Atanas Angelov
    @atanas-dev
    Sure :)
    Jennifer Eberlei
    @jennifer.eberlei_gitlab
    In the sense of the starter themes logic, what would be the best way to make page templates?
    eg. the index uses the default layout, which is in app.php but if I want to create different page templates, would I still create files in the root theme folder for eg. template-test.php and have the normal layout applied, but am able to differ parts?
    Atanas Angelov
    @atanas-dev
    If it's custom page templates, I would put them in views/. If it's core templates like index.php, page.php, single.php, archive.php etc. I would put them in the root of the theme.
    You are free to swap out parts, create multiple layouts or not use a layout at all for one, some or all of your templates. It's a preference thing and it's a way to not duplicate code that is shared between templates so it depends on your templates.
    David Towoju
    @davexpression

    Hi, thanks for this plugin/framework.
    I keep getting "Unknown named parameter $menu"

    \App::route()->get()->where( 'admin', 'top-level-slug' )->handle( 'Controller@index' );

    Please help

    David Towoju
    @davexpression
    @atanas-dev
    Atanas Angelov
    @atanas-dev
    Hi @davexpression , at the very least I'm going to need the stack trace in order to help.
    Jennifer Eberlei
    @jennifer.eberlei_gitlab

    Hi, I tried to add woocommerce styles to the theme seperately from admin|frontend|login and edited the config.json and the AssetsServiceProvider.php like this:
    config.json

      "bundles": [
        "frontend",
        "admin",
        "login",
        "editor",
        "woocommerce"
      ],

    AssetsServiceProvider.php:

    /**
         * Enqueue woocommerce assets.
         *
         * @return void
         */
        public function enqueueWoocommerceAssets() {
            // Enqueue scripts.
            \Racom::core()->assets()->enqueueScript(
                'theme-woocommerce-js-bundle',
                \Racom::core()->assets()->getBundleUrl( 'woocommerce', '.js' ),
                [ 'jquery' ],
                true
            );
    
            // Enqueue styles.
            $style = \Racom::core()->assets()->getBundleUrl( 'woocommerce', '.css' );
    
            if ( $style ) {
                \Racom::core()->assets()->enqueueStyle(
                    'theme-woocommerce-css-bundle',
                    $style
                );
            }
    
            // Enqueue theme's style.css file to allow overrides for the bundled styles.
            \Racom::core()->assets()->enqueueStyle( 'theme-woocommerce-styles', get_template_directory_uri() . '/woocommerce.css' );
        }
    but only the woocommerce.js is being processed on yarn build, i don't get a theme-woocommerce.css even though I created the corresponding files in ressources/styles/woocommerce/index.scss
    so I wonder if I missed a configuration?
    I looked into the webpack build files and could't find any hint on where else I would have to configure
    image.png
    Atanas Angelov
    @atanas-dev
    Could you paste the contents of your woocommerce.js file? On the top of my head the most likely cause is that your css/scss is not imported in it.
    Branislav Stojanovic
    @djex808

    @atanas-dev Great work and thanks a lot for the framework. Looking forward to use it on my projects. Can somebody help me with why I am getting "Unknown named parameter $post_id" when post_id has been matched in web.php? Same for post_slug, post_status...

    Error thrown with message "Unknown named parameter $post_id"

    #20 Error in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:177
    #19 call_user_func_array in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:177
    #18 WPEmerge\Kernels\HttpKernel:executeHandler in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:205
    #17 WPEmerge\Kernels\HttpKernel:WPEmerge\Kernels\{closure} in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:40
    #16 WPEmerge\Kernels\HttpKernel:executeMiddleware in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:44
    #15 WPEmerge\Kernels\HttpKernel:WPEmerge\Middleware\{closure} in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Input/OldInputMiddleware.php:44
    #14 WPEmerge\Input\OldInputMiddleware:handle in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
    #13 call_user_func_array in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
    #12 WPEmerge\Kernels\HttpKernel:executeMiddleware in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:44
    #11 WPEmerge\Kernels\HttpKernel:WPEmerge\Middleware\{closure} in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Flash/FlashMiddleware.php:40
    #10 WPEmerge\Flash\FlashMiddleware:handle in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
    #9 call_user_func_array in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Middleware/ExecutesMiddlewareTrait.php:53
    #8 WPEmerge\Kernels\HttpKernel:executeMiddleware in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:206
    #7 WPEmerge\Kernels\HttpKernel:run in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:237
    #6 WPEmerge\Kernels\HttpKernel:handle in /Users/banestojanovic/Code/Manastiri/podmaine/wp-content/themes/podmaine/vendor/htmlburger/wpemerge/src/Kernels/HttpKernel.php:332
    #5 WPEmerge\Kernels\HttpKernel:filterTemplateInclude in /Users/banestojanovic/Code/Manastiri/podmaine/wp-includes/class-wp-hook.php:292
    #4 WP_Hook:apply_filters in /Users/banestojanovic/Code/Manastiri/podmaine/wp-includes/plugin.php:212
    #3 apply_filters in /Users/banestojanovic/Code/Manastiri/podmaine/wp-includes/template-loader.php:104
    #2 require_once in /Users/banestojanovic/Code/Manastiri/podmaine/wp-blog-header.php:19
    #1 require in /Users/banestojanovic/Code/Manastiri/podmaine/index.php:17
    #0 require in /Users/banestojanovic/.composer/vendor/laravel/valet/server.php:219
    Atanas Angelov
    @atanas-dev
    Hi @djex808 ,
    This looks like a PHP 8 issue - do you mind sharing your route definition that triggers this error?
    Branislav Stojanovic
    @djex808
    @atanas-dev You were completely right as it was indeed PHP 8 issue. I forgot to change the PHP version in valet - didn't even knew that I could do it there to be honest and it kept loading version 8 while terminal kept displaying 7.4.16. Sorry for the trouble :)
    Atanas Angelov
    @atanas-dev
    No worries - while PHP 8 is still not officially supported it should be so in the near future.
    David Towoju
    @davexpression

    Hi @davexpression , at the very least I'm going to need the stack trace in order to help.

    It's a PHP 8 issue, it works in PHP 7