0

I have a Page Template, page-services.php, which displays content in various tabs. The page's URI is currently example.com/services.

I want each tab to have its own permalink so that visiting a URI like example.com/services/tab-1 displays the Services page with "Tab 1" automatically active.

I've accomplished this so far by (1) adding a rewrite rule for any Services Page Template, (2) adding a custom rewrite tag, and (3) using the rewrite tag (query var) in the page template to set the active tab accordingly.

Here are my rewrite customizations:

<?php

function custom_tab_rewrites_and_tag() {
  add_rewrite_tag('%service_tab%', '([^&]+)');

  $services_pages = new \WP_Query(array(
    'post_type'      => 'page',
    'meta_key'       => '_wp_page_template',
    'meta_value'     => 'page-services.php',
    'posts_per_page' => -1
  ));

  foreach($services_pages->posts as $p) {
    add_rewrite_rule('^'.$p->post_name.'/([^/]+)/?$', 'index.php?page_id='.$p->ID.'&service_tab=$matches[1]', 'top');
  }

}
add_action('init', __NAMESPACE__.'\\custom_tab_rewrites_and_tag');

?>

This setup works flawlessly on the Services page. However, this is a reusable Page Template and there could ultimately be multiple Services pages, each with different tabs.

The problem: When I add a new Page using the Services Page Template, my tab rewrites only work for that new Page if I flush my permalinks. I can do that in my rewrite function or on save_post, but neither of those are appealing, not to mention it's inefficient. I don't want to flush permalinks each time a new Service page is added and I suspect there may be a more efficient way to accomplish a setup like this. I may be overcomplicating this or overlooking something.

If anyone has pointers I'd greatly appreciate some input on a better way to accomplish this while maintaining this URI structure for this Page Template's tabs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.