Timber Wordpress - 显示来自两个类别的帖子块 [英] Timber Wordpress - Show blocks of posts from two categories

查看:25
本文介绍了Timber Wordpress - 显示来自两个类别的帖子块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用以下内容创建了一个新的 page-test.php.

$query = array('category_name' => 'blog,portfolio');$context['posts'] = Timber::get_posts($query);

这仅显示来自这些类别的帖子,这很棒,但我想将它们分组到页面上的特定 div 中.目前我无法获得我的自定义页面或挑逗树枝文件(我不知道我是否需要两者或只需要一个)来覆盖默认的树枝页面.我所做的更改要么破坏了页面,要么似乎什么也没做.

我确定这是完全错误的.

{% 扩展 "base.twig" %}{% 块内容 %}{% 用于帖子中的帖子 %}<div class="blog">{% 包含 ['tease-'~post.post_type~'.twig', 'tease.twig'] %}

{% 结束为 %}{% 用于帖子中的帖子 %}<div class="投资组合">{% 包含 ['tease-'~post.post_type~'.twig', 'tease.twig'] %}

{% 结束为 %}{% 结束块 %}

我不知道如何让特定的树枝文件只显示我想要的内容.

在此先感谢您的帮助.

请注意,我以前使用过 Expression Engine、Statamic 和 Craft,所以对这种类型的东西非常熟悉(虽然不是 php),但出于某种原因,这打败了我.

解决方案

为什么你的第一种方法不起作用

当您收到两个类别的帖子时,您会收到按日期排序的混合帖子,这是您第一次尝试时收到的帖子.您遍历了所有帖子,一次是在类 blog 的 div 中,一次是在类 portfolio 的 div 中.您没有检查帖子实际上是否属于博客作品集 类别.

据我所知,您想在包含中使用 post.post_type 来区分类别.但是,post_type 不是类别,它将是您的帖子的post"和您的页面的page"(或使用自定义帖子类型时的任何其他名称).你的包含试图找到 tease-post.twig,它可能不存在.

所以唯一的区别是:

{% for post in posts %}<div class="blog">{% 包含 ['tease-'~post.post_type~'.twig', 'tease.twig'] %}

{% 结束为 %}

还有这个:

{% for post in posts %}<div class="投资组合">{% 包含 ['tease-'~post.post_type~'.twig', 'tease.twig'] %}

{% 结束为 %}

最后只是div上的类名;).

现在要获取帖子的类别,您可以通过树枝文件中的 post.category 访问它.

{% for post in posts %}<div class="blog">{% 包含 ['tease-' ~ post.category.slug ~ '.twig', 'tease.twig'] %}

{% 结束为 %}

但那样的话,您的博客 div 中仍然会有来自投资组合类别的帖子.

你是怎么做到的

Timber 的美妙之处在于,您可以在将帖子处理到模板之前对其进行处理.您还可以获取从 Timber::get_posts() 获得的帖子,然后将它们拆分、过滤、扩展,随心所欲.

现在我们可以按类别对它们进行排序,然后再将它们交给模板.

一种方法是在查询中传递一个额外的参数.但是为了学习 Timber,我们将采用另一种方法.

我们将为每个类别创建一个包含子数组的新数组.让我们称这个新数组为 $sorted_posts.然后我们遍历所有帖子,获取该帖子的类别并填充 $sorted_posts 以便子数组的键是帖子第一类别的 slug.像这样:

