Hi @helgi,
Because Blade templates aren’t PHP, you can’t include them directly. They need to be compiled by the templating engine first, which converts them to PHP. That PHP is the equivalent of what you would have written if you wrote the template without using Blade.
If you look up a little in filters.php
you can see how this is done:
The template()
function is used to compile the Blade template file specified in $template
to PHP, passing the $data
to it. The output of that PHP is then echo
d, giving the output that’s sent to the browser for that template.
Here’s an example of how you could create a virtual page using the template()
function. You should be able to adapt this to your specifics.
You may find that WordPress treats your virtual page as a 404 since there is no matching entity in the database. To prevent that, you can return a fake post object as shown below. This also allows you to customize the title used in your site’s meta tags.
In filters.php
or wherever you like:
/**
* Add /virtual/ endpoint permalink
* Must be appended to an existing URL structure
* You would replace this with your rewrite rule code.
*/
add_action('init', function () {
add_rewrite_endpoint('virtual', EP_PERMALINK);
});
/**
* Load the virtual page's template
* Any additional logic, data prep, etc., can be run or called from here before rendering the template
*/
add_action('template_redirect', function () {
global $wp_query;
// bail if the virtual endpoint was not called
// modify this to check for whatever will identify your virtual page request (i.e., your query var)
if (!isset($wp_query->query_vars['virtual'])) {
return;
}
$template = locate_template(["views/partials/virtual.blade.php"]);
if ($template) {
// customize the passed array if you need to send data to your template; omit if not
echo template($template, [
'title' => 'Virtual Page',
'description' => 'This is how you might render a virtual page.',
]);
die();
}
});
/**
* Prevent 404 and customize page title, etc.
*/
add_filter('the_posts', function (array $posts, \WP_Query $query) {
// modify this to check for whatever will identify your virtual page request (i.e., your query var)
if (!isset($query->query_vars['virtual'])) {
return $posts;
}
// Returning a fake post bypasses WP's 404 logic
$title = 'Virtual Page';
$post = [
'ID' => -100,
'post_title' => $title,
'post_name' => sanitize_title($title),
'post_content' => '',
'post_excerpt' => '',
'post_parent' => 0,
'menu_order' => 0,
'post_type' => 'page',
'post_status' => 'publish',
'comment_status' => 'closed',
'ping_status' => 'closed',
'comment_count' => 0,
'post_password' => '',
'to_ping' => '',
'pinged' => '',
'guid' => home_url($query->getUrl()),
'post_date' => current_time('mysql'),
'post_date_gmt' => current_time('mysql', 1),
'post_author' => 0,
'is_virtual' => true,
'filter' => 'raw'
];
return [
new \WP_Post((object) $post)
];
}, 10, 2);
Then your template (views/partials/virtual.blade.php
in this case) can be whatever you need, e.g.:
@extends('layouts.app')
@section('content')
<h1>{{ $title }}</h1>
<p>
{{ $description }}
</p>
@endsection
Resources:
https://metabox.io/how-to-create-a-virtual-page-in-wordpress/
https://coderwall.com/p/fwea7g/create-wordpress-virtual-page-on-the-fly
https://gist.github.com/gmazzap/1efe17a8cb573e19c086
https://wordpress.stackexchange.com/questions/139071/plugin-generated-virtual-pages