Custom permalink for search and pagination

@Chip Bennet helped me out in a previous question and posted his entire pagination function. This function works perfectly fine for me but I’d like to have custom permalinks in german.

/**
 * Paginate Archive Index Page Links
 */
function oenology_get_paginate_archive_page_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','%#%'),
        'format' => '',
        'total' => $wp_query->max_num_pages,
        'current' => $current,
        'show_all' => false,
        'end_size' => $endsize,
        'mid_size' => $midsize,
        'type' => $type,
        'prev_text' => '<<',
        'next_text' => '>>'
    );

    if( $wp_rewrite->using_permalinks() )
        $pagination['base'] = user_trailingslashit( trailingslashit( remove_query_arg( 's', get_pagenum_link( 1 ) ) ) . 'page/%#%/', 'paged' );

    if( !empty($wp_query->query_vars['s']) )
        $pagination['add_args'] = array( 's' => get_query_var( 's' ) );

    return paginate_links( $pagination );
}

I use this function in my search.php template like this.

Read More
<div class="pagination">
    <?php echo oenology_get_paginate_archive_page_links(); ?>
</div>

If I search in my search bar the url for the resulting page looks like this

mysite.com/?s=term

I’d like to have the german suche (means “search”) instead …

mysite.com/suche/term

And the second bit … when clicking on the page 2 of the pagination the url looks currently like this …

mysite.com/page/2/?s=term

I’d like to have the german word the german word seite (for “page”) instead. Maybe even like this …

mysite.com/suche/term/seite/2

Is that somehow possible with this function that @Chip provided? I can’t seem to find a working solution for this.

Thank you in advance. I’d really appreciate some help.


UPDATE

function oenology_get_paginate_archive_page_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','%#%'),
        'format' => '?paged=%#%',
        'total' => $wp_query->max_num_pages,
        'current' => $current,
        'show_all' => false,
        'end_size' => $endsize,
        'mid_size' => $midsize,
        'type' => $type,
        'prev_next'    => false
    );

    if ( $wp_rewrite->using_permalinks() )
        $pagination['base'] = user_trailingslashit( trailingslashit( remove_query_arg( 's', get_pagenum_link( 1 ) ) ) . 'seite/%#%/', 'paged' );

    /*if ( !empty($wp_query->query_vars['s']) )
            $pagination['add_args'] = array( 's' => get_query_var( 's' ) );*/

    return paginate_links( $pagination );
}

/**
 * Change search- & paginationbase
 */

add_action( 'generate_rewrite_rules', 'wr_generate_rewrite_rules' );

function wr_generate_rewrite_rules( $rewrite ) {
    $rewrite->rules = array_merge( array(
         'suche/([^/]+)(?:/seite/(d+))?/?' => 'index.php?s='.$rewrite->preg_index(1).'&paged='.$rewrite->preg_index(2)
    ), $rewrite->rules );
}

add_filter( 'get_pagenum_link', 'wr_search_pagenum_link' );

function wr_search_pagenum_link( $link ) { 
    if ( !is_search() )
        return $link;

    // Attempt to parse the page number from the provided URL
    if ( !preg_match( '#/page/(d+)#', $link, $matches ) )
        return $link;

    // Return a re-formed URL
    return home_url( '/suche/' . urlencode( get_query_var( 's' ) ) . '/seite/' . $matches[0] );
}

Related posts

Leave a Reply

1 comment

  1. I believe the primary reason that the GET parameter format is still used for searches is that search forms are regular GET forms that when submitted form URLs with the GET parameters appended.

    But a further problem with using custom URLs to capture searches is that search terms can be arbitrary text, including slashes, etc, which can look ugly when baked into a URL.

    Suppose we used your desired search URL format:

    mysite.com/suche/term

    And I searched for the term "belegte brot", with the quotes. We end up with the URL:

    mysite.com/suche/%22belegte+brot%22

    Which isn’t terribly pretty, and similar escaping needs to be done for any other special characters.

    Nevertheless, it’s still possible to achieve the permalink structure you are looking for.

    Step 1: Register permalink structure

    Hook on generate_rewrite_rules action, to add new patterns:

    function my_generate_rewrite_rules( $rewrite ) {
        $rewrite->rules = array_merge( array(
            'suche/([^/]+)(?:/seite/(d+))?/?' => 'index.php?s='.$rewrite->preg_index(1).'&paged='.$rewrite->preg_index(2)
        ), $rewrite->rules );
    }
    add_action( 'generate_rewrite_rules', 'my_generate_rewrite_rules' );
    

    This registers a rule at the very top of the rewrite rule stack, which will capture URLs of the forms suche/<term>, suche/<term>/, seite/<term>/seite/<page> and seite/<term>/seite/<page>/ and transform them into the query variables s=<term> and paged=<page>

    Step 1a: Regenerate permalinks by visiting the Settings > Permalinks page in the WP admin area.

    Step 2: Insert JavaScript in your search form that will, instead of submitting a form using GET parameters, will instead redirect to a URL of the form above:

    <form id="search" action="<?php echo home_url( '/suche/' ); ?>">
        <input name="s" />
    </form>
    <script>
        jQuery('#search').submit(function(ev) {
            ev.preventDefault();
            location.href = jQuery(this).attr('action') + escape( jQuery('#search').find('[name="s"]').val() );
        });
    </script>
    

    This example shows a form whose submit event is captured and cancelled, instead updating the URL. NB: This is untested.

    Step 3: Add a hook on the get_pagenum_link filter to form the expected URLs:

    function my_search_pagenum_link( $link ) { 
        if( !is_search() )
            return $link;    // Do nothing unless on a search
    
        // Attempt to parse the page number from the provided URL
        if( !preg_match( '#/page/(d+)#', $link, $matches ) )
            return $link;
    
        // Return a re-formed URL
        return home_url( '/suche/' . urlencode( get_query_var( 's' ) ) . '/seite/' . $matches[0] );
    }
    add_filter( 'get_pagenum_link', 'my_search_pagenum_link' );
    

    This should be sufficient to achieve your desired behavior.