有时候我们需要用 Bricks 的查询循环功能做自定义文章循环,但又想用自己的 WP_Query 代码来获得更多灵活性。
原因可能是:内置设置做不到某些事(比如某些 WP_Query 参数需要更动态的处理),也可能你手上正好有一段复杂查询的现成代码——直接粘贴代码比在 UI 里手动重建快得多。
用 Bricks 的查询过滤器实现
Bricks 自带几个过滤器(filters),可以改变各种功能的行为,正是它们让这件事成为可能。
开发者文档是逐个了解这些过滤器的好资料。这里我们组合使用其中几个:注册一个新的查询类型,并给查询循环功能注入自定义的 WP_Query 参数(本篇末尾附有具体用到的过滤器文档链接)。
添加代码片段
这段代码要添加在构建器之外——放在子主题的 functions.php 里,或用 WPCodeBox 之类的代码片段管理插件。
下面的代码负责三件事:
- 在查询循环控件的「类型」(type)下拉里新增一个选项
- 选中该选项时执行我们的新查询(也就是自定义 WP_Query 代码)
- 设置全局文章数据(global post data)
/* Add new query type control to query options */
add_filter( 'bricks/setup/control_options', 'bl_setup_query_controls');
function bl_setup_query_controls( $control_options ) {
/* Adding a new option in the dropdown */
$control_options['queryTypes']['my_new_query_type'] = esc_html__( 'My new WP Query' );
return $control_options;
};
/* Run new query if option selected */
add_filter( 'bricks/query/run', 'bl_maybe_run_new_query', 10, 2);
function bl_maybe_run_new_query( $results, $query_obj ) {
if ( $query_obj->object_type !== 'my_new_query_type' ) {
return $results;
}
/* If option is selected, run our new query */
if ( $query_obj->object_type === 'my_new_query_type' ) {
$results = run_new_query();
}
return $results;
};
/* Setup post data for posts */
add_filter( 'bricks/query/loop_object', 'bl_setup_post_data', 10, 3);
function bl_setup_post_data( $loop_object, $loop_key, $query_obj ) {
if ( $query_obj->object_type !== 'my_new_query_type' ) {
return $loop_object;
}
global $post;
$post = get_post( $loop_object );
setup_postdata( $post );
return $loop_object;
};
/* Return results from our custom WP Query arguments */
function run_new_query() {
/* Add all of your WP_Query arguments here */
$args = [
'post_type' => 'post',
'orderby' => 'rand',
'posts_per_page' => '1',
];
$posts_query = new WP_Query( $args );
return $posts_query->posts;
};
改成你自己的查询
- 把前三段函数里出现的查询类型标识
my_new_query_type改成更有意义的名字; - 修改第一段函数里的显示名
My new WP Query(这就是它在设置面板里显示的名字); - 在最后一段函数里,往
$args数组里填你自己的 WP_Query 参数。
完成
保存后回到 Bricks,查询循环的「类型」下拉里就会出现这个新选项,选中它即可创建你自己的文章循环。
补充:可以看下 Ivan Nugraha 的这条 YouTube 视频教程,里面有基于 ACF relationship 字段展示文章的完整实例:https://www.youtube.com/watch?v=JLCdFATDdvg
添加多个自定义查询
想把上面的代码扩展成支持多个新查询类型?下面是个现成例子,用 my_first_custom_query 和 my_second_custom_query 命名,方便阅读和改成你自己的:
/* Add new query type controls to query options */
add_filter( 'bricks/setup/control_options', 'bl_setup_query_controls');
function bl_setup_query_controls( $control_options ) {
/* Adding new options in the dropdown */
$control_options['queryTypes']['my_first_custom_query'] = esc_html__( 'My first WP Query' );
$control_options['queryTypes']['my_second_custom_query'] = esc_html__( 'My second WP Query' );
return $control_options;
};
/* Run new query if option selected */
add_filter( 'bricks/query/run', 'bl_maybe_run_new_queries', 10, 2);
function bl_maybe_run_new_queries( $results, $query_obj ) {
if ( $query_obj->object_type === 'my_first_custom_query' ) {
$results = run_first_query();
}
if ( $query_obj->object_type === 'my_second_custom_query' ) {
$results = run_second_query();
}
return $results;
};
/* Setup post data for posts */
add_filter( 'bricks/query/loop_object', 'bl_setup_post_data', 10, 3);
function bl_setup_post_data( $loop_object, $loop_key, $query_obj ) {
/* setup post data if using any of our custom queries */
if ( $query_obj->object_type === 'my_first_custom_query' || $query_obj->object_type === 'my_second_custom_query' ) {
global $post;
$post = get_post( $loop_object );
setup_postdata( $post );
}
return $loop_object;
};
/* first WP Query arguments */
function run_first_query() {
/* Add all of your WP_Query arguments here */
$args = [
'post_type' => 'post',
'orderby' => 'rand',
'posts_per_page' => '2',
];
$posts_query = new WP_Query( $args );
return $posts_query->posts;
};
/* second WP Query arguments */
function run_second_query() {
/* Add all of your WP_Query arguments here */
$args = [
'post_type' => 'post',
'orderby' => 'rand',
'posts_per_page' => '1',
];
$posts_query = new WP_Query( $args );
return $posts_query->posts;
};
相关教程
更多创建自定义查询循环、或改造现有查询类型以覆盖 Bricks 常见用例的实用代码示例,见 Query Loop Tutorials。
过滤器文档参考: