Blog

A collection of musings about technology, animation, and design.

For many sites, it’s practical to use some sort of routing system that allows you to easily define routes programmatically. One great option for this is JetRouter, a self-described “lightning fast, easy to use router for WordPress.” By default, the admin bar won’t show up on any pages defined via JetRouter. Thankfully, there’s an easy fix!

Adding a basic, non-page-specific admin bar

The reason that the admin bar doesn’t show up by default is that, when using JetRouter, you’re bypassing the standard WordPress template hierarchy. That means that the template_redirect action isn’t being “done”. A quick dive into /wp-includes/default-filters.php will reveal that the admin bar is set up within the template_redirect action:

// Admin Bar
// Don't remove. Wrong way to disable.
add_action( 'template_redirect', '_wp_admin_bar_init', 0 );
add_action( 'admin_init', '_wp_admin_bar_init' );
add_action( 'before_signup_header', '_wp_admin_bar_init' );
add_action( 'activate_header', '_wp_admin_bar_init' );
add_action( 'wp_footer', 'wp_admin_bar_render', 1000 );
add_action( 'in_admin_header', 'wp_admin_bar_render', 0 );

That means that in order to display a basic admin bar for a JetRouter route, all we need to do is “do” the template_redirect action, like so:

$r->get( 'my-route', 'my_route', function() {
    do_action( 'template_redirect' );
    echo "How neat is that?";
    exit;
} );

Relating the admin bar to a specific page or post

You’ve probably noticed that usually, when you visit pages or posts on your site, there’s an “Edit Page” or “Edit Post” link in the admin bar that allows you to immediately edit the page/post you’re viewing. Using the method above (simplying adding the template_redirect action), you won’t get that edit link in the admin bar.

Of course, most of the time it probably doesn’t make sense to show an Edit link; the fact that it’s a JetRouter route probably means there isn’t a post that’s contextually tied to the route you’re on. But at some point there might be some cases where you actually are showing a specific page or post—you’re just using JetRouter to do it—and you want to display that edit link. For example, in one of my projects I had separate routes for a public blog and a private blog, and I used JetRouter to define my public blog routes. Because I was using JetRouter to serve those public blog posts, there were posts tied to each URL, but because they were served with JetRouter, there was no “Edit” link on them.

In cases like these, we can manually set the post/page/cpt context like this:

$r->get( 'public/blog/{slug:s}', 'public_post', function( $slug ) {
    global $wp_query;
    global $wp_the_query;

    $args = array(
        'post_type' => 'post',
        'name' => $slug,
        'posts_per_page' => 1
    );

    $post_query = new WP_Query( $args );

    // Here's where the magic happens: we're setting the global query.
    $wp_query = $post_query;
    $wp_the_query = $post_query;

    include ( get_stylesheet_directory() . '/single.php' );
} );

Now you’ll get a nice “Edit” button in the admin bar that allows you to edit the page selected in the query.