<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
代码取自Loop WordPress Codex页面。
好像有
if
循环,就可以正常工作。如果没有
while
语句,在什么情况下会出现问题?编辑
我接受了@Chip的回答。但老实说我只需要最后一部分。
我现在知道我想从我的问题中知道什么。想要放置仅应写入一次的页眉或页脚。如果您不使用“包装器”,则不需要
if
语句。#1 楼
WordPress模板加载器在许多情况下都将包括适当的上下文模板文件,即使该上下文的查询未返回任何帖子。例如:主博客文章索引
类别存档索引(类别存在,但没有帖子)
标签存档索引(标签存在,但没有标签)帖子)
作者存档索引(作者存在,但没有帖子)将输出,因为查询不返回任何帖子。
概念验证示例:
类别存在,但没有帖子(
类别不存在(包括404模板)
因此,在这些情况下,模板文件包含条件
if ( have_posts() )
很有用。在其他情况下,如果查询不返回任何帖子,则将永远不会加载模板文件。例如:
单个博客文章
在这种情况下,可能不需要
if ( have_posts() )
。编辑
我知道该查询由the_post()调用,对吗?而且,如果while(have_posts())存在,那么如果没有发布,则永远不会进行查询。以
wp_loaded
开头(为清楚起见,省略了一些内容):wp_loaded
parse_request
send_headers
parse_query
pre_get_posts
wp
template_redirect
get_header
wp_head
the_post
wp_footer
那么,怎么回事,按什么顺序?
查询被调用:
parse_query
pre_get_posts
wp
已选择模板:
template_redirect
模板已加载/输出。模板会触发以下操作:
get_header
wp_head
the_post
dynamic_sidebar
get_footer
wp_footer
因此,由
the_post
触发的the_post()
发生在解析查询,获取帖子和模板之后已加载。非常感谢您提供了许多我不知道的信息,但这不是我要的。
哦,但我相信这正是您的要求。
真正的问题是:有效的查询返回是什么?对于类别存档索引之类的上下文,查询有效,并且即使存在查询的类别ID(即使没有分配给该类别的帖子),也加载了类别模板。为什么?因为要解析的查询是(IIRC)
&cat={ID}
-即使没有分配给该类别的帖子,这也是一个有效的查询,因此在解析时不会导致404。 ,您将获得一个有效的查询,并加载了一个模板文件,但没有任何帖子。因此,if ( have_posts() )
实际上是相关的。同样,这是一个示例:存在类别,但未分配任何帖子。类别模板文件已加载,其中if ( have_posts() )
返回false
。 编辑2
如果我正确地理解是否没有if(have_posts( ))在类别模板中,并且类别没有帖子,那么即使它应该是没有帖子的return category-sample.php,它也会返回404.php。是吗?
不。请记住:已在
&p={ID}
上选择了模板。因此,如果查询有效,那么将加载适当的模板文件。如果查询无效,则会加载404模板。因此,一旦加载了模板-例如类别模板-输出循环后,模板不会更改。
再次查看操作顺序:
template_redirect
parse_query
pre_get_posts
wp
-选择模板并在此处加载。这是不可退回的模板点。此后模板无法更改。...
template_redirect
-在循环调用中,此处已设置postdata。这在模板内部被调用,并且模板不会根据查询对象中的可用数据而更改最终编辑
检查帖子的存在情况,为什么我应该两次运行相同的测试。从一开始我就是一直问这个问题。 WordPress循环。您是在询问将任意PHP
the_post
循环包装在检查相同条件的while
条件中。 br /> if
条件是二进制评估:它是if
或true
,并且该条件内部发生的事情只执行一次。 ,基于某种计数器;并多次执行该条件内发生的事情-每次计数器迭代一次。因此,假设您要输出无序的事物列表(如果填充了事物列表) 。如果使用
false
循环并省略while
包装器,则标记将如下所示: br /> <ul>
<?php while ( list_of_things() ) : ?>
<li><?php the_list_item(); ?></li>
<?php endwhile; ?>
</ul>
留下了不必要的(和无效的)标记。
但是如果添加
while
条件包装器,则可以执行以下操作:<ul>
</ul>
如果
if
为空,则根本不会输出任何标记。那只是一个例子。该
list_of_things()
条件包装器有很多用途,而if
条件包装器的用途与list_of_things()
循环的用途完全不同。评论
很长一段时间以来,在我单一的帖子/页面模板中,我只使用the_post();。因为那一刻也是不必要的。 +1为信息的完整性。
– gmazzap♦
2013年10月9日17:00
@GM可能删除if(have_posts())语句很有意义(这就是我要找出的内容),但不要只在单个页面中使用the_post()!
– Sunyatasattva
13-10-12在20:53
@ChipBennett全部考虑,您是否认为在单个* .php和page-*。php模板文件的上下文中的完整循环之前删除if(have_post())条件是否安全?
– Sunyatasattva
13-10-12在20:55
在这种情况下,“安全”确实没有明确的含义。
–芯片Bennett
13-10-12在21:05
#2 楼
实际上,要改善Chip的答案是不可能的,而只是切合实际:如果您想在没有帖子的情况下显示一些其他内容,请使用
if
部分。例如,在日期或类别存档页面上,这特别有用。如果有人导航到没有帖子的页面,那么很高兴收到这样一条消息,而不是什么也没显示,因为循环永远不会执行。if ( have_posts() ):
// Yep, we have posts, so let's loop through them.
while ( have_posts() ) : the_post();
// do your loop
endwhile;
else :
// No, we don't have any posts, so maybe we display a nice message
echo "<p class='no-posts'>" . __( "Sorry, there are no posts at this time." ) . "</p>";
endif;
评论
这就是所有需要知道的。
– Herbert Van-Vliet
18年5月18日在21:08
#3 楼
到目前为止,答案中可能还没有包括一些注意事项。不建议省略if语句。if语句通常用于:没有为其分配任何文章。
确定是否应在文章前后输出周围的html(如ul)。
如果添加了新的钩子怎么办? br />不使用if语句的另一个可能的问题是,如果wordpress团队决定添加一个新的钩子,该钩子会在第一个
no posts found
调用时触发,那么它将在错误的时间触发。如果这导致了意外的行为,则可能是您未能正确遵循规范而引起的错误。希望看到整个wordpress循环。因此,让他们搜索不存在的if语句可能不是一个好主意。#4 楼
我认为这是控制结构理论的基本问题。即使条件(have_posts())第一次评估为false,while循环中的封闭块也不会执行一次。因此,WordPress循环中
if ( have_posts() )
的目的是在对while条件求值之前仅执行一次have_posts()函数。如果have_posts()
没有副作用,则if ( have_posts() )
完全没有意义。如果have_posts()
确实有副作用,则可以简化如下:<?php have_posts(); ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>
评论
这种简化是无效的PHP,您有一个else语句,该语句没有附加的if语句。充其量很难读
– Tom J Nowell♦
14-10-23在23:27
如果在那儿是因为后面的其他。没有其他原因。如果没有帖子,那么显示一个很好的“ no posts”消息比什么都不显示更好。
–奥托
14-10-24在0:13
评论
我在阅读the_content之前投票赞成,the_title是决定性的!优秀(最终)编辑。大多数人彼此直接使用if和while,而从未使用过else。可能是因为复制粘贴。