对数据库的更改
WordPress 5.1 中站点元数据的引入为多站点开辟了许多新的可能性。
在多站点元数据中保存数据库版本和更新日期
在[46193]中,数据库版本和更新日期都保存在blogmeta
表中。
如果您的多站点设置要求从全局上下文访问数据库版本,而不是使用switch_to_blog
调用在每个站点周围循环get_option( 'db_version' )
,那您可以尝试以下函数。
function get_site_versions() {
global $wpdb;
$query = $wpdb->prepare( "SELECT blog_id, meta_value FROM $wpdb->blogmeta WHERE meta_key = 'db_version' ORDER BY blog_id DESC");
return $wpdb->get_results( $query );
}
删除blog_versions表
目前,多站点中有一个名为blog_versions
的数据表。这个表将数据库版本存储为数字和更新日期。它是在#11644中引入的,但一直都没有在WP核心中使用过。
由于现在将数据库版本和更新日期都保存在blogmeta
表中,所以blog_versions
表就多余了。
对WP_MS_Sites_List_Table的更改
WordPress 5.3在WP_MS_Sites_List_Table类中添加了一些增强功能,使插件作者可以利用站点元数据在“ 管理网络站点”界面上为多站点管理员提供更丰富的体验。
使用和/或自定义“所有文章”界面的人员将非常熟悉这些增强功能。
站点状态视图
现在,“网络站点”界面将显示一个链接列表,其中包含按状态(例如“公共”,“垃圾”等)的站点计数,类似于“所有文章”屏幕上的文章状态链接。
状态链接也可以使用views_sites-network
过滤器进行过滤。
例如,假设有一个多站点,其中主站点充当本地餐馆的目录,而每个站点都是针对单个餐馆的,而餐馆所有者可以购买“订阅”,从而使他们可以显示有关其餐馆清单的更多信息:基本订阅将允许他们添加餐厅的照片,高级订阅将允许他们添加菜单。
然后可以将订阅级别存储在blogmeta
表中,并可以为不同的订阅级别添加“状态”链接,如下所示:
add_filter( 'views_sites-network', 'myplugin_add_site_status_views' );
function myplugin_add_site_status_views( $view_links ) {
$statuses = array(
'free' => _n_noop(
'Free <span class="count">(%s)</span>',
'Free <span class="count">(%s)</span>',
'myplugin'
),
'basic' => _n_noop(
'Basic <span class="count">(%s)</span>',
'Basic <span class="count">(%s)</span>',
'myplugin'
),
'advanced' => _n_noop(
'Advanced <span class="count">(%s)</span>',
'Advanced <span class="count">(%s)</span>',
'myplugin'
),
);
// get the count of sites with each of our custom statuses.
$args = array(
'meta_query' => array(
array(
'key' => 'myplugin-status',
'compare' => '=',
),
),
'count' => true,
);
$counts = array();
foreach ( array_keys( $statuses ) as $status ) {
$args['meta_query'][0]['value'] = $status;
$counts[ $status ] = get_sites( $args );
}
$requested_status = isset( $_GET['status'] ) ? wp_unslash( trim( $_GET['status'] ) ) : '';
foreach ( $statuses as $status => $label_count ) {
$current_link_attributes = $requested_status === $status ?
' class="current" aria-current="page"' :
'';
if ( (int) $counts[ $status ] > 0 ) {
$label = sprintf( translate_nooped_plural( $label_count, $counts[ $status ] ), number_format_i18n( $counts[ $status ] ) );
$view_links[ $status ] = sprintf(
'<a href="%1$s"%2$s>%3$s</a>',
esc_url( add_query_arg( 'status', $status, 'sites.php' ) ),
$current_link_attributes,
$label
);
}
}
return $view_links;
}
当用户单击一个自定义状态链接时,可以使用现有的ms_sites_list_table_query_args将列表中的行限制为具有该特定自定义状态的网站,如下所示:
add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_custom_status' );
function myplugin_sites_with_custom_status( $args ) {
$status = ! empty( $_GET['status' ] ) ? wp_unslash( $_GET['status' ] ) : '';
if ( empty( $status ) || ! in_array( $_GET['status'], array( 'free', 'basic', 'advanced' ) ) ) {
return $args;
}
$meta_query = array(
'key' => 'myplugin-status',
'value' => $status,
);
if ( isset( $args['meta_query'] ) ) {
// add our meta query to the existing one(s).
$args['meta_query'] = array(
'relation' => 'AND',
$meta_query,
array( $args['meta_query'] ),
);
}
else {
// add our meta query.
$args['meta_query'] = array(
$meta_query,
);
}
return $args;
}
额外的表格导航
显示在“ 所有文章”界面上的文章可以按日期和分类进行过滤。插件还可以通过 restrict_manage_posts过滤器 添加自定义过滤条件。
继续上面的餐厅指南示例,假设每个餐厅提供的食物也存储在blogmeta
表中。然后,我们可以允许网络管理员通过添加各种美食的下拉列表,根据食物的类型来过滤站点:
这样的下拉列表现在可以通过新的restrict_manage_sites
动作钩子(在Trac#45954中引入)添加到“网络站点”界面上,如下所示:
add_action( 'restrict_manage_sites', 'myplugin_add_cuisines_dropdown' );
function myplugin_add_cuisines_dropdown( $which ) {
if ( 'top' !== $which ) {
return;
}
echo '<select name="cuisine">';
printf( '<option value="">%s</option>', __( 'All cuisines', 'myplugin' ) );
$cuisines = array(
'French' => __( 'French', 'myplugin' ),
'Indian' => __( 'Indian', 'myplugin' ),
'Mexican' => __( 'Mexican', 'myplugin' ),
);
$requested_cuisine = isset( $_GET['cuisine'] ) ? wp_unslash( $_GET['cuisine'] ) : '';
foreach ( $cuisines as $cuisine => $label ) {
$selected = selected( $cuisine, $requested_cuisine, false );
printf( '<option%s>%s</option>', $selected, $label );
}
echo '</select>';
return;
}
当用户选择一种食物类型并单击“ 过滤器”按钮时,列表中的行可以仅限于使用现有ms_sites_list_table_query_args过滤器提供该美食的站点, 如下所示:
add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_cuisine' );
function myplugin_sites_with_cuisine( $args ) {
if ( empty( $_GET['cuisine' ] ) ) {
return $args;
}
$meta_query = array(
'key' => 'myplugin-cuisine',
'value' => wp_unslash( $_GET['cuisine' ] ),
);
if ( isset( $args['meta_query'] ) ) {
// add our meta query to the existing one(s).
$args['meta_query'] = array(
'relation' => 'AND',
$meta_query,
array( $args['meta_query'] ),
);
}
else {
// add our meta query.
$args['meta_query'] = array(
$meta_query,
);
}
return $args;
}
网站显示状态
与其他列表一样,“站点”列表中的每一行现在都有显示状态。默认情况下,每个网站的所有网站状态(“公共”除外)都作为显示状态包括在内。此外,网络的主站点也具有“主要”显示状态。
当用户选择了特定的站点状态视图时,该状态将不在显示状态中(就像“所有文章”屏幕一样)。
插件还可以使用display_site_states
过滤器修改显示状态 。
为了进一步延续我们的餐厅指南示例,我们可以添加自定义状态以及每个餐厅提供的美食作为显示状态。这可以通过以下方式实现:
add_filter( 'ms_sites_list_table_query_args', 'myplugin_sites_with_cuisine' );
function myplugin_sites_with_cuisine( $args ) {
if ( empty( $_GET['cuisine' ] ) ) {
return $args;
}
$meta_query = array(
'key' => 'myplugin-cuisine',
'value' => wp_unslash( $_GET['cuisine' ] ),
);
if ( isset( $args['meta_query'] ) ) {
// add our meta query to the existing one(s).
$args['meta_query'] = array(
'relation' => 'AND',
$meta_query,
array( $args['meta_query'] ),
);
}
else {
// add our meta query.
$args['meta_query'] = array(
$meta_query,
);
}
return $args;
}
其他变更
返回短路的多站点类
修复在 [44983]原始补丁,在多站点类中引入了预查询过滤器。此错误使短路行为与其他短路行为有所不同,并且仍在继续执行。现在,通过networks_pre_query
和sites_pre_query
运行过滤后,该代码将立即退出。这使开发人员可以完全热线连接网络和站点查询,以从另一个来源(例如,不同的缓存或弹性搜索)进行加载。
通过ID改进了站点和网络查找的性能
在早期版本的WordPress中,当运行代码get_site( 12345 )
时,如果没有该站点的ID,是不会缓存结果的。这意味着随后的所有查找仍将导致数据库查询被触发,这是不必要的。在[45910]中,不存在的站点数据将存储为-1
而不是false
,以便后续的数据库查找。
多站点玩的比较少,很大一部分原因就是很多主题和插件的不兼容多站点模式!
一般用多站点模式来做开发和演示,偶尔也用来给客户做多语言