I am trying to fetch and display data from a feed when the user goes to a specific url like /items/32
where the 32
is the actual id of the feed item that should be fetched and displayed. Notice that I am not using any custom post type for this. I am just fetching the data from an external resource based on the supplied id:
class FeedPlugin
{
public function __construct()
{
add_action('init', array($this, 'addRewriteRules'));
add_filter('query_vars', array($this, 'addQueryVars'));
add_action('template_redirect', array($this, 'addTemplate'));
}
/**
* Add query argument item_id
**/
public function addQueryVars(array $query_vars)
{
$query_vars[] = 'item_id';
return $query_vars;
}
/**
* Add a custom rewrite in the form ^/items/123/$
**/
public function addRewriteRules()
{
add_rewrite_rule(
'items/([0-9]+)/?$',
'index.php?pagename=items&item_id=$matches[1]',
'top'
);
// This is just for testing purposes at this point.
flush_rewrite_rules(true);
}
/**
* Here we actually are fetching the data based on the id
**/
public function addTemplate()
{
global $item;
if (get_query_var('pagename') == 'items' &&
get_query_var('item_id')) {
$feedUrl = 'https://example.com/api/v1/feed?id=' . get_query_var('item_id');
$response = wp_remote_request($feedUrl);
// For now we just assume that this works.
$body = wp_remote_retrieve_body($response);
$item = json_decode($body);
// Include our custom template that renders the content from the $body variable
// I also manage to do this by using the `template_include` filter
include plugin_dir_path(__FILE__) . '/custom-item.php';
}
}
}
The above sort of works, but since I am not using a real post when visiting this route the title of the page is set to BlogName | Not found
and the http status code returned when visiting this route is set to 404
. I manage to solve this by using add_filter('pre_get_document_title', array($this, 'setTitle'));
:
public function setTitle($title)
{
global $item;
if (get_query_var('pagename') == 'items') {
return get_bloginfo('name') . ' | ' . $item->Title;
}
return $title;
}
and to get rid of the 404
status code I used:
global $wp_query;
$wp_query->is_404 = false;
status_header(200);
in the addTemplate()
method.
Even though this seems to work it feels very messy and I wonder if there is a smoother way of doing this? Perhaps by creating some kind of fake post or similar?