1.3 LOOP循环模块

现在你已经安装了基本的WP系统并且掌握了主题的基本概念,是时候看看系统是如何运行的了。这一章会告诉你什么是loop,loop是个基本的PHP查询用于向WP请求一些输出的。这一章会从一些基本的用法开始讲的,然后是跳转到多重循环(multiple loops)和一些很有效果的漂亮的小技巧。

你需要理解loop才能创建真正的WP网站,就算你不用事无巨细都了解,至少应该明白loop是什么,做什么。这样的话,当你遇到自定义的内容输出问题时,你可以搜索很多可用的函数来解决问题;

[tab:理解Loop]

1、理解WordPress的loop(Understanding the WordPress Loop )

Loop循环是WP的核心, 他就出没在主题的模板文件里。你当然也可以写一个没有loop的主题,但是这会让诸如显示最近的文章或者浏览以前的文章这类原本简单的内容的输出变得十分困难。有个别模板文件,比如404错误页面,根本没有loop循环,但是大部分文件都是有的。如果你想在模板文件中找到它,打开index.php即可,因为这页是你显示文章列表的页面。

一些模板标签只在loop循环模块内部工作,因此你需要能够辨识这些函数,在下一节就会看到他们。

  • 最基本的loop循环

如果你想用WP建站,你必须要理解loop,很幸运,最基本的loop是极其简单的,它以下面的代码开始:

[cce_php]<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>[/cce_php]
以下面的代码结束:
[cce_php]
<?php endwhile; else: ?>
      <p>Some error message or similar.</p>
<?php endif; ?>
[/cce_php]

事实上,你并不需要输出错误的这段代码,但是既然大部分主题里都有这段代码,那么就先写在这里。其实这里可以用一个404错误页面来代替,或者显示一个没有任何搜索结果的页面。

下面的代码是一个完整的loop模块,loop内有着最常用的内容输出函数,你会在大部分主题里找到他们或者极为类似的代码:

[cce_php]
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 
    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2>
        <?php the_content(); ?>
        <?php get_comments(); ?>
    </div>
<?php endwhile; else: ?> 
    <div>
        <h2>Error!</h2>
        <p>Something went wrong! Please try again.</p>
    </div>
<?php endif; ?>
[/cce_php]

当然,你可能想要一个更具有直观性的错误消息而不是上面的文字,不过那不是现在的重点。

最基本的loop检查是否有文章可以返回输出,并且用博客的全局设置来控制输出的样式(比如一页要显示多少文章等)。一个单独的文章页面只会返回一篇特定的文章,而一个分类页面则会列出所有属于这个分类的文章。

如果有文章返回,那么一个while loop就会开始执行,并且只要查询到还有文章可以输出,在全局变量的控制下,文章就会继续的输出并显示。当循环结束(所有应该输出的文章都显示完毕后)的时候,有一个endwhile来结束循环,然后用endif来结束整个loop;

如果没有任何文章符合输出的条件呢,那么else语句就会被调用,而这就是错误消息显示的时候。或者什么都不输出如果没有定义错误消息的话,这之后,loop就全部结束了。

因此,loop事实上总是从数据库里循环输出符合条件(包括博客的全局设置和你的查询条件)的文章,搞懂了吗?其实很简单是不。

关于WP_Query的一些知识

尽管你压根没在基本的loop代码里看到WP_Query,但WP_Query却是loop的核心。这是一个处理loop内部功能的类(Class),你可以在 wp-includes/query.php中找到它如果你乐意深究的话。多数情况下你更会乐意在代码手册(codex.wordpress.org/Function_Reference/WP_Query)找到WP_Query的所有描述性质和方法。

最基本的loop模块使用WP_Query,或者说它使用默认的 $wp_query对象。这就是说,当你使用have_posts()或者the_post()时,你实际上在使用$wp_query->have_posts()和$wp_query->the_post(),换言之,have_posts()之类的函数们默认认为你在使用他们的时候就是想使用$wp_query对象。任何时候当你要跳出$wp_query对象来创建自己的查询语句时,你都必须创建一个用于查询的对象,我们将在多重loops章节和后面的例子中这样做,如下所示:

[cce_php]<?php $brand_new_query = new WP_Query(); ?>[/cce_php]

