How to borrow a post, or another way to create a virtual WordPress page on fly with the active theme used

I build a new plugin recently, and was need to show a page with my custom message. The stickt need was to be used the active theme, and the same way how WP itself use it. This is because plugin must runs on any possible, include the most sophisticated (from code viewpoint) themes. So here is what way I find.

function question_1($post) {
	global $post_title, $comment_status, $post_content;
	$post->post_title = $post_title;
	$post->comment_status = $comment_status;
	$post->post_content = $post_content;
	return;
}

function question_2($content) {
	global $post_content;
	return $post_content;
}

function question_3($content) {
	return home_url();
}

function my_init() {
	if([conditions to ensure it will run only when it is need]) {
		global $post_title, $comment_status, $post_content;
		$post_title = "My post title";
		$comment_status = "closed";
		$post_content = "My content, including HTML tqags";
		add_action('the_post', 'question_1');
		add_filter('the_content', 'question_2');
		add_filter('the_permalink', 'question_3');
		query_posts('posts_per_page=1&post_type=post');
		define('WP_USE_THEMES', true);
		require_once(ABSPATH.WPINC.'/template-loader.php');
		exit();
	}
}
add_action('init', 'my_init', 1);

Why and how this works?

The function my_init() runs every time when WP runs itself. It checks if my custom page is need at this moment, or do nothing, WP runs his way. Note that my_init() must run as early as possible, thus there in add_action() stay the privilege parameter "1".

If the custom page is need, my function creates 3 global variables (to send need info to other hooks) and fills them. Those are page title, content and comment status. I not need comments there, so set it "closed". Also I not need the original permalink, as some themes allow to click the post title, so I set it to the site's main URL. The custom page serves security problems, so both these "locks" are good in my case. You may need something different, so change it accordingly. Again, because of security, both title and post content had to be created at "init" time, so I was need to place code here. Then I was need to add some hooks to allow the custom info to be placed on the "virtual page" at need time, when the theme runs.

Now the mistery begins. I have prepared the need page content already, but WP have no page prepared yet. Do we need to run the Mail WP Loop, and I do that with query_posts() function. I need only a single post. Every WP installation have at least one active post, so with these conditions I ask the first active post to be loaded. Now, we have our custom content, have a post prepared to be shown, have the hooks ready to change the content. So we need to run the theme, to show the post. With define('WP_USE_THEMES', true) row we say to the WP "We need to use the active theme". With next row we say "Run the active theme".

What happens next? WP runs the theme. Theme runs the need template. Template shows our content, but with post's ID and other post-specific info. And this the way I "borrow" a post to show my custom content.

Code is poetry! :-)

This entry was posted in Blog, Hacks and tagged , , , , , , . Bookmark the permalink.

Leave a Reply