I am trying to set up a custom WordPress routing the will look like this:
sitename/books/{book_name}/
will point to the Page-Book-Single.php file and grab that name in the query_vars
sitename/books/{book_name}/{article-name}/
will point to the Page-Book-Article.php file and grab that name in the query_vars
It works for 1 page deep (sitename/books/{book_name}/) but with 2 deep (sitename/books/{book_name}/{article-name}/) it just returns the same as 1 page deep.
Here is the code:
add_action( 'init', 'wpse26388_rewrites_init' );
function wpse26388_rewrites_init()
{
add_rewrite_rule(
'books/?([^/]*)',
'index.php?pagename=books&book_name=$matches[1]',
'top' );
add_rewrite_rule(
'books/?([^/]*)/?([^/]*)',
'index.php?pagename=books-single&article_name=$matches[1]',
'top' );
flush_rewrite_rules();
}
add_filter( 'query_vars', 'wpse26388_query_vars' );
function wpse26388_query_vars( $query_vars )
{
$query_vars[] = 'book_name';
$query_vars[] = 'article_name';
return $query_vars;
}
function prefix_url_rewrite_templates()
{
if ( get_query_var( 'book_name' ) )
{
add_filter( 'template_include', function() {
return get_template_directory() . '/page-books-single.php';
});
}
if ( get_query_var( 'article_name' ) )
{
add_filter( 'template_include', function() {
return get_template_directory() . '/page-book-article.php';
});
}
}
The first rewrite rule may take priority, and satisfies all matches.
If you request sitename/books/{book_name}/{article-name}/ the rule 'books/?([^/]*)' satisfies it. The rules may have to be:
'books/([^/]*)/?$'
and
'books/([^/]*)/([^/]*)/?'
The first one, forces it to match to the end ($), and there are no following slashes, unless it is a final slash. The second mandates a slash be between the two segments. This way, if a 2nd slash is in the request (and its not a final character) then its treated as a second value
Related
I accepted a new challenge making a custom Wordpress plugin.
After doing some research I started creating clean urls for the plugin and collected the code below.
When I visit the url https://mysite/estates/list/test/baarle/
The first custom var/rewrite_tag "jebamodus" is displayed with a value "list" in the $wp_query->query_vars array. This one's good.
The second and/or third var/rewrite_tag isn't displayed/registered?
Do I need to init each var/rewrite_tag with rewrite url seperated or are there some faults in my code?
I feel like I almost got it to work, but can't find what's wrong.
Some fresh eyes needed.
function wpse_205120_query_vars( $qvars ) {
$qvars[] = 'jebamodus';
$qvars[] = 'jebatest';
$qvars[] = 'jebaregion';
return $qvars;
}
add_filter( 'query_vars', 'wpse_205120_query_vars' );
add_action( 'init', function() {
add_rewrite_tag( '%jebamodus%', '([^/]+)' );
add_rewrite_tag( '%jebatest%', '([^/]+)' );
add_rewrite_tag( '%jebaregion%', '([^/]+)' );
add_rewrite_rule( '^estates/([^/]+)', 'index.php?jebamodus=$matches[1]', 'top' );
add_rewrite_rule( '^estates/([^/]+)/([^/]+)', 'index.php?jebamodus=$matches[1]&jebatest=$matches[2]', 'top' );
add_rewrite_rule( '^estates/([^/]+)/([^/]+)/([^/]+)', 'index.php?jebamodus=$matches[1]&jebatest=$matches[2]&jebaregion=$matches[3]', 'top' );
flush_rewrite_rules(true);
} );
add_filter('template_include', function($template){
global $wp_query;
if( isset($wp_query->query_vars['jebamodus'])) {
echo "<pre>";
print_r($wp_query->query_vars);
wp_die();
}
return $template;
});
I'm creating a plugin that will need virtual pages to output content on the front end.
Here is my code:
add_filter( 'generate_rewrite_rules', function ( $wp_rewrite ) {
$wp_rewrite->rules = array_merge(
['my-custom-url/?$' => 'index.php?custom=1'],
$wp_rewrite->rules
);
} );
add_filter( 'query_vars', function( $query_vars ) {
$query_vars[] = 'custom';
return $query_vars;
} );
add_action( 'template_redirect', function() {
$custom = intval( get_query_var( 'custom' ) );
if ( $custom ) {
include plugin_dir_path( __FILE__ ) . 'templates/states.php';
exit();
}
} );
In the plugin I have templates/states.php and in that file I have:
<?php
$state = get_query_var( 'custom' );
echo $state;
?>
When I visit localhost/my-custom-url/somevariable I get a page not found from Wordpress. I've tried flushing my permalinks.
As I said in the comments
I have never used generate_rewrite_rule
The documentation on it is pretty weak too. But this key looks just like I would expect a Regular expresion to be. And, that makes sense as that is how real Mod Rewrite and Htaccess work.
add_filter( 'generate_rewrite_rules', function ( $wp_rewrite ) {
$wp_rewrite->rules = array_merge(
['my-custom-url/?$' => 'index.php?custom=1'],
$wp_rewrite->rules
);
} );
So this $ here matches the end of the string, this means your URL must end with my-custom-url with an optional / because of the ?.
When I visit localhost/my-custom-url/somevariable I get a page not found
That's not surprising as your URL does not end in a way that will match that pattern.
Test it yourself!
So you can just remove the $ you may or may not want to keep the / optional.
add_filter( 'generate_rewrite_rules', function ( $wp_rewrite ) {
$wp_rewrite->rules = array_merge(
['my-custom-url/?' => 'index.php?custom=1'],
$wp_rewrite->rules
);
} );
One note is this will make that match anywhere in the URL
Test this one
Hope it works.
I'm using Wordpress, where I have used my custom designed template, so I'm using custom generated URL's in most cases.
I want my URL to look like: website_url/details/191/
I want to rewrite this to more SEO friendly. I don't know how to write rewrite rules in htaccess and could use your help.
add_filter( 'rewrite_rules_array','my_insert_rewrite_rules' );
add_filter( 'query_vars','my_insert_query_vars' );
add_action( 'wp_loaded','my_flush_rules' );
// flush_rules() if our rules are not yet included
function my_flush_rules(){
$rules = get_option( 'rewrite_rules' );
if ( ! isset( $rules['(details)/(\d*)$'] ) ) {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
}
// Adding a new rule
function my_insert_rewrite_rules( $rules )
{
$newrules = array();
$newrules['(details)/(\d*)$'] = 'index.php? pagename=$matches[1]&id=$matches[2]';
return $newrules + $rules;
}
// Adding the id var so that WP recognizes it
function my_insert_query_vars( $vars )
{
array_push($vars, 'id');
return $vars;
}
This is what I have added in my function.php but no change.
I'm creating a custom url rewrite structure for my WordPress site.
First I had the following code to have url: /objekt/<GID> which loads objekt page and have query var GID.
add_action( 'init', 'objekt_url_rewrites_init' );
function objekt_url_rewrites_init(){
add_rewrite_rule(
'objekt/([A-Za-z_0-9]+)/?$',
'index.php?pagename=objekt&GID=$matches[0]',
'top' );
}
add_filter( 'query_vars', 'objekt_url_query_vars' );
function objekt_url_query_vars( $query_vars ){
$query_vars[] = 'GID';
return $query_vars;
}
Now, I need to change URL structure to /en/objekt/<GID>. So, I change
objekt/([A-Za-z_0-9]+)/?$
to
en/objekt/([A-Za-z_0-9]+)/?$
But its not working!
When I visit /en/objekt/<GID> it just redirects to /en/objekt/ and not getting any query var named 'GID'
I need to pass a URL variable to my category.php file.
Currently my category page is at http://example.com/category-slug/
I am using the SEO plugin to rewrite http://example.com/category/category-slug and remove the /category/ part.
Also, the settings formy permalinks are set to this option in the settings menu: http://example.com/sample-post/
Now I need to be able to pass a variable in the URL like:
http://example.com/category-slug/?type=VALUE
or
http://example.com/category-slug/VALUE
where "type" is the name of the variable and VALUE is its value
I have tried using this piece of code in my functions.php file:
<?php
add_filter('query_vars', 'parameter_queryvars' );
function parameter_queryvars( $qvars )
{
$qvars[] = 'type';
return $qvars;
}
global $wp_query;
if (isset($wp_query->query_vars['type']))
{
print $wp_query->query_vars['type'];
}
?>
However, when I try to open http://example.com/category-slug/?type=something or http://example.com/category-slug/something I get "nothing found" and "Page not found" pages.
While I see this has been discussed over and over, none of the solutions seem to work for my case.
How do I properly pass a variable to a category page?
First of all, you code will never reach the if statement, as you return from the function before.
I also don't know which SEO tool you are using, but there is one function that goes with the "query_vars" filter: add_rewrite_rule()
I would recommend to write a little plugin which does the rewriting of the category permalink. Something like this (untested, but similar to a plugin I use):
// Flush added rewrite rules on activation
function category_permalink_rewrite_activate() {
category_permalink_rewrite_set_rewrite_rules();
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'category_permalink_rewrite_activate' );
// Remove rewrite rule for event archives
function category_permalink_rewrite_deactivate() {
flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'category_permalink_rewrite_deactivate' );
// Add rewrite rule for category permalink on init
add_rewrite_rule( '^category-(.*)/(.*)', 'index.php?category_name=$matches[1]&type=$matches[2]', 'top' );
kaufunction category_permalink_rewrite_set_rewrite_rules() {
}
add_filter( 'init', 'category_permalink_rewrite_set_rewrite_rules' );
// Register the custom query var so WP recognizes it
function category_permalink_rewrite_add_query_vars( $vars ) {
$vars[] = 'type';
return $vars;
}
add_filter( 'query_vars', 'category_permalink_rewrite_add_query_vars' );