为什么您的第一种方法不起作用
当您获得两个类别的帖子时,您会获得按日期排序的混合帖子,这是您第一次尝试时得到的。你遍历了所有的帖子,一次是在一个带有类blog的 div中,一次是在一个带有类投资组合的 div 中。您没有添加检查帖子是否实际上在类别博客或投资组合中。
据我了解,您想post.post_type
在包含中使用来区分类别。但是,post_type
不是类别,您的帖子将是“帖子”,您的页面将是“页面”(或使用自定义帖子类型时的任何其他名称)。您的 include 试图找到tease-post.twig
,它可能不存在。
所以这之间的唯一区别是:
{% 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 %}
到底是只有类名上的div
;)。
现在要获取帖子的类别,您可以通过post.category
twig 文件访问它。
{% for post in posts %}
<div class="blog">
{% include ['tease-' ~ post.category.slug ~ '.twig', 'tease.twig'] %}
</div>
{% endfor %}
但是,您的博客 div 中仍然会有来自投资组合类别的帖子。
你怎么能做到
Timber 的美妙之处在于,您可以在将帖子处理到模板之前对其进行处理。您还可以获取您从中获得的帖子Timber::get_posts()
并将它们拆分、过滤、扩展它们,无论您想要什么。
现在我们可以在将它们交给模板之前按类别对它们进行排序。
一种方法是在查询中传递一个附加参数。但是为了学习 Timber,我们将采取另一种方法。
我们将为每个类别创建一个包含子数组的新数组。我们称它为新数组$sorted_posts
。然后,我们遍历所有帖子,获取该帖子的类别并填充$sorted_posts
,以便子数组的键是帖子第一个类别的 slug。像这样:
$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
可能如下所示,共有 5 篇文章(3 篇作品集文章和 2 篇博客文章)。
$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]
在你的 twig 文件中,你可以遍历这些子数组:
{% 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 %}
这种方法无法处理的是当您为帖子分配两个或更多类别时。
为什么您的第二个解决方案有效
您在第二种方法中所做的是通过仅获取一个类别的帖子来绕过帖子排序。这样,您$context['posts']
就知道里面只有带有 categorystory
的帖子,并且$context['posts2']
里面只有带有 category 的帖子news
。您不会得到必须首先排序的混合帖子数组。
现在的好处是:您可能找到了最适合您的案例的解决方案,因为它使用的数据库查询比单独获取每个帖子的类别要少。
当我这样做时(如“你怎么能做到”)……</p>
foreach ( $posts as $post ) {
$category = $post->category();
}
… 然后 WordPress 将在额外的数据库查询中获取每个帖子的类别。老实说,我不知道是否有可能获得包含该类别的帖子。如果您没有必须在首页上显示的许多帖子,那么您或您的网站访问者在性能方面的感知差异可能可以忽略不计。
TL;DR:干得好,坚持你找到的解决方案!