Brain-WP / Cortex

Routing system for WordPress
MIT License
348 stars 20 forks source link

How to add body classes depending on a Cortex route - the right way. #24

Closed wujekbogdan closed 2 years ago

wujekbogdan commented 6 years ago

I know that I could use do_action('my_custom_action') / did_action('my_custom_action') check as follows:

add_action('cortex.routes', function (RouteCollectionInterface $routes) {
    $routes->addRoute(new QueryRoute(
        '/my/route',
        function (array $matches) {
            do_action('my_custom_action');
            return [
                // params
            ];
        }
    ));
});

add_filter('body_class', function ($classes) {
    if (!did_action('my_custom_action')) {
        return $classes;
    }

    return array_merge($classes, ['my_class']);
});

or I could add some custom query variable and then add custom classes depending on the query variable existence... but none of these methods sound right to me.

Is there a more elegant way?

gmazzap commented 6 years ago

Hi @wujekbogdan

If it something that you want to do for all matched routes you could use 'cortex.matched' or 'cortex.matched-after', something similar to:

use Brain\Cortex\Router\MatchingResult;

add_action('cortex.matched', function(MatchingResult $results) {

    $route = $results->route();
    $matches = $results->matches();
    $matchedPath = $results->matchedPath();
    $template = $results->template();

    // calculate classes here based  on info above...
    $customClasses = [];

    add_filter('body_class', function ($classes) use ($customClasses) {
        return array_merge($classes, $customClasses);
    });

});

If it is something that you want to do only for specific routes, that could be done via an "after" Route callback.

namespace Wujekbogdan\Project;

/**
 * @param array $vars
 * @param \WP $wp
 * @param string|false $template
 * @param array $matches
 */
function setupBodyClassesForRoute(array $vars, \WP $wp, $template, array $matches) {

    // calculate classes here based parameters
    $customClasses = [];

    add_filter('body_class', function ($classes) use ($customClasses) {
        return array_merge($classes, $customClasses);
    });
}

$routes->addRoute(new QueryRoute(
        '/my/route',
        function (array $matches) {
            return [
                // params
            ];
        },
        [
            'after' => 'Wujekbogdan\Project\setupBodyClassesForRoute'
        ]
    ));
wujekbogdan commented 6 years ago

@gmazzap Thank you very much for a very comprehensive response. The second solution is exactly what I was looking for - much cleaner than a solution based on did_action that I came up with :)