Seems like a good candidate for add_rewrite_endpoint()
.
add_rewrite_endpoint( \'items\', EP_ROOT, \'item_id\' );
That will register the endpoint /items/<item ID>
and also registers the query var item_id
, and eliminates the 404 status header/title as well. But the page title would be the site name and you\'d probably still want to hook to pre_get_document_title
to customize the title.
And your class would be simpler:
class FeedPlugin {
public function __construct() {
add_action( \'init\', [ $this, \'add_rewrite_endpoint\' ] );
add_action( \'template_redirect\', [ $this, \'addTemplate\' ] );
}
public function add_rewrite_endpoint() {
add_rewrite_endpoint( \'items\', EP_ROOT, \'item_id\' );
}
public function addTemplate() {
if ( $item_id = get_query_var( \'item_id\' ) ) {
/* your code here:
echo \'Yay, it works! Item ID: \' . $item_id;
exit;
*/
}
}
}
Don\'t forget to flush the rewrite rules — just visit the permalink settings page.
UPDATE
how can I specify what is valid for release_id
e.g [0-9A-Z]+
So I believe you meant item_id
when you said release_id
?
And (at the moment) there\'s no "standard"/easy way to specify the preferred RegEx pattern for an endpoint added using add_rewrite_endpoint()
, so if you need a custom RegEx pattern, it\'s actually better to use add_rewrite_rule()
. :)
And here\'s how you can prevent the 404 error with your original code.
I believe you know it happens because you\'re querying a post/Page that doesn\'t exist (pagename=items
) and I also believe you added that in the rewrite rule as an identifier for the custom feed request.
And I\'m not sure if you intentionally didn\'t do this, but it\'s a very easy way to prevent the 404 error: create a Page and set its slug to items
.
That may sound silly, but it actually works. (Although you\'d still need to tweak the page title.) And you could just create a custom Page template (which loads/generates/renders the feed) and assign the template to that items
Page, without having to hook to template_redirect
.
Alternate solution without creating a Page
In the addRewriteRules()
, just omit the pagename=items&
:
public function addRewriteRules()
{
add_rewrite_rule(
\'items/([0-9]+)/?$\',
\'index.php?item_id=$matches[1]\',
\'top\'
);
}
In the addTemplate()
, check if the matched rewrite rule is the one you added via add_rewrite_rule()
above:
public function addTemplate()
{
global $item, $wp;
if ( \'items/([0-9]+)/?$\' === $wp->matched_rule &&
( $item_id = get_query_var(\'item_id\') ) ) {
// your code here
}
}
But once again, you\'d still need to tweak the page title which defaults to the site name.