Rewriting search and pagination base

After trying for weeks now how to find a working solution I got rid of most of my functions and trials and just left the pagination function underneath in my functions.phh file:

/**
 * Pagination links for search and archives
 */

function get_pagination_links( $type = 'plain', $endsize = 1, $midsize = 1 ) {
    global $wp_query, $wp_rewrite;
    $wp_query->query_vars['paged'] > 1 ? $current = $wp_query->query_vars['paged'] : $current = 1;

    // Sanitize input argument values
    if ( ! in_array( $type, array( 'plain', 'list', 'array' ) ) ) $type = 'plain';
    $endsize = (int) $endsize;
    $midsize = (int) $midsize;

    // Setup argument array for paginate_links()
    $pagination = array(
        'base'          => @add_query_arg('paged','%#%'),
        'total'         => $wp_query->max_num_pages,
        'current'       => $current,
        'show_all'      => false,
        'end_size'      => $endsize,
        'mid_size'      => $midsize,
        'type'          => $type,
        'prev_next'     => false,
        'paged'         => get_query_var( 'paged' )
    );

    return paginate_links( $pagination );
}

My search-form looks like this:

Read More
<form class="search-form" action="<?php echo home_url( '/' ); ?>" method="get">
    <fieldset>
        <div class="input-inside-label">
            <label for="s">Suchen …</label>
            <input type="text" name="s" class="s" value="<?php the_search_query(); ?>" />
        </div>
        <button type="submit" class="search-button">Suchen</button>
    </fieldset>
</form>

What I wanna do:
I’d like to rewrite the standard /?s= to the german word /suche

So when searching for “test” I want my URL to look like this:
www.mydomain.com/suche/test (instead of /?s=test)

Moreover I’d like to rewrite the pagination as well …
So when searching for “test” and clicking on page 2 I’d like the address to look like this …

www.mydomain.com/suche/test/seite/2

So in essence I’d like to rewrite /?s= to the german word suche (for search)
And rewrite &paged=2 to the german word seite (for page)

As you can see all I have in my code right now is the pagination function above because I removed all other trials – I couldn’t seem to make it work.

Any clever ideas on that? I’m using the latest wordpress version and would love to find a filter-based solution. I don’t want any JS to interact with the search-form.

Thank you in advance

Related posts

Leave a Reply

1 comment

  1. there are 3 steps towards achieving your goal.

    1 – Rewrite rules – wordpress needs to know what to look for and what to map it to

    add_rewrite_rule( 'suche/([^/]+)/?$', 'index.php?s=$matches[1]', 'top' );
    add_rewrite_rule( 'suche/([^/]+)(/seite/(d+))/?$', 'index.php?s=$matches[1]&paged=$matches[3]', 'top' );
    

    The above adds straight rewrite rules to the rewrite rules array so anytime someone goes to a URL like /suche/apfel/ it is translated internally as index.php?s=apfel.

    2 – Redirect searches to our new structure

    // redirect immediately
    if ( isset( $_GET[ 's' ] ) ) {
        $location = '/suche/' . $_GET[ 's' ];
        if ( isset( $_GET[ 'paged' ] ) && $_GET[ 'paged' ] )
            $location .= '/seite/' . $_GET[ 'paged' ];
        wp_redirect( trailingslashit( home_url( $location ) ), 301 );
        exit;
    }
    

    Place this in your functions.php. As soon as a search request is detected wordpress will redirect to the nice search URL and the browser will remember the redirection because of the 301 status we’re passing to wp_redirect().

    We are building our replacement URL for a search here, and if the $paged parameter is present we add that too.

    3 – Create pagination links

    function pagination_links( $type = 'plain', $endsize = 1, $midsize = 1 ) {
        global $wp_query, $wp_rewrite;
        $wp_query->query_vars['paged'] > 1 ? $current = $wp_query->query_vars['paged'] : $current = 1;
    
        // Sanitize input argument values
        if ( ! in_array( $type, array( 'plain', 'list', 'array' ) ) ) $type = 'plain';
        $endsize = (int) $endsize;
        $midsize = (int) $midsize;
    
        // Setup argument array for paginate_links()
        $pagination = array(
            'base'          => home_url( '/suche/' . get_search_query() . '%_%' ),
            'format'        => '/seite/%#%/', // ?page=%#% : %#% is replaced by the page number
            'total'         => $wp_query->max_num_pages,
            'current'       => $current,
            'show_all'      => false,
            'end_size'      => $endsize,
            'mid_size'      => $midsize,
            'type'          => $type,
            'prev_next'     => false
        );
    
        return paginate_links( $pagination );
    }
    

    The only thing you were missing in this function was using the modified format and base arguments to create the nice URL base of the current search and the nice URL page argument.

    That should do what you need. You can dig deeper and remap more URLs to use translations using other filters but there are quite a few so this is a good starting point!