WordPress主题开发教程 12_文章查询

江河/ 06月17日/ WordPress/ 浏览 510

在 WordPress 主题开发中,【文章查询】是重头戏。WordPress 提供了功能强大的文章查询功能。由于其功能过去强大,对于新手并不友好。


1. 在 WordPress 主题中,简单的显示文章列表,只需要使用【主循环】就行,并不需要调用文章查询函数。看过之前文章的朋友,对这一点应该是有所体会的。


2. WordPress 提供了query_posts,get_posts,WP_Query 三种查询文章的方法。三种方法各有不同,提高了学习门槛。



我们选择使用 WP_Query 。虽然,WP_Query 看上去比另外两个函数复杂一点点,但是,WP_Query 可以解决所有的【文章查询】问题,另外两个函数则多少有一些限制。在新手期选择只使用 WP_Query,可以让学习难度至少降低50%。


WP_Query 功能非常强大,上一篇文章中,我就推荐去官方文档学习一下:


https://developer.wordpress.org/reference/classes/wp_query/


之前,在追格上也发过一系列的文章学习 WP_Query:


不想去官方看英文文档的朋友,点击下方【阅读原文】即可查看这一系列文章。


https://www.zhuige.com/news/626.html


我们现在用 WP_Query 来做一些小需求。


首页-精选文章



精选文章的文章,需要在后台设置里,一一设置,名副其实的“精选”。从后台设置项,可以读取到设置的文章ID数组。然后,根据文章ID数组查询、展示就可以了。后台->主页设置里:



这里插播一个小知识点,the_first 主题中,文章列表中的文章大都有一个图片。这个图片是从哪里来的?首选是文章特色图,即用户可以给文章特意设置一个图片:




这个文章特色图功能,开启的方法是在 functions.php 中添加下面的代码:


add_theme_support( 'post-thumbnails' );


如果,用户没有设置这个特色图,则使用文章中的第一个图片-使用正则匹配。代码如下:


/**
 * 获取文章缩略图
 */
function the_first_thumbnail_src($post_id, $post_content)
{
    $post_thumbnail_src = '';


    //如果有特色缩略图,则直接使用
    if (has_post_thumbnail($post_id)) {    
        $thumbnail_src = wp_get_attachment_image_src(get_post_thumbnail_id($post_id), 'full');
        if ($thumbnail_src) {
            $post_thumbnail_src = $thumbnail_src[0];
        }
    } 
    
    // 没有特色缩略图,则使用文中的第一个图片
    if (empty($post_thumbnail_src)) {
        $output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post_content, $matches);
        if ($matches && isset($matches[1]) && isset($matches[1][0])) {
            $post_thumbnail_src = $matches[1][0];   //获取该图片 src
        }
    }


    return $post_thumbnail_src;
}


现在使用 WP_Query 查询文章:


/**
 * 首页精选文章
 */
function home_post_recommend()
{
    $hot_ids = the_first_option('home_post_recommend');
    if (empty($hot_ids)) {
        return false;
    }


    $args = [
        'post__in' => $hot_ids,
        'orderby' => 'post__in',
        'posts_per_page' => -1,
        'ignore_sticky_posts' => 1
    ];


    $hots = [];
    $query = new WP_Query();
    $result = $query->query($args);
    foreach ($result as $post) {
        $thumbnail = the_first_thumbnail_src($post->ID, $post->post_content);
        if (empty($thumbnail)) {
            $thumbnail = get_stylesheet_directory_uri() . '/images/jiangqie.png';
        }
        $hots[] = [
            'id' => $post->ID,
            'title' => $post->post_title,
            'thumbnail' => $thumbnail
        ];
    }


    if (empty($hots)) {
        return false;
    }


    return $hots;
}


我们给 WP_Query 设置了 4 个参数:


'post__in' => $hot_ids - 做需要查询文章的ID数组


'orderby' => 'post__in' - 按文章ID数组中ID的顺序,排列查询结果中文章的顺序


'posts_per_page' => -1 - 不分页,不管文章ID数组中有多少个,只要符合要求的文章,都一次取出


'ignore_sticky_posts' => 1 - 不要再头部插入置顶文章,置顶文章后面还会介绍到,这里先这样设置就好了


