是的,这是可能的。
WordPress前端工作流可以概括如下:
通过对照所有默认值检查当前url,访问urlcustom rewrite rules url已“转换”为的一组参数WP_Query
. 这是由parse_request
的实例的方法WP
类存储在全局$wp
变量WP_Query
(保存在$wp_query
全局变量)用于查询数据库并获取与在点#2检索到的参数相关的帖子。这被称为“主查询”
根据查询参数,根据template hierarchy 它被加载并用于显示结果,因此,即使您注册了一组自定义重写规则,它们也将用于查询帖子。然而,如果你看看source of parse_request
method, 在第一行中,您可以看到:
if ( ! apply_filters( \'do_parse_request\', true, $this, $extra_query_vars ) )
return;
因此,通过将回调附加到“do\\u parse\\u request”过滤器,您可以停止WordPress解析过程并执行任何需要的操作。有不同的方法来完成这项任务,为了简单起见,这里我将给你一个粗略的例子。
如前所述,我们需要使自定义url与something,可能是一个回调,用于检索一些数据和显示数据的视图。
为了使代码可重用,我们可以使用一个通过过滤器接受自定义url设置的类,并使用该自定义url设置来显示我们需要的任何内容,使用回调来获取一些数据,并使用视图来显示它们。
class MyCustomUrlParser {
private $matched = array();
/**
* Run a filter to obtain some custom url settings, compare them to the current url
* and if a match is found the custom callback is fired, the custom view is loaded
* and request is stopped.
* Must run on \'do_parse_request\' filter hook.
*/
public function parse( $result ) {
if ( current_filter() !== \'do_parse_request\' ) {
return $result;
}
$custom_urls = (array) apply_filters( \'my_custom_urls\', array() );
if ( $this->match( $custom_urls ) && $this->run() ) {
exit(); // stop WordPress workflow
}
return $result;
}
private function match( Array $urls = array() ) {
if ( empty( $urls ) ) {
return FALSE;
}
$current = $this->getCurrentUrl();
$this->matched = array_key_exists( $current, $urls ) ? $urls[$current] : FALSE;
return ! empty( $this->matched );
}
private function run() {
if (
is_array( $this->matched )
&& isset( $this->matched[\'callback\'] )
&& is_callable( $this->matched[\'callback\'] )
&& isset( $this->matched[\'view\'] )
&& is_readable( $this->matched[\'view\'] )
) {
$GLOBALS[\'wp\']->send_headers();
$data = call_user_func( $this->matched[\'callback\'] );
require_once $this->matched[\'view\'];
return TRUE;
}
}
private function getCurrentUrl() {
$home_path = rtrim( parse_url( home_url(), PHP_URL_PATH ), \'/\' );
$path = rtrim( substr( add_query_arg( array() ), strlen( $home_path ) ), \'/\' );
return ( $path === \'\' ) ? \'/\' : $path;
}
}
这是一个粗糙的类,允许用户通过过滤器(“my\\u custom\\u url”)设置自定义url设置。自定义url设置必须是一个数组,其中键是相对url,每个值都是一个包含两个键控值的数组:一个键为“callback”,另一个键为“view”。回调是可调用的(任何is_callable
返回true),视图是一个文件,用于呈现中的视图文件中可调用和可访问的$data
变量
下面是一个如何使用该类的示例。
// first of all let\'s set custom url settings
add_filter( \'my_custom_urls\', \'set_my_urls\' );
function set_my_urls( $urls = array() ) {
$my_urls = array(
\'/customcontent/alink\' => array(
\'callback\' => \'my_first_content_callback\',
\'view\' => get_template_directory() . \'/views/my_first_view.php\'
),
\'/customcontent/anotherlink\' => array(
\'callback\' => \'my_second_content_callback\',
\'view\' => get_template_directory() . \'/views/my_second_view.php\'
)
);
return array_merge( (array) $urls, $my_urls );
}
// require the file that contain the MyCustomUrlParser class
require \'/path/to/MyCustomUrlParser\';
// attach MyCustomUrlParser::parse() method to \'do_parse_request\' filter hook
add_filter( \'do_parse_request\', array( new MyCustomUrlParser, \'parse\' ) );
当然,我们需要写my_first_content_callback
和my_second_content_callback
还有my_first_view.php
和my_second_view.php
.例如,回调如下:
function my_first_content_callback() {
$content = get_transient( \'my_first_content\' );
if ( empty( $content ) ) {
$api = a_method_to_get_an_external_api_object();
$json = $api->fetch_some_json_data();
$content = json_decode( $json );
// cache content for 1 hour
set_transient( \'my_first_content\', $content, HOUR_IN_SECONDS );
}
return $content;
}
请注意,回调返回的内容都存储在$data
可在视图中访问变量。事实上,视图文件的显示方式如下:<?php get_header(); ?>
<h1>My Content from API</h1>
<div>
<pre><?php print_r( $data ); ?></pre>
</div>
<?php get_footer() ?>
这是可行的,并且可以很好地重用,您可以使用\'my_custom_urls\'
滤器然而,也有缺点:所有与当前url的匹配都是通过精确匹配完成的,但是使用正则表达式匹配系统,这对于大型项目来说会更好,因为您可以使用url将一些变量传递给回调。
E、 g.如果您有如下url设置:
\'/customcontent/alink/page/{page}\' => array(
\'callback\' => \'my_first_content_callback\',
\'view\' => get_template_directory() . \'/views/my_first_view.php\'
)
使用regex系统可以使{page}
部件变量和匹配的值可以传递给回调以检索不同的数据。这就是通常所说的routing system, 还有一些有用的PHP库,如FastRoute, Pux 和Symfony Routing Component 这可以帮助您使用我在这里介绍的工作流,并在WordPress中构建自己的基于regex的路由系统。
如果您有PHP 5.4+(这是非常推荐的),那么a plugin I wrote called Cortex 它实现了Symfony路由组件,使其在WordPress中既可用于标准WordPress查询(显示帖子),也可用于您需要的自定义内容。