Opened 7 years ago
#41680 new defect (bug)
Added rewrite tags using add_rewrite_tag() not working on static front-page
Reported by: | Asgaros | Owned by: | |
---|---|---|---|
Milestone: | Awaiting Review | Priority: | normal |
Severity: | normal | Version: | 4.8.1 |
Component: | Rewrite Rules | Keywords: | |
Focuses: | Cc: |
Description
Hello everyone,
the following ticket is a little bit similar to the issue described here: #25143
Introduction
I am working on a plugin which provides a shortcode. This shortcode generates some content/output on a page where it is placed on. The shown output depends on optional URL-parameters. For example those two URLs result in different outputs:
- my-site.com/my-page
- my-site.com/my-page?foo=bar
In preparation for pretty URLs I have to register a new rewrite-tag foo:
add_rewrite_tag('%foo%', '([^/]*)');
This allows me (in combination with the corresponding rewrite rules) to use pretty URLs like this:
- my-site.com/my-page/foo/bar
As expected you can access the assigned value bar of foo with the following code:
$value_of_foo = get_query_var('foo'); // returns: bar
Problem
This all works fine as long as the page which includes the shortcode is not set as the sites static front-page. In this case your URLs will usually look like that:
- my-site.com (the content of the static page is shown)
- my-site.com/?foo=bar (from here it is broken)
So, whats happening? Instead of generating and showing the content based on the URL parameter, the second URL loads the front-page but instead of showing the content of the static page, it acts like the blog page and shows the list of the latest posts.
The problem is that is_home
is improperly set to true
because we now have a custom query-var in our URL which basically makes the content of a static page not static anymore. But this fact shouldnt let WordPress showing the list of the latest posts-page instead. This problem makes it impossible for users to place and show the content of a shortcode - which is based on (prettyfied) URL-parameters - on their static front-page.
At the moment I am using the following code as a workaround but I think this is not an optimal long-term solution for this problem:
function fix_query_vars_on_front_page($query) {
// Dont do this workaround when we are in the administration area or when we are not inside the main query.
if (is_admin() || !$query->is_main_query()) {
return;
}
// Cache the actual query vars first.
$queryVarCache = $query->query;
// Only continue when our query vars are not already empty.
if (!empty($queryVarCache)) {
// Remove our query vars from the cache when they are set.
if (isset($queryVarCache['foo'])) {
unset($queryVarCache['view']);
}
// When our cache is empty, we are on a front-page (is_home() or is_front_page()). Ensure that the following filtering only happens on a static front page.
if (empty($queryVarCache) && get_option('show_on_front') === 'page') {
// Get the ID of the front page and add it to the query vars.
$query->query['page_id'] = get_option('page_on_front');
// Reparse the query.
$query->parse_query($query->query);
}
}
}
add_action('pre_get_posts', 'fix_query_vars_on_front_page');
Maybe some way to add custom rewrite tags without adding them as a query var would be a possible solution for this. Of course there would be a need to add a function to access them, for example get_rewrite_var('foo')
instead of get_query_var('foo')
.
I am looking forward that WordPress will make this possible in a future version. :-)