I created a plugin that sets up a custom route and then loads a template file for that url. Everything works fine, except that WordPress seems to think it's a 404 even though it's correctly rendering my template.
For instance it says 404 in the document title and an error404
class is added to <body>
The custom url is domain/path/:id where :id
is a dynamic value corresponding to a post id, so the URL could be domain/path/275. In the example below some_id
is used as the post id variable.
Here's a reduced version of my plugin:
<?php
class MyPlugin {
public function __construct() {
add_action( 'init', array($this, 'add_response_endpoint') );
add_filter( 'template_include', array($this, 'add_response_template') );
}
public function add_response_endpoint() {
add_rewrite_rule(
'^path/([0-9]+)/?',
'index.php?pagename=my_custom_url&some_id=$matches[1]',
'top'
);
add_rewrite_tag('%some_id%', '([^&]+)');
}
public function add_response_template($template) {
if ( get_query_var( 'pagename' ) === 'my_custom_url' ) {
$template = trailingslashit( dirname( __FILE__ ) ) . 'templates/custom-page-template.php';
}
return $template;
}
}
new MyPlugin();
Am I missing something here? Or should I start looking for this bug elsewhere?
I created a plugin that sets up a custom route and then loads a template file for that url. Everything works fine, except that WordPress seems to think it's a 404 even though it's correctly rendering my template.
For instance it says 404 in the document title and an error404
class is added to <body>
The custom url is domain/path/:id where :id
is a dynamic value corresponding to a post id, so the URL could be domain/path/275. In the example below some_id
is used as the post id variable.
Here's a reduced version of my plugin:
<?php
class MyPlugin {
public function __construct() {
add_action( 'init', array($this, 'add_response_endpoint') );
add_filter( 'template_include', array($this, 'add_response_template') );
}
public function add_response_endpoint() {
add_rewrite_rule(
'^path/([0-9]+)/?',
'index.php?pagename=my_custom_url&some_id=$matches[1]',
'top'
);
add_rewrite_tag('%some_id%', '([^&]+)');
}
public function add_response_template($template) {
if ( get_query_var( 'pagename' ) === 'my_custom_url' ) {
$template = trailingslashit( dirname( __FILE__ ) ) . 'templates/custom-page-template.php';
}
return $template;
}
}
new MyPlugin();
Am I missing something here? Or should I start looking for this bug elsewhere?
Share Improve this question asked Jun 1, 2016 at 12:03 AhrengotAhrengot 4425 silver badges14 bronze badges 5 |2 Answers
Reset to default 3Manually setting is_404 = false;
fixed my issue. However I'm not sure this is the best way to do it. I tried using the pre_get_posts
filter instead without any luck.
Anyway, for anyone else in the same boat, you can do this to get rid of the 404 state:
public function add_response_template($template) {
global $wp_query;
if ( 'my_custom_url' === get_query_var( 'pagename' ) ) {
$wp_query->is_404 = false;
$template = trailingslashit( dirname( __FILE__ ) ) . 'templates/custom-page-template.php';
}
return $template;
}
And to update the document title (The stuff inside <title>
in the <head>
section) here's a snippet for making that work nicely too.
add_filter( 'document_title_parts', function($title_arr) {
if ( 'my_custom_url' === get_query_var('pagename') ) {
$title_arr['title'] = "Document title for my custom route";
}
return $title_arr;
}, 10, 1 );
If anyone knows of a better way please let me know.
I have not found custom routes in WP mature enough. I suggest you use any of the 3 routes solutions mentioned in Timber docs. https://timber.github.io/docs/v2/guides/routing/
if you use Upstatement library (https://github/Upstatement/routes) you would do:
Routes::map('info/:name/page/:pg', function($params){
//make a custom query based on incoming path and run it...
$query = 'posts_per_page=3&post_type='.$params['name'].'&paged='.intval($params['pg']);
//load up a template which will use that query
Routes::load('archive.php', null, $query, 200);
});
See the 200 in Routes::load, that sends the proper header.
If you need something more versatile use Rareloop router https://github/Rareloop/router
my_custom_url
is not the slug of an actual page, you will get a 404. Ifsome_id
is a valid post ID, then set the correct native query vars with that ID so the query succeeds. – Milo Commented Mar 1, 2017 at 16:08