Passing parameters to a custom page template using clean urls

I am now passing parameters to a custom template in the following format

www.example.com/?pageid=12&rid=24&title=this-is-the-title

I have created two tables . So I need to fetch data and display them on those pages.

Read More

I would like it to be using clean URL format like:

www.example.com/pageid/12/rid/24/title/this-is-the-title

Can anyone tell how this can be achieved?

Thanks

Related posts

Leave a Reply

2 comments

  1. add_rewrite_rule() allows you to turn the pretty url into variables.

    • numbers: (d*)
    • section: /rid/ or /pageid/
    • slug: ([a-zA-Z0-9-]+

    Here is a class to register the rewrite and handle the request if a match has been found.

    <?php
    
    if ( ! class_exists( 'CPTURLRewrite' ) ):
    
        class CPTURLRewrite {
            const ENDPOINT_QUERY_NAME  = 'pageid';
            const ENDPOINT_QUERY_PARAM = '__pageid';
    
            // WordPress hooks
    
            public function init() {
                add_filter( 'query_vars', array ( $this, 'add_query_vars' ), 0 );
                add_action( 'parse_request', array ( $this, 'sniff_requests' ), 0 );
                add_action( 'init', array ( $this, 'add_endpoint' ), 0 );
            }
    
            // Add public query vars
    
            public function add_query_vars( $vars ) {
    
                // add all the things we know we'll use
    
                $vars[] = static::ENDPOINT_QUERY_PARAM;
                $vars[] = 'pageid';
                $vars[] = 'rid';
                $vars[] = 'title';
    
                return $vars;
            }
    
            // Add API Endpoint
    
            public function add_endpoint() {
    
                // numbers:   (d*)
                // section:   /rid/
                // slug:      ([a-zA-Z0-9-]+
    
                add_rewrite_rule( '^' . static::ENDPOINT_QUERY_NAME . '/(d*)/rid/(d*)/title/([a-zA-Z0-9-]+)?', 'index.php?' . static::ENDPOINT_QUERY_PARAM . '=1&pageid=$matches[1]&rid=$matches[2]&title=$matches[3]', 'top' );
    
                //////////////////////////////////
                flush_rewrite_rules( false ); //// <---------- REMOVE THIS WHEN DONE
                //////////////////////////////////
            }
    
            // Sniff Requests
    
            public function sniff_requests( $wp_query ) {
                global $wp;
    
                if ( isset(
                    $wp->query_vars[ static::ENDPOINT_QUERY_PARAM ],
                    $wp->query_vars[ 'pageid' ],
                    $wp->query_vars[ 'rid' ],
                    $wp->query_vars[ 'title' ] ) ) {
                    $this->handle_request(); // handle it
                }
            }
    
            // Handle Requests
    
            protected function handle_request() {
                global $wp;
    
                // (optional) act on the query vars
    
                $pageid = $wp->query_vars[ 'pageid' ];
                $rid = $wp->query_vars[ 'rid' ];
                $title = $wp->query_vars[ 'title' ];
    
                // (optional) select your custom template
    
                add_filter( 'template_include', function( $original_template ) {
                    return __DIR__ . '/custom.php';
                } );
            }
        }
    
        $wpCPTURLRewrite = new CPTURLRewrite();
        $wpCPTURLRewrite->init();
    
    endif; // CPTURLRewrite
    

    UPDATE

    I found a simpler way to handle this.

    http://example.com/pageid/333/rid/444/title/your-title-here/

    This new way utilizes add_rewrite_tag with _ to run the query for a page’s ID without messing up the main query. In the example above, 333 would just modify the query to look for that post ID in pre_get_posts. You could just as easily modify template_redirect or template_include.

    /**
     * Register a rewrite endpoint for the API.
     */
    function prefix__init() {
    
        // add tags with `_` prefix to avoid screwing up query
        add_rewrite_tag( '%_pageid%', '(d*)' );
        add_rewrite_tag( '%_rid%', '(d*)' );
        add_rewrite_tag( '%_title%', '([a-zA-Zd-_+]+)' );
    
        // create URL rewrite
        add_rewrite_rule( '^pageid/(d*)/rid/(d*)/title/([a-zA-Zd-_+]+)?', 'index.php?_pageid=$matches[1]&_rid=$matches[2]&_title=$matches[3]', 'top' );
    
        // required once after rules added/changed
        // flush_rewrite_rules( true );
    }
    
    add_action( 'init', 'prefix__init' );
    
    /**
     * Handle data (maybe) passed to the API endpoint.
     *
     * @param $query
     */
    function prefix__pre_get_posts( $query ) {
    
        if ( isset( $query->query_vars[ '_pageid' ], $query->query_vars[ '_rid' ], $query->query_vars[ '_title' ] ) ) {
    
            // set the query to search for a page using `_pageid`
            $query->set( 'p', $query->query_vars[ '_pageid' ] );
        }
    }
    
    add_action( 'pre_get_posts', 'prefix__pre_get_posts' );
    

    To reference all the params passed later:

    /**
    * Debug the query params at any point
    */
    function prefix__show_query_args() {
     global $wp_query;
    
        echo "<pre>";
        print_r( array (
            'pageid' => $wp_query->query_vars[ '_pageid' ],
            'rid'    => $wp_query->query_vars[ '_rid' ],
            'title'  => $wp_query->query_vars[ '_title' ],
            'file'   => __FILE__,
            'line'   => __LINE__,
        ) );
        echo "</pre>";
    }
    

    REFERENCE

  2. If you want a simple solution this might be it (haven’t tested the code so might not be so simple if it’s not working…) or atleast it give some hint what you need to do. If you visit http://thereforei.am/2011/10/28/advanced-taxonomy-queries-with-pretty-urls/ you will find a bonus prize: A Rewrite Rule Generator in the article. I have used this before but not in a situation exactly like this. Try to combine that function with something like this:

    add_rewrite_tag('%pageid%','([^&]+)');
    add_rewrite_tag('%rid%','([^&]+)');
    add_rewrite_tag('%title%','([^&]+)');
    
    /* Generate rewrite rules. */
    add_action( 'generate_rewrite_rules', 'example_add_rewrite_rules' );
    function example_add_rewrite_rules() {
        global $wp_rewrite;
        $new_rules = eg_generate_rewrite_rules( 'post' , array('pageid','rid','title')); //    post = the post type you use
        $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
    }
    
    /* Flush rewrite rules on theme activation only. */
    add_action( 'load-themes.php', 'frosty_flush_rewrite_rules' );
    function frosty_flush_rewrite_rules() {
        global $pagenow;
        if ( 'themes.php' == $pagenow && isset( $_GET['activated'] ) )
            flush_rewrite_rules();
    }
    

    If you don’t want to use the eg_generate_rewrite_rules function, you need to set up the rules yourself. You can find information on how to do that in that article.

    More info:
    http://codex.wordpress.org/Rewrite_API/add_rewrite_tag