feat(widgets): complete phase 3 atomic integration
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
|
||||
namespace AKSRT\WidgetSystem;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
/** Canonical 40 static areas plus five opt-in areas for each page. */
|
||||
final class WidgetAreas {
|
||||
private const PAGE_CACHE_KEY = 'aksrt_widget_pages_v1';
|
||||
|
||||
/** @return array<string, array{0:string,1:string,2:string}> */
|
||||
public static function definitions(): array {
|
||||
$areas = [
|
||||
'all_top_fluid' => ['所有页面 - 顶部全宽', '显示在所有知识内容页面顶部。', 'fluid'],
|
||||
'all_bottom_fluid' => ['所有页面 - 底部全宽', '显示在所有知识内容页面底部。', 'fluid'],
|
||||
'all_sidebar_top' => ['所有页面 - 侧栏顶部', '显示在页面侧栏最上方。', 'sidebar'],
|
||||
'all_sidebar_bottom' => ['所有页面 - 侧栏底部', '显示在页面侧栏最下方。', 'sidebar'],
|
||||
];
|
||||
$page_names = [
|
||||
'home' => '首页',
|
||||
'single' => '文章页',
|
||||
'cat' => '分类页',
|
||||
'tag' => '标签页',
|
||||
'search' => '搜索页',
|
||||
];
|
||||
$positions = [
|
||||
'top_fluid' => ['顶部全宽', 'fluid'],
|
||||
'top_content' => ['主内容上面', 'content'],
|
||||
'bottom_content' => ['主内容下面', 'content'],
|
||||
'bottom_fluid' => ['底部全宽', 'fluid'],
|
||||
'sidebar' => ['侧边栏', 'sidebar'],
|
||||
];
|
||||
foreach ($page_names as $prefix => $page_name) {
|
||||
foreach ($positions as $suffix => [$position, $kind]) {
|
||||
$areas[$prefix . '_' . $suffix] = [
|
||||
$page_name . ' - ' . $position,
|
||||
sprintf('显示在%s的%s位置。', $page_name, $position),
|
||||
$kind,
|
||||
];
|
||||
}
|
||||
}
|
||||
foreach (['author' => '作者页', 'msg' => '消息中心'] as $prefix => $page_name) {
|
||||
$areas[$prefix . '_top_fluid'] = [$page_name . ' - 顶部全宽', '显示在' . $page_name . '内容顶部。', 'fluid'];
|
||||
$areas[$prefix . '_bottom_fluid'] = [$page_name . ' - 底部全宽', '显示在' . $page_name . '内容底部。', 'fluid'];
|
||||
}
|
||||
$areas['user_top_fluid'] = ['用户中心 - 顶部全宽', '显示在用户中心内容顶部。', 'fluid'];
|
||||
$areas['user_top_content'] = ['用户中心 - 内容区上面', '显示在用户中心主内容上面。', 'content'];
|
||||
$areas['user_bottom_fluid'] = ['用户中心 - 底部全宽', '显示在用户中心内容底部。', 'fluid'];
|
||||
$areas['newposts_sidebar_top'] = ['前台投稿 - 侧栏顶部', '显示在前台投稿侧栏顶部,并在移动端保留。', 'sidebar'];
|
||||
$areas['newposts_sidebar_bottom'] = ['前台投稿 - 侧栏底部', '显示在前台投稿侧栏底部,并在移动端保留。', 'sidebar'];
|
||||
$areas['all_footer'] = ['页脚内部', '显示在站点页脚内部。', 'content'];
|
||||
$areas['mobile_nav_fluid'] = ['移动菜单 - 底部', '显示在移动端抽屉菜单底部。', 'sidebar'];
|
||||
return $areas;
|
||||
}
|
||||
|
||||
/** @return string[] */
|
||||
public static function static_ids(): array {
|
||||
return array_keys(self::definitions());
|
||||
}
|
||||
|
||||
public static function register(): void {
|
||||
foreach (self::definitions() as $id => [$name, $description, $kind]) {
|
||||
self::register_area($id, $name, $description, $kind);
|
||||
}
|
||||
self::register_page_areas();
|
||||
}
|
||||
|
||||
public static function render(string $id, string $class = ''): bool {
|
||||
if (!is_active_sidebar($id)) {
|
||||
return false;
|
||||
}
|
||||
$class = trim('aksrt-widget-area aksrt-widget-area--' . sanitize_html_class($id) . ' ' . $class);
|
||||
echo '<div class="' . esc_attr($class) . '" data-widget-area="' . esc_attr($id) . '">';
|
||||
dynamic_sidebar($id);
|
||||
echo '</div>';
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function flush_page_cache(): void {
|
||||
wp_cache_delete(self::PAGE_CACHE_KEY, 'aksrt');
|
||||
}
|
||||
|
||||
private static function register_page_areas(): void {
|
||||
$page_ids = wp_cache_get(self::PAGE_CACHE_KEY, 'aksrt');
|
||||
if (!is_array($page_ids)) {
|
||||
$page_ids = get_posts([
|
||||
'post_type' => 'page',
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => -1,
|
||||
'fields' => 'ids',
|
||||
'orderby' => 'date',
|
||||
'order' => 'ASC',
|
||||
'no_found_rows' => true,
|
||||
'update_post_meta_cache' => false,
|
||||
'update_post_term_cache' => false,
|
||||
'meta_query' => [
|
||||
[
|
||||
'key' => 'widgets_register',
|
||||
'value' => '1',
|
||||
],
|
||||
],
|
||||
]);
|
||||
$page_ids = array_map('absint', $page_ids);
|
||||
wp_cache_set(self::PAGE_CACHE_KEY, $page_ids, 'aksrt');
|
||||
}
|
||||
|
||||
$positions = [
|
||||
'sidebar' => ['侧边栏', 'sidebar'],
|
||||
'top_fluid' => ['顶部全宽', 'fluid'],
|
||||
'top_content' => ['主内容上面', 'content'],
|
||||
'bottom_content' => ['主内容下面', 'content'],
|
||||
'bottom_fluid' => ['底部全宽', 'fluid'],
|
||||
];
|
||||
foreach ($page_ids as $page_id) {
|
||||
$enabled = get_post_meta($page_id, 'widgets_register_container', true);
|
||||
if (!is_array($enabled)) {
|
||||
continue;
|
||||
}
|
||||
$title = wp_html_excerpt(get_the_title($page_id), 12, '…');
|
||||
foreach (array_values(array_unique(array_map('sanitize_key', $enabled))) as $position) {
|
||||
if (!isset($positions[$position])) {
|
||||
continue;
|
||||
}
|
||||
[$label, $kind] = $positions[$position];
|
||||
self::register_area(
|
||||
'page_' . $position . '_' . $page_id,
|
||||
sprintf('[页面:%1$s] - %2$s', $title, $label),
|
||||
sprintf('显示在页面“%1$s”的%2$s位置。', $title, $label),
|
||||
$kind
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function register_area(string $id, string $name, string $description, string $kind): void {
|
||||
register_sidebar([
|
||||
'id' => $id,
|
||||
'name' => __($name, 'aksrt'),
|
||||
'description' => __($description, 'aksrt'),
|
||||
'before_widget' => '<section id="%1$s" class="aksrt-widget-shell aksrt-widget-shell--' . esc_attr($kind) . ' %2$s">',
|
||||
'after_widget' => '</section>',
|
||||
'before_title' => '<h3 class="aksrt-widget-shell__title">',
|
||||
'after_title' => '</h3>',
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user