WordPress:Displaying Posts Using a Custom Select Query
描述[ ]
在你的WordPress发展历程的某个时刻,或许你需要通过非WordPress的 query_posts 架构提供的选择标准来显示一篇或更多的文章。例如,你有时或许必须加入 WordPress表格以确定要显示的文章或使用自己表格中的储存数据来确定要显示正在写的文章。
以下概述的实例展示了这样一个过程:选择有 定制区域存入值的所有文章并把它们在建立在页面模板基础上的页面显示出来。这些编码最初用来执行文章标签插件,它允许以比WordPress分类稍无序的构架来组织文章。你的使用或许有所不同,但以下的例子仍会给你提供些有用的一般过程说明。
文章假设[ ]
本文通常假设你拥有PHP, MySQL知识和WordPress 使用能力。
但此例的特定假设是:
- 你至少拥有一篇定制区域数据文章。自定义区域有“标签”键和“电子邮件”键值。
- 你已创建一个页面并有一个页面模板链接。在此例中,假定模板名称为'Qbased',它是从wp-content/themes/index.php模板复制的。如果你对此过程不熟悉,按照创建你自己的页面模板中的说明进行操作。
- 由于这是稍先进的开发主题,推荐掌握循环的WordPress核心概念。
网页模板编码[ ]
查询[ ]
首先,需要检索[[WordPress:Glossary#Recordset|数据集],里面包含你要显示的文章。要做到这一点,需要使用WordPress$wpdb 数据库 类创建一个(结果集)。注意MySQL SELECT指令阐明了一个“简单的” JOIN。$pageposts在此会包含数组对象。每个对象代表一篇有自定义字段key-value(键-键值)配对且键名为tag,值为email的“已发布”文章。
<?php $querystr = " SELECT wposts.* FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = 'tag' AND wpostmeta.meta_value = 'email' AND wposts.post_status = 'publish' AND wposts.post_type = 'post' ORDER BY wposts.post_date DESC "; $pageposts = $wpdb->get_results($querystr, OBJECT); ?>
已修改的Loop(循环)[ ]
现在,若要通过以前的SELECT 标准来显示$pageposts中的文章,你需要用Qbased网页模板中你自己的循环编码来替代WordPress:The Loop。这需要创建一个已修改的循环(loop),使它能够循环$pageposts中的文章并显示它们。注意:下面loop(循环)中的结构/标记取自WordPress“默认”主题. 。
<?php if ($pageposts): ?> <?php foreach ($pageposts as $post): ?> <?php setup_postdata($post); ?> <div class="post" id="post-<?php the_ID(); ?>"> <h2><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 class="entry"> <?php the_content('Read the rest of this entry »'); ?> </div> <p class="postmetadata">Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?> <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p> </div> <?php endforeach; ?> <?php else : ?> <h2 class="center">Not Found</h2> <p class="center">Sorry, but you are looking for something that isn't here.</p> <?php include (TEMPLATEPATH . "/searchform.php"); ?> <?php endif; ?>
就是它!
一行一行地审查编码的重要部分,你必须:
- 测试以确保$pageposts中的查询可以查到符合SELECT标准的文章:
<?php if ($pageposts): ?>
- foreach loop审查已返回$pageposts的文章,并显示文章:
<?php foreach($pageposts as $post): ?>
- 调用WordPress文章格式化函数,setup_postdata(),自动填入所需变量:
<?php setup_postdata($post); ?>
Loop (循环)内部[ ]
由于例子中调用了setup_postdata($post);,你可以使用可包括在正常Wordpress循环(loop)中的相同模板标签,如the_content() 和 the_permalink()。这意味着你能够较方便地用网页模板创建自己的文章显示结果,并自动利用你的Wordpress博客已激活的各种插件提供额外的格式和功能。
已完成的网页模板[ ]
这是Wordpress“默认”主题运行的新模板的完整事例。
<?php /* Template Name: Qbased */ ?> <?php get_header(); ?> <div id="content" class="narrowcolumn"> <?php $querystr = " SELECT wposts.* FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta WHERE wposts.ID = wpostmeta.post_id AND wpostmeta.meta_key = 'tag' AND wpostmeta.meta_value = 'email' AND wposts.post_status = 'publish' AND wposts.post_type = 'post' AND wposts.post_date < NOW() ORDER BY wposts.post_date DESC "; $pageposts = $wpdb->get_results($querystr, OBJECT); ?> <?php if ($pageposts): ?> <?php foreach ($pageposts as $post): ?> <?php setup_postdata($post); ?> <div class="post" id="post-<?php the_ID(); ?>"> <h2><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 class="entry"> <?php the_content('Read the rest of this entry »'); ?> </div> <p class="postmetadata">Posted in <?php the_category(', ') ?> | <?php edit_post_link('Edit', '', ' | '); ?> <?php comments_popup_link('No Comments »', '1 Comment »', '% Comments »'); ?></p> </div> <?php endforeach; ?> <?php else : ?> <h2 class="center">Not Found</h2> <p class="center">Sorry, but you are looking for something that isn't here.</p> <?php include (TEMPLATEPATH . "/searchform.php"); ?> <?php endif; ?> </div> <?php get_sidebar(); ?> <?php get_footer(); ?>
这里值得注意的是,上述例子“只有”当$wpdb->get_results()
是以"output_type"为参数,面向对象通过时才运行。当ARRAY_A 或ARRAY_N在$wpdb->get_results()通过时,setup_postdata()似乎不运行。
定制区域和类别基础上的查询[ ]
此事例设置了上个事例中使用的$querystr变量以获得类别1,2,和3中的有meta_key 'paragraf'的所有文章,并按meta_values升序排列。此例来源于Otto42在Forum Topic 121011. 中的回复。
$querystr = " SELECT $wpdb->posts.* FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id) LEFT JOIN $wpdb->post2cat ON ($wpdb->posts.ID = $wpdb->post2cat.post_id) WHERE $wpdb->postmeta.meta_key = 'paragraf' AND $wpdb->posts.post_status = 'publish' AND $wpdb->posts.post_type = 'post' AND $wpdb->post2cat.category_id IN (1,2,3) ORDER BY $wpdb->postmeta.meta_value ASC ";
使用 wordpress2.3,你需要把以上显示的sql查询更新为:
此例来源于kernow在Forum Topic 121011 中的回复
SELECT * FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id) LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id) LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id) WHERE $wpdb->term_taxonomy.term_id = 1,2,3 AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->posts.post_status = 'publish' AND $wpdb->postmeta.meta_key = 'paragraf' ORDER BY $wpdb->postmeta.meta_value ASC
致谢[ ]
非常感谢Kafkaesquii指出填写适当全局变量等的更简便方法:使用setup_postdata()。