Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Atanas Angelov
    @atanas-dev
    The pagination logging you see is possibly from the browser preloading the next page or some similar behavior (i.e. it's most likely a separate request, not the controller being run twice on the same request). You'll have to look into what generated the pagination URLs and filter it as needed. Other than that I can't really investigate this without exact steps to reproduce / a minimal reproduce case.
    No changes related to routing have been made in 0.16.1.
    Calvin Alkan
    @calvinalkan

    This is config that is specific and necessary to the app core which is distributed with the starter plugin and theme - https://github.com/htmlburger/wpemerge-app-core
    The App Core package provides common utilities like image resizing on the fly, asset loading utilities, config.json handling etc. - check out the Utilities section in the docs here: https://docs.wpemerge.com/#/starter/utilities/assets

    got it. Should path and url properties reference the plugin root directory? I moved the config file a bit.

    Atanas Angelov
    @atanas-dev
    Yes, they should reference the root directory and main plugin file, respectively.
    Tom K.
    @tomkeysers
    @atanas-dev bumping up the 'Blog pages show at most' under wp settings > Reading seems to do the trick. It's an ugly and temporary fix, but I have frankly no clue what could cause the request to the second page. But it'll do for now :)
    Calvin Alkan
    @calvinalkan
    Thank you, @atanas-dev When I did run the unit test scafolling I remeber that there was some test case with boilerplate code generated where its shown how to alias, replace or mock the application instance. But since I dont use the inbuilt suite I cant remeber what it was and I could not find it in the docs. Do you happen to now where I could find this file or the examples?
    Luc D
    @LucArthos_gitlab
    hey all, hope you're doing well. i need a bit of help to debug a jQuery problem. with WPEmerge theme v0.16.2, i'm using Elementor, and tried to use a simple counter (numbers going from 0 to the defined one, with the help of a javascript function) on a page, but nothing happens, and i have an error in the console (Uncaught TypeError: e.elements.$counterNumber.numerator is not a function). i've tried to use that one on a premade theme (OceanWP) and the error doesn't show. i guess it's a conflict with jQuery, but what can it be? (jQuery.fn.jquery "3.5.1")
    Luc D
    @LucArthos_gitlab
    ok, might be that the jQuery version with OceanWP is 1.12.14 and a version too advanced may break things. gonna try something else.
    Calvin Alkan
    @calvinalkan

    @atanas-dev Hey Atanas, during the last week I worked on a fork of WP Emerge that replaces every reference of the concrete pimple container with a container interface. I did this so we can leverage better containers like illuminate/container. I also coded a simple adapter around the pimple container so it can still be used flawlessly as a default container with WP Emerge. Minimal changes were done to the source code and everything is non-breaking. The only changes in the core are changing every implementation of the pimple container to are container interface and refactoring the GenericFactory Class so it uses the container interface.

    I already did an integration for the laravel container as that's what I'm using and everything works flawlessly. Zero Configuration Resolution etc.
    The only change needed for client code to swap containers is to pass an optional implementation of the containerinterface into the App::make() Facade before bootstrapping. If nothing is passed the default pimple container will be used like before.

    Are you open to implementing this in WP Emerge so I can commit a proper pull request?

    Greetings.

    11 replies
    Atanas Angelov
    @atanas-dev
    @calvinalkan thanks for exploring that option! I can't absolutely guarantee this will be merged but I'm definitely interested :)
    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