0

A colleague and I are working on a custom theme and one of the things we need to do is push a specific custom URL type (/team/ for example) into the backend of our website(/wp-content/themes/custom_theme/page-templates/team.php). We're trying to use url rewriting as described in this article.

The theme's functions.php contains the following code, which we've proved is running (debug() does that).

function themes_dir_add_rewrites() {
   $theme_name = next(explode('/themes/', get_stylesheet_directory()));
   global $wp_rewrite;
   $new_non_wp_rules = array('team/.*'=> 'wp-content/themes/'. $theme_name . '/page-templates/team.php',);
   debug(print_r($new_non_wp_rules, true)."\n");
   $wp_rewrite->non_wp_rules = array_merge($wp_rewrite->non_wp_rules,$new_non_wp_rules);
 }
 add_action('generate_rewrite_rules', 'themes_dir_add_rewrites');

We run this by going to the rewrite rules in the WordPress back-end and saving them. This runs the above code (debug() function call fires), and in theory and flushing/rewriting the rules. However, the redirect isn't working, and browsing to /team/ simply calls the 404.php page template instead of going where we want it to. We added some code to the 404.php page as follows to see if we can see anything:

global $wp_rewrite;
echo "<pre>";
print_r($wp_rewrite->non_wp_rules);
print_r($wp_rewrite->rules);
echo "</pre>";
?>

This duly prints out the two data structures, however $wp_rewrite->non_wp_rules is empty (null). $wp_rewrite->rules has all the usual wordpress defaults. We are running a DevKinsta development environment. Any pointers as to what might be going on, or even how to debug further would be most welcome. First step would seem to be getting an entry to stick in $wp_rewrite->non_wp_rules. Thanks in advance.

Update:

To explain further what we are doing... One of the theme settings pages in the back-end looks like this:

enter image description here

We would like the theme user to be able to select between static pages which they create, or the 3 built-in pages we have in the theme for these functions. If the Theme Default is chosen in the drop-downs (see Customers above), then our url rewrites would apply and "/contact/", "/team/", and "/customers/" would render the respective built-in page without changing the url.

5
  • What is at example.com/team URL? Is it one of the pages created in the WordPress dashboard, and you want it to look different than the others (use a different template file)? Maybe the template hierarchy solves your problem, but I'm not sure what you want to do.
    – nmr
    Commented Feb 27, 2023 at 10:36
  • As for merging arrays, it's better to use the array_merge function, the + operator works differently than you might think.
    – nmr
    Commented Feb 27, 2023 at 10:42
  • Have you checked your .htaccess file to see if there's a line containing a RewriteRule ^team/.* /wp-content/themes/...? Are you sure you visited /team/ and not /team (no ending slash)? If it's the latter, then your regex was not allowing that, hence it's normal if you saw 404 at /team. And it's also normal that the $wp_rewrite->non_wp_rules was empty on your 404 pages, because generate_rewrite_rules runs only when generating the rewrite rules which would not happen on 404 pages...
    – Sally CJ
    Commented Feb 27, 2023 at 13:56
  • OK, so because we're using DevKinsta, I believe the webserver is nginx. There is no .htaccess file in the root web directory, and frankly we're not sure how wordpress is saving the rewrite rules. We also can't use the template hierarchy for this functionality. I've updated the post to explain this further.
    – Andrew
    Commented Feb 27, 2023 at 15:57
  • Code updated to use array_merge. No change in behavior.
    – Andrew
    Commented Feb 27, 2023 at 16:28

1 Answer 1

0

Here's a solution to the problem. Not sure it's the best one, but it does work. From lots of reading and a bit of poking around in the wordpress core (code), it seems that non_wp rewrite rules only work on Apache. DevKinsta is Nginx-based, and there's precious little out there at this deep level on any of the tech blogs, stackExchange, or stackOverflow.

Anyway, I ditched all the previous rewrite code and used the following instead:

//catch "/contact/", "/customers/", and "/team/" in the URL and pull content from the built-in templates
function templates_callback( $original_template ) {
    $theme_name = next(explode('/themes/', get_stylesheet_directory()));
    $url = $_SERVER['REQUEST_URI'];
    //FIXME the logic below needs to be extended to check for the dropdown setting of each page
    //in the themes setting page. If the setting is default, return the template as configured 
    //below. If there's another page selected, return that page instead
    if (preg_match('/\/team\//',$url)) {
        return 'wp-content/themes/'. $theme_name . '/page-templates/team.php';
    }elseif(preg_match('/\/contact\//',$url)){
        return 'wp-content/themes/'. $theme_name . '/page-templates/contact.php';
    }elseif(preg_match('/\/customers\//',$url)){
        return 'wp-content/themes/'. $theme_name . '/page-templates/customers.php';
    }else {
        return $original_template;
    }
}
add_filter( 'template_include', 'templates_callback' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.