Wordpress plugin to create virtual page using rewrite rules - php

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.

Related

Rewrite rules stops working tried flushing on events but didn't worked

i used to do url rewriting on wordpress for this i use a code that works perfectly but after sometime it stops working and give 404 error then i do Permalink setting to save once again and it works; everytime it stops i do premalink save setting and it works but didn't figured out how to solve this issue permanently.
url rewrite code
//rewrite rules
function custom_add_rewrite_rule(){
$posts = get_posts( array( 'numberposts' => -1, 'post_type' => 'post') );
if( $posts ){
foreach($posts as $post ){
add_rewrite_rule(
$post->post_name . '/download/?$',
'index.php?name=' . $post->post_name . '&post_action=download&post_id=' . $post->ID,
'top'
);
}
}
}
above code is on function.php
and to solve i tried by flushing rules on every post save/update for this i used below code
//flush reqrite rule on post/update
add_action( 'save_post', 'my_save_post_function' );
function my_save_post_function( $post_id ) {
$maybe_some_extra_logic = true; // if applicable
if ( $maybe_some_extra_logic && ! has_action( 'shutdown', 'my_flush_rewrite_rules' ) ) {
add_action( 'shutdown', 'my_flush_rewrite_rules', 9999 ); // set suitable priority
}
}
function my_flush_rewrite_rules() {
flush_rewrite_rules();
}
but didn't worked.

Remove cpt slug and add custom taxonomy in url

I need to change the custom post type url, this code works it but is also affecting other cpts causing 404 in all other cpt, how can I make it only for the one I need.
Here is my code
// Rewrite urls of resources and put category on url
function change_custom_post_link( $post_link, $id = 0 ){
$post = get_post($id);
if ( is_object( $post ) ){
$terms = get_the_terms( $post->ID, 'resource_type' );
if(get_post_type($post->ID) == 'resource' ) {
if( $terms ){
return home_url( "/".$terms[0]->slug."/".$post->post_name );
}else{
return home_url( "/resource/".$post->post_name );
}
}
}
return $post_link;
}
add_filter( 'post_type_link', 'change_custom_post_link', 1, 3 );
and this is the rewrite
function resource_rewrite_rules() {
add_rewrite_rule(
'^(.*)/(.*)/?$',
'index.php?post_type=resource&name=$matches[2]',
'top'
);
}
add_action( 'init', 'resource_rewrite_rules' );
Why are you doing this? That's too tricky.
You may use this plugin to create and modify CPT: CPT plugin WordPress
Or refer to docs: https://developer.wordpress.org/reference/functions/register_post_type/

How to rewrite the particular query string in wordpress?

I have tried to rewrite the query string using hooks but cant get the right url. Should i place it in htaccess.
current url: https://exmaple.com/club-contact/?officer=MzYzOU1ZX1NFQ1JFVF9TVFVGRg==
url rewritten: https://exmaple.com/club-contact/MzYzOU1ZX1NFQ1JFVF9TVFVGRg==/officer
function custom_rewrite( $wp_rewrite ) {
$feed_rules = array(
'club-contact/(.+)' => 'index.php?page_id=3692&officer=' . $wp_rewrite->preg_index(1),
);
$wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
}
function custom_wp_querystring() {
add_rewrite_tag('%officer%','([^&]+)');
}
add_action( 'init', 'custom_wp_querystring');
add_filter( 'generate_rewrite_rules', 'custom_rewrite' );

add_rewrite_rule - suddenly stopped working (wordpress)

I have a url
example.com/sample-page/?amount=567
It initially worked ok, it redirects to:
example.com/sample-page/567
But after few days, i noticed its not working any more.
Its now redirecting to post without query var or get var
What could be the reason?? Is there any solution??
I used below codes in my functions.php file:
& I already flushed permalinks.
I am using custom post type
I have removed custom post type base from url using a plugin.
UPDATE
I just noticed Its due to empty post id/pagename.
So now, Question is how to get page name of current post...inside init function dynamically??
//https://developer.wordpress.org/reference/functions/wp_redirect/#comment-4109
add_action( 'init', function() {
global $wp;
$pagename = $wp->request;
add_rewrite_rule( ''.$pagename.'/([0-9]+)[/]?$', 'index.php?pagename='.$pagename.'&amount=$matches[1]', 'top' );
} );
add_filter( 'query_vars', function( $query_vars ) {
$query_vars[] = 'amount';
return $query_vars;
} );
function wpb_change_search_url() {
global $wp;
if ( ! empty( $_GET['amount'] ) ) {
wp_redirect( get_permalink( home_url( $wp->request ) ) . urlencode( get_query_var( 'amount' ) ) );
exit();
}
}
add_action( 'template_redirect', 'wpb_change_search_url' );

wordpress rewrite rule 2 subdirectories deep

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

Categories