I’m currently working on a file browser plugin which requires frontend editing capabilities for a registered user. For this scenario, I have registered some custom rewrite rules for my custom post type.
Rewrite Analyzer
As you can see in the screenshot above, the plugin has a basic CRUD interface for managing the downloads. The routing is made through the template_redirect
hook, which checks if the query variable action
is set and then make a call to the appropriate action method.
add_action('template_redirect', array($this, '_requestHandler'), 9);
// ...
public function _requestHandler() {
try {
$requestedPage = get_query_var('pagename');
if((isset($requestedPage) && $requestedPage == 'webeo-download')) {
$action = get_query_var('action');
$this->action = (isset($action)) ? $action : null;
$downloadId = get_query_var('download');
$this->downloadId = (isset($downloadId)) ? (int) $downloadId : null;
if(isset($this->action) && !is_null($this->action) && strlen($this->action) > 0) {
$method = 'action' . ucfirst($this->action);
if(method_exists($this, $method)) {
call_user_func(array($this, $method));
} else {
throw new Webeo_Exception(sprintf(__('Action method <code>%s</code> does not exists.', WEBEO_DOWNLOAD_TEXTDOMAIN), $method));
}
} else {
$this->actionIndex();
}
echo $this->view->render($this->view->viewTemplate);
exit();
}
} catch (Webeo_Exception $e) {
$this->view->assign('error', $e);
echo $this->view->render('default.phtml');
exit();
}
}
This works really well, except one thing. I wanted to prevent WordPress from generating any default rewrite rules for my custom post type. Access to my posts from outside should also be restricted. Only my controller above should be responsible to serve any download data to the user.
To do this, I have set the arguments public
and publicly_queryable
to false inside the register_post_type
function. I’ve also set the argument exclude_from_search
to true
.
This seems to work. No post is showing under the default rewrite rule (e.g. example.com/downloads/<postname>
) nor is a download listed in the default search results. Unfortunately the $wp_query
arguments are also not set anymore. Therefore I’m not able to use comments_template()
or any other loop-function inside my templates.
It’s clear: WordPress doesn’t know my page structure and is not able to generate the correct settings. I’ve tried to manually pre-populate the $wp_query
arguments before the redirect inside the template_redirect
method. But this doesn’t seem to work. I’m probably to late in the chain.
global $wp_query, $post, $withcomments;
$wp_query->is_single = true;
$wp_query->is_page = true;
$post = get_post($this->downloadId);
$withcomments = true;
wp_reset_query();
Any suggestions?
Thanks in advance
Roman
I’ve probably found the solution for the above problem. To pre-populate the global variable
$wp_query
you have to run thequery_posts()
function with the correct arguments and reset the$wp_query->post
with the functionwp_reset_postdata()
. This must be done on thetemplate_redirect
hook or earlier.If someone has a better approach, please let me know!