这里你把所有的数据加载到$brand_new_query里而不是默认的$wp_query,而这就意味着你要做一些主循环loop之外的事情了。

大多数函数都会和WP_Query类连接,包括主题标签和条件语句,如果可能,你应该尽可能用这个,你可以改变WP_Query类内部的事情,不过如果已经有了现成的解决方案就要尽量避免那样做,这算是常识和约定。当然了,你或许有那么一次要跳出这个盒子做点其他事,不过这是后话。
[tab:使用Loop]

2、使用Loop( Using the Loop)

目前你应该已经搞懂了哪里需要loop循环(在文章的列表页面,当然单独的文章页面single.php也算是列表长度为1的列表),并且你可以同时运行几个loop,问题是如何能够更好的使用loop而不仅仅是使用。比如,你可能不想在分类页面展示全部的文章内容,而只是显示摘要。这就要用到模板标签,用到控制内容输出的模板标签。

这一章我们首先快速的浏览一下常用的标签,比如说你要显示文章标题,并且要链接到具体的文章页面。下面这段代码片几乎是每个主题里用来列出文章列表的代码,偶尔也会只列出一篇,比如single.php里:

[cce_php]<h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h2>[/cce_php]

这确实很简单,用这些函数来输出文章的标题(并且在link里的title属性也是文章的标题)。包住title的就是常见的超链接,从the_permalink()中获得链接的值,当然就是我们要求的文章的真实链接了。一切都顺利成章,让我们来输出一些内容吧,你有两个选项,使用下面两个模板标签里的任意一个。

[cce_php]
<?php the_content() ;?>
<?php the_excerpt() ;?>
[/cce_php]

上面第一个输出文章的全文,除非在是在文章的列表页面而且你的文章里用了<!—more—>这个标签,那么第一个才会输出<!—more—>这个标签之前的内容,如果没用这个标签,那么也同样会输出全文。如果你用过Wordpress,你就会知道这些,More按钮就在HTML编辑窗口中,其功能是插入一个read more的链接。如你所料,你也可以以任何一种方式显示这个链接:

[cce_php]<?php the_content('Read more here, mate!') ;?>[/cce_php]

这会用“Read more here, mate!”来替换默认的read more链接。该函数还有一些更多的选项,你甚至可以放入HTML代码(可能用图片来替换文字),不过这不是这里要讲的重点。重点是模板函数the_content()输出文字内容,并且在列表页面输出<!—more—>之前的内容,然后跟一个”read more”链接;

当然了,当你在一个独立的文章页面时,the_content()则总是输出全文而不会有read more链接。

第二个输出内容的模板函数是the_excerpt(),顾名思义,它只输出内容的摘要,默认是文章的前55个字符。所有的HTML内容,不过是图片还是断行符或者视频内容都不会出现在摘要里。因此用这个函数还是要小心起见。不过这里没有什么费解的参数,对吧。你可能以为你应该可以控制输出摘要的长度,不过,这次你错了,真的没有参数控制这个。

图3-1 所有这些内容都是在loop循环中输出。

 

不过,the_excerpt()的确有一个功能,你应该知道在WP后台发布文章的框下面有个填写摘要的文本域(图3-2),如果你在那里写了东西,那么the_excerpt()就会输出你写的东西而不是默认的前55个字。因此一个简单的“你好,这是我的文章”填在摘要区域里,文章的摘要就会输出“你好,这是我的文章”,尽管这比55个字符还要短。

图3-2 WP后台发布文章的摘要区域

那么 the_excerpt()的好处到底是什么呢,有可能你不希望输出全文在列表页面占用太大的空间,比如搜索结果页面和类似归档的页面。

不过,the_excerpt()最明显的用法是用来置顶、推广你的文章,你可能在主页最上方有一个单独的loop用户输出特定标签的文章,你也照常输出他们的标题,而你想用the_excerpt()只输出他们的摘要而不是全文。下面我会展示如何使用。

先来澄清一下the_excerpt()的默认用法:

[cce_php]<?php the_excerpt(); ?>[/cce_php]

记住不要再独立的文章页面例如single.php里使用该函数,那里你需要的是the_content()函数来展示全文。当然了,你可以一起使用它们。