然后,查询就得到文章列表,取出我们需要的数据就可以了。


在首页模板中展示:


<?php 
$home_post_recommend = home_post_recommend();
if ($home_post_recommend) : 
?>
<div class="base-list mb-20">
    <h5 class="mb-20">精选文章</h5>
    <div class="row d-flex flex-wrap mb-0-md">
    <!--横向图文列表-->
    <?php foreach ($home_post_recommend as $post) : ?>
        <div class="column md-4 easy-item">
            <figure class="relative">
                <div>
                <a href="<?php echo get_permalink($post['id']) ?>">
                    <img alt="picture loss" src="<?php echo $post['thumbnail'] ?>" />
                </a>
                </div>
            </figure>
            <figcaption class="title">
            <h3><a href="<?php echo get_permalink($post['id']) ?>"><?php echo $post['title'] ?></a></h3>
            </figcaption>
        </div>
    <?php endforeach; ?>
    </div>
</div>
<?php endif; ?>


如果用户未设置-比如刚刚安装这个主题的朋友,按照我们上面的代码,首页就会隐藏【精选文章】这个模块。这种处理方法的优点就是:通过是否设置精选文章ID还可以开关【精选文章】这个模块;缺点就是:萌新用户安装后和预期差距比较大,可能会比较懵。


还有一种处理方式,就是用户未设置的时候,直接显示一组随机文章或者最新文章。和上面的处理方式各有优缺点。如果想再完善一点就单独加一个配置:是否显示【精选文章】模块的开关。


猜你喜欢-详情底部


直接上代码:


<?php
//猜你喜欢
$detail_switch_recommend = the_first_option('detail_switch_recommend');
if (0 && $detail_switch_recommend) : ?>
    <h5 class="mb-20">猜你喜欢</h5>
    <div class="row d-flex flex-wrap mb-20">
        <?php
        $args = array(
            'post_status' => 'publish',
            'post__not_in' => [$post->ID],
            'ignore_sticky_posts' => 1,
            'orderby' => 'comment_date',
            'posts_per_page' => 3
        );


        $posttags = get_the_tags();
        if ($posttags) {
            $tags = '';
            foreach ($posttags as $tag) {
                $tags .= $tag->term_id . ',';
            }
            $args['tag__in'] = explode(',', $tags);
        }
        
        $the_query = new WP_Query($args);
        while ($the_query->have_posts()) {
            $the_query->the_post();
            global $post;
            $thumbnail = the_first_thumbnail_src($post->ID, $post->post_content);
            if (empty($thumbnail)) {
                $thumbnail = get_stylesheet_directory_uri() . '/images/jiangqie.png';
            }
        ?>
            <div class="column md-4 easy-item">
                <figure class="relative">
                    <div>
                        <a href="<?php the_permalink(); ?>">
                            <img alt="picture loss" src="<?php echo $thumbnail; ?>" alt="<?php the_title(); ?>" />
                        </a>
                    </div>
                </figure>
                <figcaption class="title">
                    <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
                </figcaption>
            </div>
        <?php
        }
        wp_reset_postdata();
        ?>
    </div>
<?php endif; ?>


post__not_in 可以排除指定的文章。向用户再次推荐当前文章,肯定是不合适的。所以,排除掉当前文章。


查询当前文章的【标签】,然后通过 tag__in ,查询具有和当前文章相同标签的文章。如果用户喜欢看当前文章,大概也会对有相同标签的文章感兴趣吧。


这次我们是单独设置了开关的:detail_switch_recommend,就像我们刚刚介绍的【控制模块是否显示的开关】。


我们使用 WP_Query 完成了两个小功能,后面我们还会不断使用 WP_Query 去完成各种功能。WP_Query 的功能非常强大。在 WordPress 中,不管是多复杂的查询,WP_Query 都可以轻松应对。所以,务必花点时间学习一下 WP_Query。


最新的代码依旧更新在:


https://gitee.com/zhuige_com/course_jiangqie_theme


https://github.com/zhuige-com/course_jiangqie_theme


下次见,朋友们!





发表评论

暂无评论,抢个沙发...

客服 工单