1

I work on a blog that contains both English and Romanian posts.

I made the site bilingual by prefixing the slug of every article with ro- and en-. It is a simple way and it works pretty well.

Now I have to create a custom archive that displays for a given month, with pagination, just the articles that have a slug (page_name) that begins with ro-, or en- respectively.

I guess I should make two PHP files, one called en-archive.php and other called ro-archive.php, this is what I think I will try, but I do not know how to make the query so that it shows correctly with pagination.

Also, what would be the correct replacement after this change for this:?

<ul class='archives-list'><?php wp_get_archives() ?></ul>

Thank you.

1

With a custom Page (post type page) and a custom Page Template, you can do it like so:

  1. In the templates, make a new instance of WP_Query which is used for querying the posts in either the Romanian or English language.

  2. In the query/function args for WP_Query and wp_get_archives(), use a custom parameter named lang which defines the language slug — ro for Romanian, en for English — and which is used to include only the posts or the archives having the posts where the post slug begins with <language slug>-, e.g. ro-.

The Code

  1. The custom Page template:

    Note that I used the same code for both the Romanian and English versions, except that the lang is of course set to the corresponding language slug. If you want, you can use a custom meta data (e.g. _lang) for the Page and use just a single template for all languages, but you will need to implement that on your own.

    So on my test site, I've got these Pages:

    • RO Archive (/ro-archive/) using the template-ro-archive.php template

    • EN Archive (/en-archive/) using the template-en-archive.php template

    <?php
    // I'm only including the main content, but make sure your template contains
    // the Template Name header and the calls to get_header() and get_footer().
    ?>
    <ul>
        <?php wp_get_archives( [
            'lang' => 'ro',
        ] ); ?>
    </ul>
    
    <?php
    $paged = max( 1, get_query_var( 'paged' ) );
    
    // Query the posts.
    $query = new WP_Query( [
        'lang'           => 'ro',
        'paged'          => $paged,
        'posts_per_page' => 10,
    ] );
    
    // Display the loop.
    while ( $query->have_posts() ) :
        $query->the_post();
        // .. your code here.
    endwhile;
    
    // And a pagination.
    echo paginate_links( [
        'current' => $paged,
        'total'   => $query->max_num_pages,
    ] );
    
    // Lastly, restore the global $post variable.
    wp_reset_postdata();
    ?>
    

    And actually, you can also make the templates specific to the respective Page, e.g. use the name page-ro-archive.php and not template-ro-archive.php.

  2. The query filter for WP_Query, using the posts_where hook:

    This code should go in the theme's functions file.

    // Include only the posts where the slug begins with <language-slug>- like ro-
    add_filter( 'posts_where', function ( $where, $query ) {
        if ( ! is_admin() && $lang = $query->get( 'lang' ) ) {
            global $wpdb;
            $where .= $wpdb->prepare(
                " AND {$wpdb->posts}.post_name LIKE %s",
                $lang . '-%'
            );
        }
    
        return $where;
    }, 10, 2 );
    
  3. The query filter for wp_get_archives(), using the getarchives_where hook:

    This code should go in the theme's functions file.

    // Include only archives having posts where the slug begins with
    // <language-slug>- like ro-
    add_filter( 'getarchives_where', function ( $where, $parsed_args ) {
        if ( ! is_admin() && ! empty( $parsed_args['lang'] ) ) {
            global $wpdb;
            $where .= $wpdb->prepare(
                " AND post_name LIKE %s",
                $parsed_args['lang'] . '-%'
            );
        }
    
        return $where;
    }, 10, 2 );
    

Alternate Solution

Use a custom taxonomy, e.g. lang, for your articles/posts. That way, you could have the terms ro (Romanian) and en (English), then you'd have an archive at /lang/ro and /lang/en. And, you can have a single and standard template (i.e. taxonomy-lang.php) for those archives.

But,

  1. You'll need to assign all your articles to the correct lang term.
  2. You'd still need to use the lang arg/filter for wp_get_archives().
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.