站长百科 | 数字化技能提升教程 数字化时代生存宝典
首页
数字化百科
电子书
建站程序
开发
服务器
办公软件
开发教程
服务器教程
软件使用教程
运营教程
热门电子书
WordPress教程
宝塔面板教程
CSS教程
Shopify教程
导航
程序频道
推广频道
网赚频道
人物频道
网站程序
网页制作
云计算
服务器
CMS
论坛
网店
虚拟主机
cPanel
网址导航
WIKI使用导航
WIKI首页
最新资讯
网站程序
站长人物
页面分类
使用帮助
编辑测试
创建条目
网站地图
站长百科导航
站长百科
主机侦探
IDCtalk云说
跨境电商导航
WordPress啦
站长专题
网站推广
网站程序
网站赚钱
虚拟主机
cPanel
网址导航专题
云计算
微博营销
虚拟主机管理系统
开放平台
WIKI程序与应用
美国十大主机
编辑“
WordPress自定义查询语句
”
人物百科
|
营销百科
|
网赚百科
|
站长工具
|
网站程序
|
域名主机
|
互联网公司
|
分类索引
跳转至:
导航
、
搜索
警告:
您没有登录。如果您做出任意编辑,您的IP地址将会公开可见。如果您
登录
或
创建
一个账户,您的编辑将归属于您的用户名,且将享受其他好处。
反垃圾检查。
不要
加入这个!
<span style="border:1px solid #000; text-align:center; float:right; padding:6px;"><strong>导航:</strong> [[WordPress插件及插件开发资源|上一页]] | {{Template:WordPress导航}}</span> <div style="clear:both;"></div> 插件通过hook[http://www.wordpress.la/codex-%E6%8F%92%E4%BB%B6API.html 钩子](动作钩子和过滤器钩子)来扩展WordPress的功能。钩子能够改变WordPress的运行方式。有时插件需要执行自定义查询,这比在WordPress中加上动作钩子或是过滤器钩子要复杂得多。下面这篇文章介绍了自定义查询的相关信息,以及插件开发者怎样执行自定义查询。 注意: *文章假设读者对[http://www.wordpress.la/codex-%E6%8F%92%E4%BB%B6%E5%BC%80%E5%8F%91.html 编写插件]、[http://www.wordpress.la/codex-%E7%94%A8%E6%8F%92%E4%BB%B6%E5%88%9B%E5%BB%BA%E6%95%B0%E6%8D%AE%E5%BA%93%E8%A1%A8.html 用插件创建数据库表]、[http://www.wordpress.la/codex-%E6%8F%92%E4%BB%B6API.html 插件API]的动作钩子和过滤器钩子以及MySQL数据库查询语言有基本了解。 *文章只适用于博客访问者能够看到的页面,不适用于WordPress后台界面(但某些操作可能会影响日志列表的后台页面)。 *文中所提到的文件名都是相对WordPress根目录而言。 ==背景知识介绍== ===定义=== 在本文中,查询指的是WordPress用来在主循环中寻找即将显示在页面上的日志列表的数据库查询(本文中的“[[数据库]]查询”即一般类型的数据库查询)。默认情况下,WordPress查询会查找属于当前页面的日志,无论是某一篇日志,或是静态页面、类别存档、日期存档、搜索结果、feed以及[[博客]]所有日志列表;查询日志限制在一定数量内(可以在WordPress后台的“设置”中设定),所有日志按时间逆序排列(最近发表的日志排在列表的最上方)。插件可以用自定义查询来改变日志排列顺序。例如: *以不同顺序显示日志,如按字母顺序排列“glossary”分类中的日志 *更改将要显示在页面上的日志的默认数量;例如,glossary插件可能会显示更多“glossary”类别中的日志(相对于其它类别而言) *从特定页面中删除某些文章;例如,属于“glossary”分类的日志将只出现在“glossary”类别页面,而不出现在主页和存档页面中。 *扩大WordPress默认的关键字查找范围(WordPress默认[[关键字]]查找范围仅限于日志标题和正文);例如某个地域标签插件的城市、州、乡村等字段。 *允许用example.com/blog?geostate=oregon 或example.com/blog/geostate/oregon等类似自定义URL来表示带有“Oregon”(俄勒冈州)标签的日志存档。 ===WordPress默认运行方式=== 修改WordPress中的默认查询前,我们需要了解WordPress的默认运行方式。[http://www.wordpress.la/codex-%E6%9F%A5%E8%AF%A2%E8%AF%AD%E5%8F%A5%E6%A6%82%E8%A7%88.html 查询语句概览]中简要描述了WordPress生成博客页面的过程以及插件对该过程的修改。 ==执行自定义查询== 现在我们可以开始执行自定义查询了。接下来我们会用几个例子来说明怎样修改查询,开始时的例子比较简单,之后会慢慢过度到相对复杂的例子。 ===日志排列顺序与总数限制=== 在第一个例子中,我们假设目前有一个glossary插件,网站/博客管理员可通过该插件将日志归入“glossary”类别(由插件保存在全局变量$gloss_category中)。我们希望达到的效果是:访问者访问glossary类别存档时看到的会是按字母顺序排列而不是按时间顺序排列的日志,是glossary类别下的所有日志而不是由网站管理规定显示数量的日志。 此时我们需要用以下两种方法来修改查询: #为查询的ORDER BY语句加上一个过滤器钩子,将glossary类别下的日志列表改为字母顺序排列。过滤器钩子名为'posts_orderby',过滤SQL语句中ORDER BY后的内容。 #为查询的LIMIT语句加上一个过滤器钩子,解除日志的数量限制。过滤器钩子名为'post_limits',过滤SQL语句中包括包括LIMIT关键字在内关于日志数量限制的内容。 在上面两种方法中,过滤器函数都只会在我们浏览glossary类别时执行查询修改(用is_category函数进行逻辑操作)。因此,接下来我们需要编写如下代码: add_filter('posts_orderby', 'gloss_alphabetical' ); add_filter('post_limits', 'gloss_limits' ); function gloss_alphabetical( $orderby ) { global $gloss_category; if( is_category( $gloss_category )) { // alphabetical order by post title return "post_title ASC"; } // not in glossary category, return default order by return $orderby; } function gloss_limits( $limits ) { global $gloss_category; if( is_category( $gloss_category )) { // remove limits return ""; } // not in glossary category, return default limits return $limits; } ===删除某类别日志=== 这里我们继续以glossary插件为例,这次我们希望能够禁止glossary类别下的日志出现在指定的页面上(主页与非类别存档页)以及feed中。要达到预期效果,首先要添加一个'pre_get_posts'动作钩子,该动作钩子能够探测当前访问者所请求的页面类型,之后根据页面类型删除glossary类别下的日志。根据查询说明(存储在$wp_query->query_vars中)中的规定,我们还可以在某个类别索引号前加上一个符号“-”以删除该类别。因此,修改后的代码如下: add_action('pre_get_posts', 'gloss_remove_glossary_cat' ); function gloss_remove_glossary_cat( $notused ) { global $wp_query; global $gloss_category; // Figure out if we need to exclude glossary - exclude from // archives (except category archives), feeds, and home page if( is_home() || is_feed() || ( is_archive() && !is_category() )) { $wp_query->query_vars['cat'] = '-' . $gloss_category; } } ==插件表中的关键字查找== 这个例子中我们假设目前有一个地域标签插件,插件为每一篇日志贴上一个或多个城市、州、乡村的标签。该插件将所有标签存在自备的[[数据库]]表中;我们假设数据库表名在全局变量$geotag_table中且表名具有geotag_post_id, geotag_city, geotag_state, geotag_country字段。我们希望在这个例子中,每当有人进行关键字查找时(WordPress默认关键字查找范围仅限于日志标题和正文),都能够查找到内容中带有插件表字段关键字的日志。 因此,我们需要通过多种方式来修改之前用于查找日志的SQL查询(在查找页面上例外): *用'posts_join'过滤器函数连接插件的数据库表与日志表,该函数运行在[[SQL]] JOIN语句上。 *用'posts_where'过滤器函数扩展查询的WHERE语句,使之能够查看插件表的字段。之后根据WordPress查找日志标题字段的原理,我们也可以对自定义表的字段进行相同操作(如不是复制WordPress复杂的逻辑语句)。WordPress添加的语句可能是这样的:(post_title LIKE 'xyz')。 *用'posts_groupby'过滤器函数为查询加上一个GROUP BY语句,该过滤器函数过滤SQL语句中GROUP BY之后的内容。这样如果有日志同时被标上Portland、Oregon和Salem、Oregon标签,访问者查找“Oregon”时,我们只会返回一次这篇日志。 结果代码显示如下: add_filter('posts_join', 'geotag_search_join' ); add_filter('posts_where', 'geotag_search_where' ); add_filter('posts_groupby', 'geotag_search_groupby' ); function geotag_search_join( $join ) { global $geotag_table, $wpdb; if( is_search() ) { $join .= " LEFT JOIN $geotag_table ON " . $wpdb->posts . ".ID = " . $geotag_table . ".geotag_post_id "; } return $join; } function geotag_search_where( $where ) { if( is_search() ) { $where = preg_replace( "/\(\s*post_title\s+LIKE\s*(\'[^\']+\')\s*\)/", "(post_title LIKE \\1) OR (geotag_city LIKE \\1) OR (geotag_state LIKE \\1) OR (geotag_country LIKE \\1)", $where ); } return $where; } function geotag_search_groupby( $groupby ) { global $wpdb; if( !is_search() ) { return $groupby; } // we need to group on post ID $mygroupby = "{$wpdb->posts}.ID"; if( preg_match( "/$mygroupby/", $groupby )) { // grouping we need is already there return $groupby; } if( !strlen(trim($groupby))) { // groupby was empty, use ours return $mygroupby; } // wasn't empty, append ours return $groupby . ", " . $mygroupby; } ==自定义存档== 这部分我们仍然以地域标签插件为例。首先假设我们需要用插件来激活类似于www.example.com/blog?geostate=oregon形式的自定义永久链接,让WordPress查找与“oregon”州名相符合的日志并显示在页面上。 要实现以上效果,插件必须进行以下操作: 将“geostate”添加到WordPress能够识别的查询变量列表(query_vars过滤器函数),以确保WordPress解析URL时,州名被保存在查询变量中。下面是操作方法: add_filter('query_vars', 'geotag_queryvars' ); function geotag_queryvars( $qvars ) { $qvars[] = 'geostate'; return $qvars; } 查找到“geostate”查询变量时执行正确的查询;过程与之前提到的自定义查询相似。唯一的区别在于,这里用测试来判断“geostate”查询变量是否被探测到,而不是判断is_search或者posts_where以及其它各种数据库查询过滤器函数。用下面代码来代替上个例子中的if( is_search() ) 语句: global $wp_query; if( isset( $wp_query->query_vars['geostate'] )) { // modify the where/join/groupby similar to above examples } 插件可能还需要生成这些永久链接。例如,插件可能有一个叫做geotags_list_states的函数,该函数能够查找出地域标签表中的各个州名,并为这些州名生成链接: function geotags_list_states( $sep = ", " ) { global $geotag_table, $wpdb; // find list of states in DB $qry = "SELECT geotag_state FROM $geotag_table " . " GROUP BY geotag_state ORDER BY geotag_state"; $states = $wpdb->get_results( $qry ); // make list of links $before = '<a href="' . get_bloginfo('home') . '?geostate='; $mid = '">'; $after = "</a> "; $cur_sep = ""; foreach( $states as $row ) { $state = $row->state; echo $cur_sep . $before . rawurlencode($state) . $mid . $state . $after; // after the first time, we need separator $cur_sep = $sep; } } ===自定义存档的永久链接=== 如果网站/博客管理员没有已激活的非默认[[永久链接]],我们可以延续上一个例子(自定义存档)的内容,激活 example.com/[[blog]]/geostate/oregon,这样可以列出所有标有“Oregon”[[标签]]的日志。首先我们需要在WordPress的重写规则中加入一些内容,告诉WordPress如何解析永久链接类型的URL。具体来说,我们要添加一个能够告诉WordPress怎样解析/geostate/oregon 与?geostate=oregon的重写规则。(重写过程参见查询语句概览。) 实际定义一个新的重写规则可以分两步: #用init过滤器函数“清理”缓存的重写规则,迫使WordPress重新计算重写规则 #计算重写规则时,用generate_rewrite_rules动作还属来添加新规则: add_action('init', 'geotags_flush_rewrite_rules'); function geotags_flush_rewrite_rules() { global $wp_rewrite; $wp_rewrite->flush_rules(); } 生成新规则相对复杂。首先,重写规则是一个关联数组,数组的关键字是能够匹配永久链接URL的正则表达式,而数组值则是相应非永久链接类型的URL。因此,要定义一个能与/geostate/oregon类似URL(其中oregon可以换成其它任意州名)相匹配的重写规则,并且告诉WordPress与?geostate=oregon相对应,我们需要进行以下操作: add_action('generate_rewrite_rules', 'geotags_add_rewrite_rules'); function geotags_add_rewrite_rules( $wp_rewrite ) { $new_rules = array( 'geostate/(.+)' => 'index.php?geostate=' . $wp_rewrite->preg_index(1) ); $wp_rewrite->rules = $new_rules + $wp_rewrite->rules; } ==相关条目== *[[Drupal]] *[[OBLOG]] *[[X-Space]] *[[SaBlog-X]] *[[Bo-Blog]] [[category:WordPress中文文档|Z]] [[category:WordPress网站开发|Z]] [[category:WordPress开发文档|Z]]
摘要:
请注意,您对站长百科的所有贡献都可能被其他贡献者编辑,修改或删除。如果您不希望您的文字被任意修改和再散布,请不要提交。
您同时也要向我们保证您所提交的内容是您自己所作,或得自一个不受版权保护或相似自由的来源(参阅
Wordpress-mediawiki:版权
的细节)。
未经许可,请勿提交受版权保护的作品!
取消
编辑帮助
(在新窗口中打开)
本页使用的模板:
模板:WordPress导航
(
查看源代码
)(受保护)