动手尝试:用摘要取代全文

1、打开默认主题(wp-content/themes/default)里的index.php,他的代码如下:

 

[cce_php]
<?php
/**
 * @package WordPress
 * @subpackage Default_Theme
 */
get_header(); ?>
<div id="content" role="main"> <?php if (have_posts()) : ?>
  <?php while (have_posts()) : the_post(); ?>
<div <?php post_class() ?> id="post-<?php the_ID(); ?>">
<h2><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to
<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
<small><?php the_time('F jS, Y') ?> <!-- by <?php the_author() ?> --></small>
<div>
<?php the_content('Read the rest of this entry &raquo;'); ?>
</div>
<p><?php the_tags('Tags: ', ', ', '<br />'); ?> Posted in
<?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?> <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?></p>
</div>
  <?php endwhile; ?>
<div>
<div><?php next_posts_link('&laquo; Older Entries') ?></div> <div><?php previous_posts_link('Newer Entries &raquo;') ?></div>
  </div>
 <?php else : ?>
<h2>Not Found</h2>
<p>Sorry, but you are looking for something that isn't here.</p> <?php get_search_form(); ?>
37
<?php endif; ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>
[/cce_php]

2、用the_excerpt替换the_content,从而来显示摘要。你会在20行左右找到下面的代码:

[cce_php]<?php the_content('Read the rest of this entry &raquo;'); ?>[/cce_php]

 3、用下面的代码替换第2步里的代码

[cce_php]<?php the_excerpt(); ?>[/cce_php]

4、保存并上传index.php,这样你就可以看到默认的摘要输出(前55个字)而不是全文输出。因为主题都有自己的single.php来输出详细的全文,你不用担心这里只显示了摘要。如果你乐意,记得还可以在图3-2的地方填入自己的摘要,那么填入的文章就会优先输出,而不是输出前55个字。

 

  • 关于文章的置顶

WordPress从2.7版本开始增加了一个叫做sticky post(置顶文章)的东西,经常逛论坛的人应该很熟悉这个词,基本上就是通过置顶将一篇文章一直保持在页面的最顶端(见图3-3)。在文章的编辑界面,你可以通过设置该文章为置顶,从而让文章一直保持页面顶端。如果两篇文章都设置了置顶,那么会按照时间顺序排在页面的最顶端,以此类推。当你从后台撤消了该文章的置顶,那么该文章就会自动与剩余的文章一起正常排序。

图3-3 在首页置顶的文章会一直显示在页面顶部

模板函数里有一个sticky_class()用于输出置顶文章的样式类。不过和post_class()函数比起来则没有太大用处。

[cce_php]<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>[/cce_php]

可爱的post_class()函数会根据文章的详细设置给文章增加一些css类,这对于设计师来说是十分有用的,因此我们还会在第六章深入讲述post_class();

如果一篇文章被设为置顶,post_class()就会增加一个.sticky的css类,你可以任意修改这个类的样式,比如你想要一个淡灰色的背景,更大的字号等等,只需要将这些样式加入到你的style.css的.sticky类里即可。

