You can make your life a little easier by moving the details fetching to an earlier point in the WordPress loading sequence and wrapping the data in a class. The object initialized from the class can then be used to provide the data to WordPress and to your template with filters.
For example you could have a handler class akin to this.
// Separate file or in functions.php
class My_Product_Details_Handler
{
protected $product = null;
public function __construct(int $product_id)
{
$this->setupProduct($product_id);
}
protected function setupProduct(int $product_id): void
{
$rss = simplexml_load_file('https://domain.com/xml');
foreach ($rss->channel as $channel) {
foreach ($channel->item as $item) {
if ($item->id !== $product_id) {
continue;
}
$this->product = $item;
break 2; // break both foreach loops
}
}
}
public function filter_wp_title(string $title, string $sep, string $seplocation): string
{
return $this->product ? $this->product->title : $title;
}
public function render_product_title(): void
{
echo $this->product ? $this->product->title : '';
}
public function provide_product_details()
{
return $this->product;
}
}
An object could be created from the class for example on the init
action. template_redirect
could work too for providing the data to the front end.
// functions.php
add_action('init', 'init_my_product_details_handler');
function init_my_product_details_handler(): void {
// Are we on the right template?
if (! is_page_template('product-details.php')) {
return;
}
// Get id from the url
$product_id = !empty($_GET['id']) && is_numeric($_GET['id'])
? (int) $_GET['id']
: 0;
// Do nothing, if there's no ID
if (! $product_id) {
return;
}
// Init handler
$handler = new My_Product_Details_Handler($product_id);
// Attach handler to relevant hooks
add_filter( 'wp_title', [$handler, 'filter_wp_title'], 10, 3 );
add_filter( 'my_product_details_data', [$handler, 'provide_product_details'] );
}
Then a small tweak to the template file. Using a filter to get the product data makes the template file a little cleaner looking.
// product-details.php template
<body>
<?php
$product_details = apply_filters( 'my_product_details_data', null );
if ($product_details) {
// render the details
} else {
echo 'No results found;
}
?>
</body>