feat(widgets): complete phase 3 atomic integration

This commit is contained in:
2026-08-17 18:21:47 +08:00
parent 7c3f4221fe
commit d5dfeb7102
89 changed files with 843 additions and 12886 deletions
+146
View File
@@ -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>',
]);
}
}