admin管理员组

文章数量:1315336

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.

Update

I have not tried the accepted answer because I started using a plugin (Polylang) for that but for the community I accepted it (and it looks very nice and is detailed).

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.

Update

I have not tried the accepted answer because I started using a plugin (Polylang) for that but for the community I accepted it (and it looks very nice and is detailed).

Share Improve this question edited Nov 20, 2020 at 19:21 silviubogan asked Jun 16, 2020 at 5:10 silviubogansilviubogan 15910 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 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().

本文标签: phpHow to query for pagespost depending on slug