[cce_css].sticky { padding: 15px; background: #eee; border: 1px solid #bbb; color: #444; font-size: 18px; }[/cce_css]

上面的css代码会应用到置顶文章里:浅灰的背景和暗边框,18px的字体;

下面是在基本loop循环里的应用:

[cce_php]
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 
    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
            <?php the_title(); ?></a></h2>
            <?php the_content(); ?>
    </div>
<?php endwhile; else: ?>
    <p>Some error message or similar.</p>
<?php endif; ?>
[/cce_php]

还想对置顶文章做更多的设置?有个条件函数is_sticky()能帮助你做一些事情,或许你真的想特别突出这个置顶的文章,那么为什么不这么做呢:

[cce_php]<?php if (is_sticky()) echo 'Super important post! Read it! Now!'; ?>[/cce_php]

怎么样,页面顶部的一道风景哈? 但是更多时候是用于输出或者更改通知等事情,这取决于你如何使用了。基本的概念是置顶的文章确实足够重要,你想你的读者都看到它,比如在博客上出售你的电子书等等。

[cce_php]<?php if (is_sticky()) echo 'The latest e-book release by yours truly'; ?>[/cce_php]

因为WP之前的版本没有置顶这项功能,所以主题的设计师和用户都经常忘记有这么个功能。千万记得用置顶当你真的要强调重要的内容时。

 

  • 利用query_posts()发挥功能

每个善于使用loop的和雄心勃勃的主题设计师都应该知道强大的query_post()工具。本质上来说,query_post(),就是使得wordpress的默认loop循环里的数据变得具有可操作性,比如你可能想限制输出文章的数量,去除一些不想输出的分类或者改变排序之类的特殊需求。

需要谨慎的是:query_posts()只能用在单个的主循环中,而不是用在多重loop中,虽然也是可以用在多重loops中,但是结果可能会比较怪异,所以最好别再多重loops里用。你会在“多重loops”这一节学到如何创建任意多的loops。

query_posts()的使用方法也很简单,像下面的代码所示,放在你的loop循环之前:

[cce_php]
<?php query_posts(); ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
 <!— Doing stuff here, styling the posts and so on. —>
<?php endwhile; else: ?>
 <p>Some error message or similar.</p>
<?php endif; ?>
[/cce_php]

当然了,你可以把上面的代码写的更加紧凑,query_posts()前后的PHP的标签没必要单独使用,可以和下面的have_posts()部分写在一起。

那么,这到底对loop做了什么呢?实际上什么也没做,因为你还没有给query_posts()传入任何参数。由于这个函数没有任何默认参数,因此会输出标准的loop结果。query_posts()真正能做的事情就是告诉SQL语句在loop循环之前要满足你的需求。

现在你已经熟悉了query_post()函数,你可以尝试几个例子了。首先,你需要知道有很多使用该函数的方法,它的确有很多的设置,并且和条件函数配合使用可以得到千变万化的组合。

首先,从某个分类下去除所有文章开始做起,可能你在那个分类下你只放了几个短小没意义的文章,你需要先得到该分类的ID,这可以从后台编辑分类的地方得到,ID就隐藏在URL的末尾。

[cce_html]http://25.timepaw.com/wp-admin/categories.php?action=edit&cat_ID=130[/cce_html]

如你所看到的,cat_ID=130告诉你ID就是130.记住,分类的ID或者任何的ID都只是纯粹的数字,没有其他任何关系,文章、分类、标签所有的ID都是混合的,因此你可能前一个分类ID是3后一个就说不定是749。

回到我们的例子里,我们不想在展示ID为130的分类下的文章,codex.wordpress.org/Template_Tags/ query_posts这里的query_posts()代码手册说,你可以使用很多方法来传入分类的信息,使用cat参数,比如IDs。

[cce_php]<?php query_posts('cat=-130'); ?>[/cce_php]

这行代码,如前所述放在loop的前面,会去除属于分类ID为130的文章。请注意这里ID数字前的负号“-”,你必须要有它,如果没有负号,你就会得到恰好相反的结果——只输出分类ID为130的文章。基本上来说,ID前的一个负号都表示你排除了这个ID,因此这是很有用的。

接下来,显示文章标签为blue,green,yellow的文章,很简单,只需要把下面的代码放在loop前面:

[cce_php]<?php query_posts('tag=blue+green+yellow'); ?>[/cce_php]

这里,你显然是使用了tag这个参数,和cat这个参数一样,还有很多类似的参数可以传入。比如你可以通过query_posts()只获得某个作者写的文章,对任何数据做一些基础的查询和排序。你甚至可以抓取自定义字段并且拿他们来做事。你会在稍后建站的时候做很多类似的事情。

有一个问题你可能会疑惑,那就是query_posts()到底返回多少条数据?这仍旧是受WP设置(每页显示的数量)的控制。幸运的是连这个你也可以通过传入参数来控制。比如说,你想你的首页显示5篇文章,而其他分类页面依旧显示10篇文章。你可以通过两种方式处理这个问题,你可以创建一个home.php并且里面使用query_posts()来控制,或者在index.php里使用一个条件语句。第一种方法是最简单干净的,通过传入posts_per_page这个参数来控制显示:

[cce_php]<?php query_posts('posts_per_page=5'); ?>[/cce_php]

把上面的代码放在你home.php的loop前面,就会只显示5篇文章在首页,简单吧!现在,用第二种方法来试试,在index.php里加入条件语句,因为你可能的确不怎么需要一个单独的home.php文件。你需要做的全部就是使用is_home()条件函数来判断当前页面是否是首页,如果不是,一切照旧,如果是,就会先执行query_posts()函数。这样你会得到和前面增加home.php一样的效果:

[cce_php]
<?php
   if (is_home()) {
query_posts('posts_per_page=5'); }
?>
[/cce_php]

既然你已经可以控制要显示文章的数量了,当然你也可以去掉这样的限制。只要讲posts_per_page设为“-1”,你就会列出所有符合条件的文章,如果你有成千上万篇文章,千万别这样做,因为一旦你这样做,该页面会显示你全部的文章,而这对于数据库并不是很好玩的SQL查询。不过,换言之,你可以用这个方法来显示比如作者Admin在2011年发布的全部文章。

[cce_php]<?php query_posts('author_name=Admin&year=2011&posts_per_page=-1'); ?>[/cce_php]

如你所见,query_posts()以查询条件的方式传入参数,这意味着你可以填很多条件进去,只要别太复杂即可。我们往后会经常用query_posts()函数,所以掌握它吧。

[tab:多重Loops]

3、使用多重loops

有时候你可能需要在一个页面使用多重loops,你可能你想多展示一个非常重要的分类的文章,可能你想在侧边显示一下最近的文章,总之当你想在同页面内第二次获取某个文章时就需要使用另一个loop了。这个用法在你想改变博客传统的布局的时候是经常要用到的,因此也是掌握为好。

从简单的多重loop开始——在一个页面内新增一个loop。这里需要靠rewind_posts()函数,该函数会重置先前loop的指针让你再次查询。

[cce_php]
<?php rewind_posts(); ?>
  <?php while (have_posts()) : the_post(); ?>
  <!— And then the basic loop continues... —>
[/cce_php]

当然了,这只会输出和你第一个默认loop输出一样的内容,这看起来即没有必要也没有用处。因此要用rewind_posts()做点有意义的事情,你需要改变一点代码:比如你需要在页面最底部的一个盒子里显示新闻(News)分类中的最后5篇文章。这恰好可以通过前面提到的query_posts来做到:

[cce_php]
<?php rewind_posts(); ?>
<?php query_posts('category_name=news&showposts=5'); ?> 
<?php while (have_posts()) : the_post(); ?>
    <!— And then the basic loop continues.... —>
[/cce_php]

这会从news分类获取最新的5篇文章,正好显示在前面所说的底部的盒子里。

  • 用多重循环显示推荐文章:

多重循环的另一个常用功能是在页面顶部显示特色推荐文章,显示特色文章会打破博客的常规布局,并且正在变得越来越流行,尤其对于杂志型的博客更是如此。

下面是如何使用:首先,你需要一个loop从特色分类里获取一篇文章——比如最新的一篇。然后你需要第二个loop从所有分类里获取最新的文章。为了不让两者冲突,你需要把第一个loop的查询单独存在一个对象里,我们可以调用WP_query函数来存储。WP_query是loop循环的最核心的东西。虽然你没有在基本的loop里看到它,但是其实你一直都在使用have_posts()的时候使用它,比如,对于$wp_query->have_posts();你不需要写全,只要写出have_posts()即可。WP_query很庞大也有点复杂。不过你还是会和WP_query打交道的。

调用query_posts()这个模板函数,用法说明里写到其主要是用于修改主循环,因此你不会在其他loop里使用,取而代之是使用一个新的WP_query(),下面是代码:

[cce_php]
<?php $featured_query = new WP_Query('category_name=featured&showposts=1'); 
while ($featured_query->have_posts()) : $featured_query->the_post(); 
$do_not_duplicate = $post->ID; ?>
    <!— Styling for your featured post —>
<?php endwhile; ?>
    <!— Put whatever you want between the featured post and the normal post listing —>
<?php if (have_posts()) : while (have_posts()) : the_post();
if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?>
    <!— Your normal loop post styling goes here —>
<?php endwhile; else: ?>
    <p>Some error message or similar.</p>
<?php endif; ?>
[/cce_php]

那么这几行代码究竟起了什么作用?让我们从第一个loop那里一行一行攻克,你用$featured_query来创建一个新的WP_Query的循环,这里和query_post()一样的方式传入参数,也就是说你将循环限制在特色分类里,并且只显示一篇:$featured_query = new WP_Query(‘category_name= featured&showposts=1’);.

然后,程序进入while循环,看起来很像基本的loop循环:while ($featured_query- >have_posts()) : $featured_query->the_post(); 还记得基本loop里的have_ posts()就是 $wp_query->have_posts()吧,这里也是一样,不同的是你没用$wp_query对象而是使用了新建的$featured_query。这就是说我们来做和基本loop里一样的事情,只不过我没用默认的对象,而是创建了新的对象,当然不会对$Wp_query有任何影响。第三行就很简单了,我们把特色文章的ID赋值给$do_not_duplicate参数,这么做的原因是我们要确定特色文章不会重复出现在下面的文章列表里。如果你曾经看到过多重循环的代码,你大概认识上面的代码,在代码手册里也能看到。你会继续使用你的主循环,但是不显示存在$d0_not_duplicate里的文章。当然了,这只在你要显示一条特色文章的时候起作用,如果有多个特色文章,则要用一个数组来存放特色文章的ID了。

这之后,程序进入了典型的文章输出环节,通常会有一个带链接的二号字体的标题,接着是内容或者摘要,你可能还想来点炫的,比如用自定义字段来显示特色图片等。不过目前就先输出内容吧。

继续下去,第8行是一个if语句用户检测当前的文章ID是否是$do_not_duplicate所存储的ID,如果是,我们就跳过,如果不是,就正常输出。

[cce_php]
<?php if (have_posts()) : while (have_posts()) : the_post();
  if( $post->ID == $do_not_duplicate ) continue; update_post_caches($posts); ?>
[/cce_php]

这之后就是基本loop里的那套代码,直到输出完毕。

因此,总结而言,你首先在一个单独的loop里输出特色文章,然后进入常规的loop循环,并且检查文章的ID从而避免特色文章被重复输出。

  • 三个优雅,四个更酷

用你已经掌握的知识,在这一节里尝试用用多重循环。在这个例子里,你会在一个loop里循环三个特色文章,之后连续三栏分别输出三个分类的最新文章。这是常见的非博客的CMS网站布局。根据模板文件的部署,这个文件最好叫做home.php,也就是只在首页才使用该模板页面。
考虑以下代码:
[cce_php]
<?php $featured_query = new WP_Query('category_name=featured&showposts=3'); 
while ($featured_query->have_posts()) : $featured_query->the_post(); 
$do_not_duplicate[] = $post->ID ?>
      <!— Styling for your featured posts —>
  <?php endwhile; ?>
<!— Now begins the first column loop —>
<?php query_posts('category_name=apples&showposts=10'); ?>
<?php while (have_posts()) : the_post(); ?>
if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?>
      <!— Category Apples post —>
  <?php endwhile; ?>
<!— Now begins the second column loop —>
<?php rewind_posts(); ?>
<?php query_posts('category_name=oranges&showposts=10'); ?>
<?php while (have_posts()) : the_post(); ?>
if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?>
      <!— Category Oranges post —>
  <?php endwhile; ?>
<!— Now begins the third column loop —>
<?php rewind_posts(); ?>
<?php query_posts('category_name=lemons&showposts=10'); ?>
<?php while (have_posts()) : the_post(); ?>
if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?>
      <!— Category Lemons post —>
  <?php endwhile; ?>
[/cce_php]

我们来看看工作原理,从三个特色文章开始。这和前面的例子极为相似,只不过这里你要显示三个特色文章,并且不希望他们重复出现,因此要用一个数组变量来存储他们的ID。懂PHP的应该很容易看出来中括号$do_not_duplicate object后的[]是表示数组。如果你不熟悉,简单来讲就是用于存储一系列的ID值,本例中存了3个ID,你在后面的loop里都要检查并跳过这三个ID的文章。

接下来,每一个栏目的循环都包含一个分类,这里都是基本的loop循环,使用query_posts()来限制输出的数量,你会根据前面的例子发现这里是如何排序和限制文章输出数量的。

考虑到你不想在下面的栏目里重复输出特色文章,你需要检查$do_not_duplicate数组变量,你会发现if语句对于数组的检查有一点点变化。

最后,在第一个栏目循环结束的时候,你需要使用rewind_posts()来恢复循环的指针从而在下一个栏目里重新使用query_posts(),然后一切都是重复的。

一个备选的方案是创建四个不同的query对象,就像前面例子里的特色文章的输出,从而取代$WP_query,不过说真的,这里没有多大必要。

下面是上面例子的完整代码,包括输出文章的HTML和CSS代码:

[cce_php]
<div id="featured">
<?php $featured_query = new WP_Query('category_name=featured&showposts=3'); 
while ($featured_query->have_posts()) : $featured_query->the_post(); 
$do_not_duplicate[] = $post->ID ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title();
?></a></h2>
<?php the_excerpt(); ?>
        </div>
    <?php endwhile; ?>
</div>
<div class="column left">
<h2>Latest from <span>Apples</span></h2>
<ul>
<!— Now begins the first column loop —>
<?php query_posts('category_name=apples&showposts=10'); ?> <?php while (have_posts()) : the_post();
        if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?>
        <li>
<h3><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
            <?php the_excerpt(); ?>
        </li>
<?php endwhile; ?>
</ul>
</div><div class="column left">
      <h2>Latest from <span>Oranges</span></h2>
      <ul>
      <!— Now begins the second column loop —>
      <?php rewind_posts(); ?>
<?php query_posts('category_name=oranges&showposts=10'); ?> <?php while (have_posts()) : the_post();
          if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?>
          <li>
<h3><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
              <?php the_excerpt(); ?>
          </li>
      <?php endwhile; ?>
</ul>
</div><div class="column right">
      <h2>Latest from <span>Lemons</span></h2>
      <ul>
      <!— Now begins the third column loop —>
      <?php rewind_posts(); ?>
<?php query_posts('category_name=lemons&showposts=10'); ?> <?php while (have_posts()) : the_post();
if (in_array($post->ID, $do_not_duplicate)) continue; update_post_caches($posts); ?> 49 <li>
<h3><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></h3>
              <?php the_excerpt(); ?>
          </li>
      <?php endwhile; ?>
</ul> </div>
[/cce_php]

上面的代码里,四个循环,其中一个用于特色文章,然后三个循环用户展示三个不同分类里的文章,这些代码可以轻松的在WP主题是实现,不过正常工作起见,你需要修改这里的分类名称为你的博客分类名。

[tab:自定义字段]

4、自定义字段(Custom Fields)

自定义字段经常出现在loop循环里,他们是完全由用户自定义的和文章关联的数据库字段。如果你仔细看过WP后台文章编辑框的下方,应该有一个或几个自定义区域,每个里面有个字段名。如图3-4所示:你可以在这里添加一到多个自定义字段。

图3-4 自定义字段区域

自定义字段总是属于文章的,并且包括字段名和值。你可以在任何时候添加新的自定义字段,用过一次的字段都会在下次显示在下拉框里,这很便于你想起以前加了什么字段并且避免拼写错误。

开始使用自定义字段:极为简单,只要写个文章并且加一些字段即可,然后点击增加自定义字段按钮来保存。这样你就已经保存了自己的自定义字段,不过在你调用它之前它都是隐藏的。

在调用它们之前,我们再来重复一遍,每个自定义字段都包含了一个名字和值,这样是希望在不同的文章之间都能共用这些字段名,不同的是改改数值。

处理自定义字段的模板函数是the_meta(),默认情况下,该函数会输出一个列表包含该文章下的所有自定义字段;如果你只是用自定义字段存储一些例如你今天有多高兴、你正在读的书,或者是文章的评分等一些东西那么这么用会非常ok,ul和li会列出你的每一个自定义字段,并且每一个自定义字段的值的外面都有li包含,li的html代码里都有一个class=”post-meta-key”。

比如你有一个叫做”Actor”的自定义字段,值是”Harrison Ford”,另一个自定义字段叫”Director”,值是”Stephen Spielberg”,最后有个自定义字段叫”Movie Title”,值是”Indiana Jones and the Raiders of the Lost Ark”,这里所有的字段和值都属于一个特定的文章,并且如果你将the_meta()放在了loop里的什么位置,那么这个文章就会将这些字段显示出来,输出的代码应该如下:

[cce_html]
<ul class='post-meta'>
    <li><span class='post-meta-key'>Actor</span> Harrison Ford</li>
    <li><span class='post-meta-key'>Director</span> Stephen Spielberg</li>
    <li><span class='post-meta-key'>Movie</span> Indiana Jones and the Raiders of the Lost Ark</
li> </ul>
[/cce_html]

只要你是想展示这些简单的东西,那么这就足够了,况且你还可以用css来定义输出的样式,当然了,你一定想多学一些,继续吧。

发布文章的特色图片Posting Header Images    

自定义字段最流行的一个用法是给一篇文章附上一个特色图片,用于分隔一篇篇文章,首先你需要决定你的自定义字段叫什么,比如就叫post-image,也比较好记,当你在代码里看到的时候也容易理解,这是好习惯。

接下来,你需要一些数据来实验。用WP的图片上传工具来上传一个图片并复制该图片的url地址,类似于这样:

[cce_html]
http://25.timepaw.com/wp-content/uploads/2012/07/wordpress-essentials-508x293.jpg
[/cce_html]

现在来在发布文章的界面里增加post-image字段。如果你之前的文章里没使用过post-image字段的话就直接在自定义字段输入框里输入post-image,否则就直接选择下拉菜单里的post-image,然后将这个图片的url粘贴到post-image对应的值的输入框里,保存即可。现在你已经将这个图片设为这篇文章的自定义字段了,这意味着你可以用它来作为特色图片了。

在你的文章里找个要输出这个图片的位置,可能是和你的文章一起输出在首页,这取决于你图片的形状,可以是标题左侧的一个缩略图,也可以是一个大图。

本例展示了如何将自定义字段的图片放置在h2的标题上面,一些杂志型主题常常这么做,和loop配合起来就是这样的:

[cce_php]
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> 
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<?php $splashimg = get_post_meta($post->ID, 'post-image', $single = true); ?> 
<?php if($splashimg !== '') { ?>
<img src="<?php echo $splashimg; ?>" alt="<?php { echo the_title(); } ?>" class="splashimg" /> 
<?php } else { echo ''; } ?>
<h2><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></
    a></h2>
      <?php the_content(); ?>
  </div>
  <?php endwhile; else: ?>
      <p>Some error message or similar.</p>
  <?php endif; ?>
[/cce_php]

第三行代码就是通过get_post_meta()函数来取得自定义字段的值并存储在变量$splashimg里。这和之前的the_meta()函数很像,这里你传入了三个参数分别是:文章的ID,用于告诉WP在哪里输出这个自定义字段,第二个是你想要取得值的自定义字段的名称,这里就是post-image,这和你之前输入的名称要保持一致。最后一个参数是设置$singe=true,是用来告诉WP以字符串的形式传值,否则就会给出一个自定义字段的数组,当然有些时候这样也很有用,不过本例只想要字符串并存入$splashimg里。

第四行代码我们开始检查$splashimg是否有值,如果有则输出一个图片。

这就是你从get_post_meta()里取得的值了,其实就是一个图片的地址。如果$splashimg里没有任何东西,那么就是说你没有存入任何值在post-image里,也就无法输出图片,当然你可以设置个默认的图片,以防万一出现了这种情况。

这之后还是常规的loop,输出标题,内容等等。

[tab:开始coding]

5、开始coding

loop的使用一开始会很奇妙,基本的loop代码一眼就能认出,而且这基本就是你能开始写WP的全部了。随着深入的了解,你会越来越容易的理解这其中的机制,而当你开始创建你自己的WP主题的时候,你会很快发现这点。

如果你看完本文后依旧对loop的理解表示困难,不要太在意,随着你阅读的例子和代码越来越多,理解就会变得越轻松。而这就是接下来我们将要做的,真真切切的开始创建这些东西。首先是主题,随后的三章都是讲解主题的制作,这意味着你将会看到非常多的loop,而同时你也会更深入的钻研模板函数和其他一些WP用于控制输出的工具。

[tab:END]

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注