运行中的The Loop(主循环)
简介
“The Loop”是一个涉及WordPress主要进程的术语。用户可以在模板文件中使用The Loop为访问者显示文章。不使用The Loop也可以制作模板,但只能显示一篇文章的信息。
首先,WordPress检查所需文件是否都存在,然后搜集数据库博客管理者中定义的默认设置,包括每页显示的文章数量,是否准许评论,等等。默认设置成立后,WordPress将查看用户需求,并根据用户要求从数据库中调出相应文章。
若用户没有指定任何文章、类别、页面或时间,WordPress会根据之前搜集的默认值来决定为用户显示某篇文章。例如,若博客管理者在 管理面板>设置>阅读中设置每页显示五篇文章,然后WordPress将从数据库中获取五篇最新文章。若用户指定阅读某文章、类别、页面或时间,WordPress会根据用户要求从数据库中返回指定内容。
完成以上操作后,WordPress连接到数据库,检索指定信息并将结果存放在变量中。The Loop访问这个变量,利用变量值在模板中显示信息。
默认情况下,若访问者未指定文章、页面、类别或日期,WordPress用index.php显示所有信息。本文对The Loop的研究,首先放在index.php和用户博客的默认显示上。用户了解运行流程后,文章会对其他模板文件中的The Loop做进一步研究。
世界上最简单的索引页
以下是一个完整的函数索引,该函数索引根据The Loop的准备条件来显示每篇文章的内容(仅内容)。在这里显示函数索引的目的是让大家明白,函数在The Loop中的必要性微乎其微。在index.php中能充分发挥作用、保持The Loop良好运行状态的是CSS,HTML,以及PHP声明。
<?php get_header(); if (have_posts()) : while (have_posts()) : the_post(); the_content(); endwhile; endif; get_sidebar(); get_footer(); ?>
下面就来介绍这些保持The Loop良好运行状态的重要因素。
Loop默认用法
本段内容以WordPress 1.5标准安装程序下的“default”和“classic”主题为背景,循序渐进地介绍了The Loop的默认用法。
启动The Loop
默认index.php模板文件最上方就是WordPress主循环的起始代码。
<?php if (have_posts()) : ?><br /> <?php while (have_posts()) : the_post(); ?>
1. 代码首先判断是否有文章被have_posts()函数搜集。
2. 如果有文章被搜集,启用PHP while 循环。只要圆括号中的条件没有逻辑错误,while循环会一直运行。因此只要have_posts()函数返回的值为真,The Loop就会一直运行下去。
3. have_posts()函数检查是否还有搜集到的文章:有就返回true;没有则返回false。
生成文章
the_post()函数获取文章集合中的当前文章,激活该文章以便在The Loop循环中使用。如果没有the_post()函数,主题中很多模板标签都无法运行。
文章数据被激活后,模板就可以为访问者显示文章数据了。
标题,日期以及作者
用下面的模板标签获取文章的标题,发表时间和作者。
<h2 id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"> <?php the_title(); ?></a></h2> <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
文章内容
用模板标签the_content() 显示文章内容。这是文章穿过The Loop的重要环节:
<div class="entry"> <?php the_content('Read the rest of this entry »'); ?> </div>
如果在文章正文中添加一个名称为“more”的快速标签按钮,显示为<!–more–>,那么访问者只能看到带有下划线的正文部分。如果只希望在首页显示文章的前一两句话,将<!–more–> 插入文章第一行就能达到效果。
浏览单独一篇文章时,<!–more–>分隔符将被忽略。因此请在所有文章中插入<!–more–>分隔符,这样访问者要阅读全文时就不得不点击进入单篇文章。
其他内容
在index.php模板文件中,每篇文章正文下方都留有空间显示文章相关信息,例如文章类别,时间以及评论内容。若访问者具有足够的用户权限(或文章作者),在文章meta数据版块中还会显示 “Edit This(编辑该文章)”链接,链接由edit_post_link()模板文件支持。
<p class="postmetadata"> Posted in <?php the_category(', ') ?> <strong>|</strong> <?php edit_post_link('Edit','','<strong>|</strong>'); ?> <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p>
文章允许评论或已经有评论时,模板标签comments_popup_link()显示评论链接。使用评论弹出窗口时,链接会打开评论窗口;否则链接直接跳转到文章的评论内容。
访问者浏览文章索引时(若The Loop中有不止一篇文章),comments_popup_link()链接会将访问者导向文章具体页面。
自动发现trackback
模板标签trackback_rdf()为自动显示trackback输出计算机可读代码。
<!-- <?php trackback_rdf(); ?> -->
注意: trackback_rdf()标签应与注释码共同使用。
关闭The Loop
以下代码关闭The Loop。文章相关模板标签在The Loop关闭后不能正常运行(如果可以运行则使用The Loop最后一篇文章的相关信息)。这意味着,如果希望在The Loop中使用模板标签,需要预先将标签放入The Loop。
<?php endwhile; ?>
在The Loop被关闭后,下列代码展示了切换网页的导航控制。
<div class="navigation"> <div class="alignleft"><?php posts_nav_link('','','« Previous Entries') ?></div> <div class="alignright"><?php posts_nav_link('','Next Entries »','') ?></div> </div>
若博客设置每页显示10篇文章,The Loop根据条件选择了25篇,那么就需要为三个网页做导航链接:前两个网页每页显示10篇文章,第三个网页显示5篇文章。访问者可以通过导航链接在这三个页面内任意切换。
导航控制存在于The Loop范围外if条件内,因此只在有文章时才能显示导航链接。导航函数本身也会根据当前循环查看是否有文章可供链接,然后根据文章显示导航链接。
<?php else : ?> <h2 class="center">Not Found</h2> <p class="center"> <?php _e("Sorry, but you are looking for something that isn't here."); ?></p>
另: have_posts()(从顶端起)为false时,从句决定下一步动作。也就是说,只有在The Loop中没有文章 时才能执行else后的语句。例如,若访问者查找某一时间但该时间范围内没有文章发表时,或搜索不返回任何结果时,页面上不显示文章。
<?php endif; ?>
这样就结束了“有文章时进行一种操作,没有文章则进行另一种操作”的条件检验。条件检验结束后,默认index.php模板中会包含侧边栏,最后将页脚也包括进去。
其他模板中的The Loop
WordPress可用不同模板文件将博客以不同方式展示给访问者。在WordPress默认主题中有索引视图的模板文件,类别视图的模板文件,还有一个可浏览具体文章的模板。每个模板都使用WordPress主循环,但在格式和模板标签的使用上又有一些差别。
WordPress对没有单独模板文件的视图默认使用index.php。如果访问者请求单独文章,WordPress首先寻找single.php文件。如果文件存在,则用文件向访问者显示文章,如果不存在,WordPress用index.php为访问者显示文章。这被称为模板层级。
制作自己的主题时,可以参考默认主题中的模板文件。将主题中的index.php作为其他模板文件的模板也有一定帮助效果。用户对相关内容和工作页面有所了解之后就可以创造出更多模板文件。
不同存档格式
存档中保存了所有历史文章。在默认用法中,显示在主索引上的文章都是时间上排在最近的文章。访问者点击存档链接或手动选择某一时间的存档文章(http://www.example.com/blog/index.php?m=200504 或http://www.example.com/blog/2005/04,选择2005年4月所有文章)后,WordPress显示存档视图。默认情况下,存档使用index.php文件,与主页版式相同,但只显示2005年4月的文章。
WordPress为访问者准备存档索引时,会在当前主题目录中仔细查找是否有一个名为archive.php的文件。如果不希望存档页面与主页版式相同,将index.php复制到archive.php并在必要时对archive.php进行编辑即可。
例如,如果用户希望只显示文章标题而不显示内容,可以再存档列表中使用如下代码:
<?php get_header(); ?> <div id="content" class="narrowcolumn"> <?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); ?> <div class="post"> <h2 id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h2> <small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small> </div> <?php endwhile; ?> <div class="navigation"> <div class="alignleft"> <?php posts_nav_link('','','« Previous Entries') ?> </div> <div class="alignright"> <?php posts_nav_link('','Next Entries »','') ?> </div> </div> <?php else : ?> <h2 class="center">Not Found</h2> <p class="center"><?php _e("Sorry, but you are looking for something that isn't here."); ?></p> <?php endif; ?> </div> <?php get_sidebar(); ?> <?php get_footer(); ?>
不同类别
与准备存档索引相似,WordPress也会为分类索引查找一个单独模板文件。访问者点击博客中的类别链接时就会被导向到类别视图。WordPress为The Loop准备被选中类别中的文章,并将文章数量限制在博客默认的最大数量之内。
如果不希望类别视图与索引视图版式相同,可复制index.php并重命名为category.php。在类别视图中不必列出某篇文章所属的所有类别,因此可以将这部分内容删除,然后在页面上方声明类别。
<?php get_header(); ?> <div id="content" class="narrowcolumn"> <p> <strong> <?php single_cat_title('Currently browsing '); ?> </strong><br /> <?php echo category_description(); ?> </p> <?php if (have_posts()) : ?> <?php while (have_posts()) : the_post(); ?> <div class="post"> <h2 id="post-<?php the_ID(); ?>"> <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"> <?php the_title(); ?></a></h2> <small> <?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --> </small> </div> <?php endwhile; ?> <div class="navigation"> <div class="alignleft"> <?php posts_nav_link('','','« Previous Entries') ?> </div> <div class="alignright"> <?php posts_nav_link('','Next Entries »','') ?> </div> </div> <?php else : ?> <h2 class="center">Not Found</h2> <p class="center"><?php _e("Sorry, but you are looking for something that isn't here."); ?></p> <?php endif; ?> </div> <?php get_sidebar(); ?> <?php get_footer(); ?>
不同类别的不同格式
模板层级中描述到,为每个类别都创建一个单独的模板文件已经成为可能。将模板文件命名为 category-X.php,其中 X 是类别的数字编号。创建模板前请慎重考虑类别是否的确需要全新模板。
假设类别“Plants”和“Flowers”的编号分别是3和4。如果用户希望在文章标题旁显示文章所属类别的图片标记(植物或花朵),可以使用以下方法:
- 为文章标题分别使用文件category-3.php 和category-4.php,两个文件含有不同img标签
- 在默认category.php文件中使用条件检验,判断当前类别是“Plants”或“Flowers”(也可能不属于两种类别中任一种),然后显示相关图片:
<?php if (is_category('3') ): // we're in the Plants category, so show a plant ?> <img src='/images/plant.png' alt='a plant' /> <?php } elseif (is_category('4') ): // we're in the Flowers category, so show a flower ?> <img src='/images/flower.png' alt='a pretty flower' /> <?php endif; // end the if, no images for other other categories ?>
如果希望再添加一个类别“Cars”并以完全不同的方式显示该类别图片,这时创建一个单独category-X.php文件较为合适。
不同类别的不同CSS样式
很多用户都希望为特定类别单独制作CSS文件,事实上这很容易解决。HTML文件的<head>部分负责定义并加载样式表单,在WordPress中则使用 header.php文件。在默认header.php文件中寻找以下命令行:
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
将命令行修改为:
<?php if ( is_category('5') ) { // Load special CSS for "Cars" category ?> <link rel="stylesheet" href="<?php bloginfo('template_url'); ?>/category-5.css" type="text/css" media="screen" />; <?php } else { ?> <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" /> <?php } ?>
注意: Cars模板用category-5.css文件改写默认版式。本例中以所应用的类别模板文件而不是类别的实际名称为CSS文件命名。这样就可以推断出 category-5.css 与category-5.php相匹配。
单篇文章的不同格式
WordPress使用single.php文件帮助访问者浏览单篇文章(或固定链接)。
WordPress默认single.php文件中的以下部分显示了当前文章的文章meta数据信息:
<p class="postmetadata alt"> <small> This entry was posted on <?php the_time('l, F jS, Y') ?> at <?php the_time() ?> and is filed under <?php the_category(', ') ?>. You can follow any responses to this entry through the <?php comments_rss_link('RSS 2.0'); ?> feed. <?php if (('open' == $post->comment_status) && ('open' == $post->ping_status)) { // Both Comments and Pings are open ?> You can <a href="#respond">leave a response</a>, or <a href="<?php trackback_url(display); ?>">trackback</a> from your own site. <?php } elseif (!('open' == $post->comment_status) && ('open' == $post->ping_status)) { // Only Pings are Open ?> Responses are currently closed, but you can <a href="<?php trackback_url(display); ?> ">trackback</a> from your own site. <?php } elseif (('open' == $post->comment_status) && !('open' == $post->ping_status)) { // Comments are open, Pings are not ?> You can skip to the end and leave a response. Pinging is currently not allowed. <?php } elseif (!('open' == $post->comment_status) && !('open' == $post->ping_status)) { // Neither Comments, nor Pings are open ?> Both comments and pings are currently closed. <?php } edit_post_link('Edit this entry.','',''); ?> </small> </p>
无论评论是否关闭,这些信息都不宜在索引、存档或类别视图中出现;因此类似信息都被存入single.php模板文件。
The Loop使用技巧
学习完WordPress Loop(循环)的基本用法后,下面就来看看循环的其他效果和使用诀窍。
静态首页
怎样才能只在博客首页上显示一些特别内容呢?也就是说除了首页,博客其他地方都不显示这些内容。其实很简单。这种方法被称为首页静态化。博客站点的首页并不是静态的,只是the Loop会将首页显示得如同静态页面。
用条件模板标签函数 is_home()帮助完成这次loop效果。
在Index.php中用if()检验选择性输出附加内容:
<?php get_header(); ?> <?php if (is_home()) { // we're on the home page, so let's show a picture of our new kitten! echo "<img src='/images/new_kitty.jpg' alt='Our new cat, Rufus!' />"; // and now back to our regularly scheduled home page } ?>
若访问者未请求具体文章、页面、类别或时间,is_home()函数将返回true,最终显示结果即博客主页。
了解更多信息请查看制作WordPress静态首页。
显示文章摘要
如果希望只显示文章摘要而不是全文,最简单的方法是将所有the_content()实例替换为the_excerpt()。若用户没有为文章编辑摘要,函数自动显示文章内容的前55个单词。
<div class="entry"> <?php the_excerpt(); ?> </div>
根据页面文章数量自动显示摘要或全文
在存档页面或其它一些情况下,网页中可能只有一篇文章,这时用户希望显示文章的全文,也可能有很多篇文章,这时用户又希望显示文章摘要。通过自定义the Loop就可以达到这种效果。
<?php if (have_posts()) : ?> <?php if (($wp_query->post_count) > 1) : ?> <?php while (have_posts()) : the_post(); ?> <!-- Do your post header stuff here for excerpts--> <?php the_excerpt() ?> <!-- Do your post footer stuff here for excerpts--> <?php endwhile; ?> <?php else : ?> <?php while (have_posts()) : the_post(); ?> <!-- Do your post header stuff here for single post--> <?php the_content() ?> <!-- Do your post footer stuff here for single post--> <?php endwhile; ?> <?php endif; ?> <?php else : ?> <!-- Stuff to do if there are no posts--> <?php endif; ?>
不同页眉/侧边栏/页脚
WordPress的模板文件中有get_header(), get_sidebar(), 以及get_footer()等Include标签以供使用。通过这些函数用户可轻松定义易于编辑的标准页眉/侧边栏/页脚。无需其他操作,对这些文件的更改就能立即反映在访问者所浏览的页面上。
有时用户不需要显示侧边栏,这时可以从模板中删除对get_sidebar() 函数的调用。例如WordPress默认主题的single.php模板中没有侧边栏。
为自己创建侧边栏时有两种方法可供选择:
1. 将侧边栏内容直接插入目前正在运作的模板文件。如果希望类别3的侧边栏与众不同,可以编辑category-3.php,在其中添加必要的HTML和PHP文件,制作一份独一无二的侧边栏。
2. 在PHP函数 include 中加入另一个文件。WordPress中的get_sidebar()函数只加载sidebar.php文件。若用户希望创建一份名为sideleft.php的文件,使用以下代码:
<?php include(TEMPLATEPATH . '/sideleft.php'); ?>
在WordPress 2.5 及以后版本中,也可以用以下方法调用侧边栏:
<?php get_sidebar('right'); ?>
这会生成模板的模板路径。 'sidebar-right.php'应包含在代码中。
可以利用WordPress默认模板层级在多个模板上使用相同要素,最好将要素分别放置在独立模板文件中并使用PHP函数include()。若添加的要素是某模板文件独有的,可将该要素直接添加到相应的模板文件中。
总结
本文只是对The Loop用法的浅显介绍,以下文章能够让读者进一步了解如何定制WordPress主循环。
外部资源
- The Ultimate Guide to the WordPress Loop
- WordPress Triple Loop Tutorial
- Multiple Loops with Multiple Columns
- Super Loop: Exclude Categories and Limit Number of Posts
- Easily Adaptable WordPress Loop Templates: Basic Loops, Mullet Loops, and More
- Horizontally Sequenced Display Order for WordPress Posts in Two Columns
分类:中文手册