> */ public static function templates(): array { return [ 'article_home' => [ 'label' => __('文章首页', 'aksrt'), 'description' => __('公告、幻灯片、多栏目文章与热榜侧栏。', 'aksrt'), 'sidebars' => [ 'home_top_content' => [ ['widget' => 'notice', 'settings' => ['title' => '站点公告']], ['widget' => 'slider', 'settings' => ['title' => '精选内容']], ['widget' => 'tab_posts', 'settings' => ['title' => '热门栏目']], ], 'home_sidebar' => [['widget' => 'hot_posts', 'settings' => ['title' => '热门文章']]], ], ], 'article_list' => [ 'label' => __('文章列表', 'aksrt'), 'description' => __('标题、分类卡片与可分页文章列表。', 'aksrt'), 'sidebars' => [ 'home_top_content' => [ ['widget' => 'text_title', 'settings' => ['heading' => '最新知识内容', 'description' => '持续更新的课程、文章与资料']], ['widget' => 'term_cards', 'settings' => ['title' => '内容分类']], ['widget' => 'posts', 'settings' => ['title' => '最新发布', 'paginate' => 'number']], ], ], ], 'links_navigation' => [ 'label' => __('链接导航', 'aksrt'), 'description' => __('搜索、分类入口与链接列表。', 'aksrt'), 'sidebars' => [ 'home_top_content' => [ ['widget' => 'icon_cover_cards', 'settings' => ['title' => '常用入口']], ['widget' => 'links', 'settings' => ['title' => '链接导航']], ], 'home_sidebar' => [['widget' => 'search', 'settings' => ['title' => '快速查找']]], ], ], 'article_sidebar' => [ 'label' => __('文章侧栏', 'aksrt'), 'description' => __('目录、作者、付费授权与热榜文章。', 'aksrt'), 'sidebars' => [ 'single_sidebar' => [ ['widget' => 'posts_toc', 'settings' => ['title' => '文章目录']], ['widget' => 'author_card', 'settings' => ['title' => '作者']], ['widget' => 'post_pay', 'settings' => []], ['widget' => 'hot_posts', 'settings' => ['title' => '热门文章']], ], ], ], 'knowledge_landing' => [ 'label' => __('知识付费落地页', 'aksrt'), 'description' => __('亮点、方案、评价与常见问题。', 'aksrt'), 'sidebars' => [ 'home_top_content' => [ ['widget' => 'feature_intro', 'settings' => ['title' => '系统化学习路径']], ['widget' => 'highlights', 'settings' => ['title' => '内容亮点']], ['widget' => 'pricing_plans', 'settings' => ['title' => '选择学习方案']], ['widget' => 'reviews', 'settings' => ['title' => '学员评价']], ['widget' => 'faq', 'settings' => ['title' => '常见问题']], ], ], ], ]; } public static function template_payload(string $template): array { $templates = self::templates(); if (!isset($templates[$template])) { throw new \InvalidArgumentException(__('未知的小工具模板。', 'aksrt')); } return [ 'format' => self::FORMAT, 'template' => $template, 'sidebars' => $templates[$template]['sidebars'], ]; } public static function export(string $sidebar = ''): array { $assignments = wp_get_sidebars_widgets(); $sidebars = []; foreach ($assignments as $sidebar_id => $widget_ids) { if ($sidebar !== '' && $sidebar_id !== $sidebar) { continue; } if (!is_array($widget_ids)) { continue; } $items = []; foreach ($widget_ids as $widget_id) { $item = self::export_widget((string) $widget_id); if ($item !== null) { $items[] = $item; } } if ($items || $sidebar !== '') { $sidebars[$sidebar_id] = $items; } } return [ 'format' => self::FORMAT, 'exported_at' => gmdate('c'), 'sidebars' => $sidebars, ]; } /** @return array{sidebars:int,widgets:int} */ public static function import(array $payload, string $mode = 'append', string $target_sidebar = ''): array { if (($payload['format'] ?? '') !== self::FORMAT || !isset($payload['sidebars']) || !is_array($payload['sidebars'])) { throw new \InvalidArgumentException(__('仅接受 aksrt.widgets.v1 格式。', 'aksrt')); } $mode = $mode === 'replace' ? 'replace' : 'append'; $registered = array_keys($GLOBALS['wp_registered_sidebars'] ?? []); $assignments = wp_get_sidebars_widgets(); $sources = array_slice($payload['sidebars'], 0, 100, true); if ($target_sidebar !== '') { $combined = []; foreach ($sources as $items) { if (is_array($items)) { $combined = array_merge($combined, $items); } } $sources = [$target_sidebar => $combined]; } $changed = 0; $created = 0; foreach ($sources as $source_sidebar => $items) { $sidebar_id = $target_sidebar !== '' ? sanitize_key($target_sidebar) : sanitize_key((string) $source_sidebar); if (!in_array($sidebar_id, $registered, true) || !is_array($items)) { continue; } $current = isset($assignments[$sidebar_id]) && is_array($assignments[$sidebar_id]) ? $assignments[$sidebar_id] : []; if ($mode === 'replace') { $current = []; } foreach (array_slice($items, 0, 100) as $item) { if (!is_array($item)) { continue; } $widget_id = self::create_widget($item); if ($widget_id !== '') { $current[] = $widget_id; $created++; } } $assignments[$sidebar_id] = array_values(array_unique($current)); $changed++; } wp_set_sidebars_widgets($assignments); return ['sidebars' => $changed, 'widgets' => $created]; } public static function preview(string $template): string { $payload = self::template_payload($template); $html = ''; foreach ($payload['sidebars'] as $sidebar_id => $items) { $html .= '

' . esc_html((string) $sidebar_id) . '

'; foreach ($items as $item) { $definition = WidgetRegistry::get((string) ($item['widget'] ?? '')); if ($definition === null) { continue; } $settings = $definition->normalize((array) ($item['settings'] ?? [])); $html .= '
' . esc_html($definition->name()) . '
'; $html .= RendererRegistry::render($definition->renderer(), $settings, ['widget_id' => 'preview-0']); $html .= '
'; } $html .= '
'; } return $html; } private static function export_widget(string $widget_id): ?array { if (!preg_match('/^(aksrt_widget_[a-z0-9_]+)-([1-9][0-9]*)$/', $widget_id, $matches)) { return null; } $definition = WidgetRegistry::get_by_id_base($matches[1]); if ($definition === null) { return null; } $settings = get_option('widget_' . $definition->id_base(), []); $number = (int) $matches[2]; if (!is_array($settings) || !isset($settings[$number]) || !is_array($settings[$number])) { return null; } return ['widget' => $definition->slug(), 'settings' => $definition->normalize($settings[$number])]; } private static function create_widget(array $item): string { $definition = WidgetRegistry::get(sanitize_key((string) ($item['widget'] ?? ''))); if ($definition === null) { return ''; } $option_name = 'widget_' . $definition->id_base(); $settings = get_option($option_name, []); $settings = is_array($settings) ? $settings : []; $numbers = array_filter(array_map('intval', array_keys($settings)), static fn(int $number): bool => $number > 0); $number = $numbers ? max($numbers) + 1 : 1; $settings[$number] = $definition->normalize((array) ($item['settings'] ?? [])); $settings['_multiwidget'] = 1; update_option($option_name, $settings); return $definition->id_base() . '-' . $number; } }