$query = array('category_name' =>'博客,投资组合',);$posts = Timber::get_posts( $query );$sorted_posts = array();foreach ( $posts as $post ) {//获取第一类文章$category = $post->category();//将帖子填回 sorted_posts$sorted_posts[ $category->slug ][] = $post;}//将排序后的帖子添加到上下文$context['posts'] = $sorted_posts;

$sorted_posts 上的 var_dump() 可能如下所示,总共有 5 个帖子(3 个作品集帖子和 2 个博客帖子).

$sorted_posts = 数组(大小=2)'投资组合' =>数组(大小=3)0 =>对象(木材\邮政)[379]1 =>对象(木材\邮政)[430]2 =>对象(木材\邮政)[375]'博客' =>数组(大小=2)0 =>对象(木材\邮政)[378]1 =>对象(木材\邮政)[429]

在你的树枝文件中,你可以循环遍历这些子数组:

{% 扩展 'base.twig' %}{% 块内容 %}<div class="blog"><h3>博客</h3>{% 用于posts.blog 中的帖子%}{% 包含 ['tease-blog.twig', 'tease.twig'] %}{% 结束为 %}

<div class="投资组合"><h3>投资组合</h3>{% 用于posts.portfolio 中的帖子%}{% 包含 ['tease-portfolio.twig', 'tease.twig'] %}{% 结束为 %}

{% 结束块 %}

当您为帖子分配两个或多个类别时,这种方法无法处理.

为什么您的第二个解决方案有效

您在第二种方法中所做的是通过仅获取一个类别的帖子来绕过帖子排序.这样,您就知道在 $context['posts'] 中将只有类别为 story 和在 $context['posts2'] 将只有类别为 news 的帖子.您不会得到必须先排序的混合帖子数组.

现在的好处是:您可能找到了最适合您的案例的解决方案,因为与单独获取每个帖子的类别相比,它使用的数据库查询更少.

当我这样做时(如你怎么能做到")......

foreach ( $posts as $post ) {$category = $post->category();}

... 然后 WordPress 将在附加数据库查询中获取每个帖子的类别.老实说,我不知道是否有可能获得包含该类别的帖子.如果您不需要在首页上展示很多帖子,那么您或您的网站访问者所感知到的性能差异可能可以忽略不计.

TL;DR:干得​​好,坚持你找到的解决方案!

I've created a new page-test.php with the following.

$query = array('category_name' => 'blog, portfolio');
$context['posts'] = Timber::get_posts($query);

This shows posts from just these categories which is great but I want to group these into specific divs on the page. At present I can't get my custom page or tease twig files (I've no idea if I need both or just one) to override the default twig pages. I make changes that either break the page or seem to do nothing.

I'm sure this is totally wrong.

{% extends "base.twig" %}

{% block content %}
    {% for post in posts %}
        <div class="blog">
            {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
        </div>
    {% endfor %}

    {% for post in posts %}
        <div class="portfolio">
            {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
        </div>
    {% endfor %}
{% endblock %}

I've no idea how I make the specific twig files show just the content I want.

Thanks in advance for any help.

Please note I've previously used Expression Engine, Statamic and Craft, so am pretty familiar with this type of thing (not php though) but for some reason this has beaten me.

解决方案

Why your first approach didn’t work

When you get posts for two categories, you get a mix of posts, sorted by date, which is what you got on your first try. You looped over all the posts, once in a div with class blog and once in a div with class portfolio. You did not add a check whether a post was actually in the category blog or portfolio.

As I understand it, you wanted to use post.post_type in your include to discern between the categories. However, post_type is not the category, it will be "post" for your posts and "page" for your pages (or any other name when you use Custom Post Types). Your include tried to find tease-post.twig, which probably didn’t exist.

So the only difference between this:

{% for post in posts %}
    <div class="blog">
        {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
    </div>
{% endfor %}

and this:

{% for post in posts %}
    <div class="portfolio">
        {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
    </div>
{% endfor %}

is in the end only the class name on the div ;).

Now to get the category for a post, you can access it through post.category in your twig file.

{% for post in posts %}
    <div class="blog">
        {% include ['tease-' ~ post.category.slug ~ '.twig', 'tease.twig'] %}
    </div>
{% endfor %}

But then you’d still have posts from the portfolio category in your blog div.

How you could do it

The beauty in Timber is, that you can work on your posts before you handle them over to your template. You can also take the posts that you get from Timber::get_posts() and split them, filter them, extend them, whatever you want.

Now we could sort them by category before handing them over to the template.

One way to do this would be to pass an additional parameter in the query. But for the sake of learning Timber we will take another approach.

We will make a new array with sub-arrays for each category. Let’s call that new array $sorted_posts. We then loop over all the posts, get the category for that posts and fill $sorted_posts so that the keys for the sub-arrays are the slugs of the posts first categories. Like this:

$query = array(
    'category_name' => 'blog,portfolio',
);

$posts = Timber::get_posts( $query );

$sorted_posts = array();

foreach ( $posts as $post ) {
    // Get first category of post
    $category = $post->category();

    // Fill post back to sorted_posts
    $sorted_posts[ $category->slug ][] = $post;
}

// Add sorted posts to context
$context['posts'] = $sorted_posts;

A var_dump() on $sorted_posts could look something like the following, with 5 posts in total (3 portfolio posts and 2 blog posts).

$sorted_posts = array (size=2)
    'portfolio' => array (size=3)
        0 => object(Timber\Post)[379]
        1 => object(Timber\Post)[430]
        2 => object(Timber\Post)[375]
    'blog' => array (size=2)
        0 => object(Timber\Post)[378]
        1 => object(Timber\Post)[429]

In your twig file, you then can just loop over these sub-arrays:

{% extends 'base.twig' %}

{% block content %}

<div class="blog">
    <h3>Blog</h3>
    {% for post in posts.blog %}
        {% include ['tease-blog.twig', 'tease.twig'] %}
    {% endfor %}
</div>

<div class="portfolio">
    <h3>Portfolio</h3>
    {% for post in posts.portfolio %}
        {% include ['tease-portfolio.twig', 'tease.twig'] %}
    {% endfor %}
</div>

{% endblock %}

What this approach won’t handle is when you assign two or more categories to your post.

Why your second solution works

What you did in your second approach was to bypass the post sorting by getting the posts for only one category. This way, you know that in $context['posts'] there will be only posts with category story and in $context['posts2'] there will be only posts with category news. You don’t get a mixed posts array that you’d have to sort first.

Now the good thing is: You probably found the most performant solution for your case, because it uses less database queries than getting the category for each post separately.

When I do this (as in "How you could do it")…

foreach ( $posts as $post ) {
    $category = $post->category();
}

… then WordPress will get the category for each of the posts in an additional database query. I honestly don’t know if there is a possibility to get posts with the category included. If you don’t have many posts that you have to show on your front page, the perceived difference in performance for you or your website visitors is probably negligible.

TL;DR: Good job, stick with the solution you found!

这篇关于Timber Wordpress - 显示来自两个类别的帖子块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