feat(widgets): complete phase 3 atomic integration
This commit is contained in:
@@ -760,12 +760,11 @@ $hmb_js = get_template_directory() . '/assets/js/header-newadd.js';
|
||||
}
|
||||
|
||||
// 单篇资源专属样式
|
||||
if ($is_single_resource) {
|
||||
$enqueue_module('single-post');
|
||||
$enqueue_module('resource-meta');
|
||||
$enqueue_module('comments');
|
||||
$enqueue_module('widgets');
|
||||
}
|
||||
if ($is_single_resource) {
|
||||
$enqueue_module('single-post');
|
||||
$enqueue_module('resource-meta');
|
||||
$enqueue_module('comments');
|
||||
}
|
||||
|
||||
// 资源归档专属样式
|
||||
if ($is_resource_archive) {
|
||||
|
||||
@@ -71,13 +71,13 @@ trait ScriptsPart1c {
|
||||
'aksrt-swiper',
|
||||
$base_uri . '/assets/css/frontend/swiper-bundle.min.css',
|
||||
[],
|
||||
'11.0'
|
||||
'11.2.10'
|
||||
);
|
||||
wp_enqueue_script(
|
||||
'aksrt-swiper',
|
||||
$base_uri . '/assets/js/swiper-bundle.min.js',
|
||||
[],
|
||||
'11.0',
|
||||
'11.2.10',
|
||||
true
|
||||
);
|
||||
}
|
||||
@@ -299,17 +299,6 @@ trait ScriptsPart1c {
|
||||
);
|
||||
}
|
||||
|
||||
$widget_set_js = get_template_directory() . '/assets/js/widget-set.js';
|
||||
if (file_exists($widget_set_js)) {
|
||||
wp_enqueue_script(
|
||||
'aksrt-widget-set',
|
||||
$base_uri . '/assets/js/widget-set.js',
|
||||
['aksrt-script', 'aksrt-qrcode'],
|
||||
(string) filemtime($widget_set_js),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
// ===== 全局 UI 增强(Toast、骨架屏、悬停动效、灯箱、滚动感知)=====
|
||||
$enhancements_css = get_template_directory() . '/assets/css/frontend/enhancements.css';
|
||||
if (file_exists($enhancements_css)) {
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace AKSRT\Core;
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class Setup {
|
||||
use SetupPart1;
|
||||
use SetupPart2;
|
||||
|
||||
|
||||
@@ -26,7 +25,6 @@ class Setup {
|
||||
public function init(): void {
|
||||
add_action('after_setup_theme', [$this, 'load_textdomain'], 1);
|
||||
add_action('after_setup_theme', [$this, 'setup_theme']);
|
||||
add_action('widgets_init', [$this, 'register_sidebars']);
|
||||
add_filter('dynamic_sidebar_params', [$this, 'filter_sidebar_widget_params']);
|
||||
add_action('init', [$this, 'register_nav_menus'], 0);
|
||||
add_action('init', [$this, 'register_post_types'], 1);
|
||||
|
||||
@@ -1,424 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Core;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
trait SetupPart1 {
|
||||
|
||||
public function register_sidebars(): void {
|
||||
$fluid_wrapper_before = '<div id="%1$s" class="zib-widget %2$s">';
|
||||
$card_wrapper_before = '<div id="%1$s" class="zib-widget %2$s">';
|
||||
$title_before = '<h3>';
|
||||
$title_after = '</h3>';
|
||||
|
||||
// ===== 全站 / 首页挂载位(对齐 Zibll 首页骨架) =====
|
||||
register_sidebar([
|
||||
'id' => 'all_top_fluid',
|
||||
'name' => __('全站 - 顶部全宽', 'aksrt'),
|
||||
'description' => __('显示在所有页面内容区上方的全宽挂载位。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'all_bottom_fluid',
|
||||
'name' => __('全站 - 底部全宽', 'aksrt'),
|
||||
'description' => __('显示在所有页面页脚上方的全宽挂载位。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'all_sidebar_top',
|
||||
'name' => __('全站 - 侧栏顶部', 'aksrt'),
|
||||
'description' => __('显示在全站侧栏顶部。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'all_sidebar_bottom',
|
||||
'name' => __('全站 - 侧栏底部', 'aksrt'),
|
||||
'description' => __('显示在全站侧栏底部。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'all_footer',
|
||||
'name' => __('全站 - 页脚小工具', 'aksrt'),
|
||||
'description' => __('显示在页脚内部的统一小工具区域。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'mobile_nav_fluid',
|
||||
'name' => __('移动端 - 菜单底部', 'aksrt'),
|
||||
'description' => __('显示在移动端抽屉菜单底部。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'home_top_fluid',
|
||||
'name' => __('首页 - 顶部全宽', 'aksrt'),
|
||||
'description' => __('显示在首页主内容上方的全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'home_top_content',
|
||||
'name' => __('首页 - 内容上方', 'aksrt'),
|
||||
'description' => __('显示在首页主内容区顶部。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'home_bottom_content',
|
||||
'name' => __('首页 - 内容下方', 'aksrt'),
|
||||
'description' => __('显示在首页主内容区底部。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'home_bottom_fluid',
|
||||
'name' => __('首页 - 底部全宽', 'aksrt'),
|
||||
'description' => __('显示在首页页脚上方的全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'home_sidebar',
|
||||
'name' => __('首页 - 侧边栏', 'aksrt'),
|
||||
'description' => __('显示在首页右侧栏。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
// 文章详情页侧栏
|
||||
register_sidebar([
|
||||
'id' => 'sidebar-article',
|
||||
'name' => __('文章页 - 侧边栏', 'aksrt'),
|
||||
'description' => __('显示在文章详情页右侧。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
// ===== 文章页 Widget 区域(模板zibll 多位置) =====
|
||||
register_sidebar([
|
||||
'id' => 'single_top_fluid',
|
||||
'name' => __('文章页 - 顶部全宽', 'aksrt'),
|
||||
'description' => __('文章页顶部全宽区域(在封面/面包屑之上)。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'single_top_content',
|
||||
'name' => __('文章页 - 内容上方', 'aksrt'),
|
||||
'description' => __('文章主体卡片上方(在内容列内)。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'single_bottom_content',
|
||||
'name' => __('文章页 - 内容下方', 'aksrt'),
|
||||
'description' => __('评论区下方(在内容列内)。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'single_bottom_fluid',
|
||||
'name' => __('文章页 - 底部全宽', 'aksrt'),
|
||||
'description' => __('文章页底部全宽区域(在页脚之上)。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
// ===== 分类页 Widget 区域 =====
|
||||
register_sidebar([
|
||||
'id' => 'cat_top_fluid',
|
||||
'name' => __('分类页 - 顶部全宽', 'aksrt'),
|
||||
'description' => __('分类归档页顶部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'cat_top_content',
|
||||
'name' => __('分类页 - 内容上方', 'aksrt'),
|
||||
'description' => __('分类归档页内容区上方。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'cat_bottom_content',
|
||||
'name' => __('分类页 - 内容下方', 'aksrt'),
|
||||
'description' => __('分类归档页内容区下方。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'cat_bottom_fluid',
|
||||
'name' => __('分类页 - 底部全宽', 'aksrt'),
|
||||
'description' => __('分类归档页底部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'cat_sidebar',
|
||||
'name' => __('分类页 - 侧栏', 'aksrt'),
|
||||
'description' => __('分类归档页侧栏区域。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
// ===== 标签页 Widget 区域 =====
|
||||
register_sidebar([
|
||||
'id' => 'tag_top_fluid',
|
||||
'name' => __('标签页 - 顶部全宽', 'aksrt'),
|
||||
'description' => __('标签归档页顶部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'tag_top_content',
|
||||
'name' => __('标签页 - 内容上方', 'aksrt'),
|
||||
'description' => __('标签归档页内容区上方。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'tag_bottom_content',
|
||||
'name' => __('标签页 - 内容下方', 'aksrt'),
|
||||
'description' => __('标签归档页内容区下方。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'tag_bottom_fluid',
|
||||
'name' => __('标签页 - 底部全宽', 'aksrt'),
|
||||
'description' => __('标签归档页底部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'tag_sidebar',
|
||||
'name' => __('标签页 - 侧栏', 'aksrt'),
|
||||
'description' => __('标签归档页侧栏区域。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
// ===== 搜索页 Widget 区域 =====
|
||||
register_sidebar([
|
||||
'id' => 'search_top_fluid',
|
||||
'name' => __('搜索页 - 顶部全宽', 'aksrt'),
|
||||
'description' => __('搜索结果页顶部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'search_top_content',
|
||||
'name' => __('搜索页 - 内容上方', 'aksrt'),
|
||||
'description' => __('搜索结果页内容区上方。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'search_bottom_content',
|
||||
'name' => __('搜索页 - 内容下方', 'aksrt'),
|
||||
'description' => __('搜索结果页内容区下方。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'search_bottom_fluid',
|
||||
'name' => __('搜索页 - 底部全宽', 'aksrt'),
|
||||
'description' => __('搜索结果页底部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'search_sidebar',
|
||||
'name' => __('搜索页 - 侧栏', 'aksrt'),
|
||||
'description' => __('搜索结果页侧栏区域。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'archive_bottom_fluid',
|
||||
'name' => __('归档页 - 底部全宽', 'aksrt'),
|
||||
'description' => __('分类/标签/归档页底部全宽区域。', 'aksrt'),
|
||||
'before_widget' => $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
register_sidebar([
|
||||
'id' => 'author-sidebar',
|
||||
'name' => __('作者页 - 侧栏', 'aksrt'),
|
||||
'description' => __('作者归档页侧栏区域。', 'aksrt'),
|
||||
'before_widget' => $card_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
|
||||
// ── Per-page dynamic sidebars (zibll zib_page_register_sidebar parity) ──
|
||||
// Pages that opt in via meta `widgets_register=1` + `widgets_register_container`
|
||||
// (a serialized list of area keys) get page_{key}_{ID} sidebars registered, and
|
||||
// the matching `page_sidebar_{ID}` is treated as active when any of its areas
|
||||
// hold widgets. page.php reads page_top_fluid_/page_top_content_/etc.
|
||||
$this->register_page_sidebars();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register dynamic per-page widget areas (aligns Zibll zib_page_register_sidebar).
|
||||
*
|
||||
* Zibll stores, per page, a `widgets_register` flag and a `widgets_register_container`
|
||||
* serialized array of area keys (sidebar/top_fluid/top_content/bottom_content/bottom_fluid).
|
||||
* We replicate that: for every page opted in, register page_{key}_{ID} sidebars.
|
||||
*/
|
||||
public function register_page_sidebars(): void {
|
||||
global $wpdb;
|
||||
// Cache the opt-in page list (postmeta-driven), mirroring zib_get_widgets_register_pages.
|
||||
$pages = wp_cache_get('aksrt_widgets_register_pages', 'aksrt_cache_group', true);
|
||||
if (false === $pages) {
|
||||
// phpcs:ignore WordPress.DB.DirectDatabaseQuery
|
||||
$rows = $wpdb->get_results(
|
||||
"SELECT p.ID, p.post_title, pm.meta_value
|
||||
FROM {$wpdb->posts} p
|
||||
INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID
|
||||
WHERE p.post_type = 'page'
|
||||
AND p.post_status = 'publish'
|
||||
AND pm.meta_key = 'widgets_register_container'
|
||||
AND pm.meta_value LIKE '%;}'"
|
||||
);
|
||||
$pages = is_array($rows) ? $rows : [];
|
||||
wp_cache_set('aksrt_widgets_register_pages', $pages, 'aksrt_cache_group');
|
||||
}
|
||||
|
||||
$area_labels = [
|
||||
'sidebar' => __('侧边栏', 'aksrt'),
|
||||
'top_fluid' => __('顶部全宽度', 'aksrt'),
|
||||
'top_content' => __('主内容上面', 'aksrt'),
|
||||
'bottom_content' => __('主内容下面', 'aksrt'),
|
||||
'bottom_fluid' => __('底部全宽度', 'aksrt'),
|
||||
];
|
||||
|
||||
$fluid_wrapper_before = '<div id="%1$s" class="zib-widget %2$s">';
|
||||
$card_wrapper_before = '<div id="%1$s" class="zib-widget %2$s">';
|
||||
$title_before = '<h3>';
|
||||
$title_after = '</h3>';
|
||||
|
||||
foreach ($pages as $page) {
|
||||
$meta_value = maybe_unserialize($page->meta_value);
|
||||
if (!is_array($meta_value)) {
|
||||
continue;
|
||||
}
|
||||
$name = function_exists('aksrt_str_cut') ? aksrt_str_cut($page->post_title, 0, 10, '...') : mb_substr((string) $page->post_title, 0, 10);
|
||||
foreach ($meta_value as $key) {
|
||||
if (!isset($area_labels[$key])) {
|
||||
continue;
|
||||
}
|
||||
$id = 'page_' . $key . '_' . (int) $page->ID;
|
||||
register_sidebar([
|
||||
'name' => sprintf(__('[页面: %1$s] - %2$s', 'aksrt'), $name, $area_labels[$key]),
|
||||
'id' => $id,
|
||||
'description' => sprintf(__('显示在[页面:%1$s]的 %2$s 位置', 'aksrt'), $name, $area_labels[$key]),
|
||||
'before_widget' => $key === 'sidebar' ? $card_wrapper_before : $fluid_wrapper_before,
|
||||
'after_widget' => '</div>',
|
||||
'before_title' => $title_before,
|
||||
'after_title' => $title_after,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,351 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Public widget list REST endpoints.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
namespace AKSRT\Core;
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
class WidgetAjax {
|
||||
private static $instance = null;
|
||||
|
||||
public static function get_instance(): self {
|
||||
if (null === self::$instance) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function init(): void {
|
||||
add_action('rest_api_init', [$this, 'register_routes']);
|
||||
}
|
||||
|
||||
public function register_routes(): void {
|
||||
$routes = [
|
||||
'/widgets/posts' => 'rest_main_posts',
|
||||
'/widgets/tab-posts' => 'rest_tab_posts',
|
||||
'/widgets/category-tabs' => 'rest_category_tabs',
|
||||
'/widgets/category-block' => 'rest_category_block',
|
||||
'/widgets/category-recommend' => 'rest_category_recommend',
|
||||
'/widgets/hot-posts' => 'rest_hot_posts',
|
||||
'/widgets/oneline-posts' => 'rest_oneline_posts',
|
||||
'/widgets/recent-comments' => 'rest_recent_comments',
|
||||
'/widgets/tag-cloud' => 'rest_tag_cloud',
|
||||
'/widgets/categories' => 'rest_categories',
|
||||
'/widgets/term-cards' => 'rest_term_cards',
|
||||
'/widgets/term-aggregation' => 'rest_term_aggregation',
|
||||
];
|
||||
foreach ($routes as $path => $cb) {
|
||||
register_rest_route('aksrt/v1', $path, [
|
||||
'methods' => 'GET',
|
||||
'callback' => [$this, $cb],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function rest_main_posts(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\WidgetMainPosts')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'count' => max(1, min(30, (int) ($request->get_param('count') ?? 6))),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')),
|
||||
'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC',
|
||||
'cat' => max(0, (int) ($request->get_param('cat') ?? 0)),
|
||||
'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)),
|
||||
'pay_type' => sanitize_key((string) ($request->get_param('pay_type') ?? '')),
|
||||
'style' => sanitize_key((string) ($request->get_param('style') ?? 'list')),
|
||||
'show_thumb' => $request->get_param('show_thumb') === null ? 1 : (int) $request->get_param('show_thumb'),
|
||||
'show_meta' => $request->get_param('show_meta') === null ? 1 : (int) $request->get_param('show_meta'),
|
||||
'show_number' => (int) ($request->get_param('show_number') ?? 0),
|
||||
'paginate' => in_array(sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')), ['none','ajax','number'], true) ? sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')) : 'ajax',
|
||||
];
|
||||
$page = max(1, (int) ($request->get_param('page') ?? $request->get_param('paged') ?? 1));
|
||||
return $this->payload(\AKSRT\Widgets\WidgetMainPosts::query_payload($instance, $page), $page);
|
||||
}
|
||||
|
||||
public function rest_tab_posts(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\TabPostsWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$default_count = max(1, min(20, (int) ($request->get_param('count') ?? 5)));
|
||||
$style = sanitize_key((string) ($request->get_param('style') ?? 'mini'));
|
||||
if (!in_array($style, ['list', 'card', 'mini'], true)) {
|
||||
$style = 'mini';
|
||||
}
|
||||
$paginate = sanitize_key((string) ($request->get_param('paginate') ?? 'none'));
|
||||
if (!in_array($paginate, ['none', 'ajax', 'number'], true)) {
|
||||
$paginate = 'none';
|
||||
}
|
||||
$page = max(1, (int) ($request->get_param('page') ?? 1));
|
||||
$tab = [
|
||||
'title' => '',
|
||||
'category_id' => max(0, (int) ($request->get_param('cat') ?? $request->get_param('category_id') ?? 0)),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')),
|
||||
'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC',
|
||||
'count' => max(0, min(20, (int) ($request->get_param('tab_count') ?? 0))),
|
||||
'enabled' => true,
|
||||
'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)),
|
||||
'pay_type' => sanitize_key((string) ($request->get_param('pay_type') ?? '')),];
|
||||
$opts = [
|
||||
'style' => $style,
|
||||
'paginate' => $paginate,
|
||||
'show_thumb' => $request->get_param('show_thumb') === null ? 1 : (int) $request->get_param('show_thumb'),
|
||||
'show_meta' => $request->get_param('show_meta') === null ? 1 : (int) $request->get_param('show_meta'),
|
||||
'show_number' => (int) ($request->get_param('show_number') ?? 0),
|
||||
];
|
||||
$payload = \AKSRT\Widgets\TabPostsWidget::render_tab_payload($tab, $default_count, $opts, $page);
|
||||
$html = (string) ($payload['html'] ?? '');
|
||||
if ($html === '') {
|
||||
$html = function_exists('aksrt_get_ajax_null')
|
||||
? aksrt_get_ajax_null(__('暂无文章', 'aksrt'))
|
||||
: '<p class="widget-empty ajax-item">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||
} else {
|
||||
$html = '<div class="widget-tab-posts__list widget-tab-posts__list--' . esc_attr($style) . ' aksrt-main-posts style-' . esc_attr($style) . '">' . $html . '</div>';
|
||||
}
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
'html' => $html,
|
||||
'paginate_html' => (string) ($payload['paginate_html'] ?? ''),
|
||||
'has_more' => !empty($payload['has_more']),
|
||||
'page' => (int) ($payload['page'] ?? $page),
|
||||
'max_pages' => (int) ($payload['max_pages'] ?? 1),
|
||||
'total' => (int) ($payload['total'] ?? 0),
|
||||
], 200);
|
||||
}
|
||||
|
||||
public function rest_category_tabs(\WP_REST_Request $request) {
|
||||
$cat = max(0, (int) ($request->get_param('cat') ?? 0));
|
||||
$count = max(1, min(12, (int) ($request->get_param('count') ?? 6)));
|
||||
$layout = sanitize_key((string) ($request->get_param('layout') ?? 'card'));
|
||||
$columns = max(1, min(4, (int) ($request->get_param('columns') ?? 3)));
|
||||
$context = sanitize_key((string) ($request->get_param('context') ?? 'homepage'));
|
||||
if ($cat <= 0) {
|
||||
return new \WP_REST_Response(['success' => true, 'html' => ''], 200);
|
||||
}
|
||||
$post_types = function_exists('aksrt_home_widget_post_types') ? aksrt_home_widget_post_types() : ['post'];
|
||||
$query = new \WP_Query([
|
||||
'post_type' => $post_types,
|
||||
'post_status' => 'publish',
|
||||
'posts_per_page' => $count,
|
||||
'ignore_sticky_posts' => true,
|
||||
'no_found_rows' => true,
|
||||
'cat' => $cat,
|
||||
]);
|
||||
ob_start();
|
||||
if (function_exists('aksrt_home_widget_render_post_grid')) {
|
||||
aksrt_home_widget_render_post_grid($query, $layout, $columns, $context);
|
||||
} elseif ($query->have_posts()) {
|
||||
if (function_exists('aksrt_render_mini_list')) {
|
||||
echo '<div class="widget-tab-posts__list widget-tab-posts__list--mini">';
|
||||
aksrt_render_mini_list($query, ['context' => 'widget', 'show_thumb' => true]);
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo '<ul class="widget-tab-posts__list">';
|
||||
while ($query->have_posts()) {
|
||||
$query->the_post();
|
||||
echo '<li><a href="' . esc_url(get_permalink()) . '">' . esc_html(get_the_title()) . '</a></li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
}
|
||||
} else {
|
||||
echo function_exists('aksrt_get_ajax_null')
|
||||
? aksrt_get_ajax_null(__('暂无文章', 'aksrt')) // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
: '<p class="widget-empty ajax-item">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||
}
|
||||
wp_reset_postdata();
|
||||
$html = (string) ob_get_clean();
|
||||
if ($html === '') {
|
||||
$html = function_exists('aksrt_get_ajax_null')
|
||||
? aksrt_get_ajax_null(__('暂无文章', 'aksrt'))
|
||||
: '<p class="widget-empty ajax-item">' . esc_html__('暂无文章', 'aksrt') . '</p>';
|
||||
}
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_hot_posts(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\HotPostsWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$paginate = sanitize_key((string) ($request->get_param('paginate') ?? 'ajax'));
|
||||
if (!in_array($paginate, ['none', 'ajax', 'number'], true)) {
|
||||
$paginate = 'ajax';
|
||||
}
|
||||
$instance = [
|
||||
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))),
|
||||
'order_by' => sanitize_key((string) ($request->get_param('order_by') ?? 'views')),
|
||||
'days' => max(0, (int) ($request->get_param('days') ?? 30)),
|
||||
'show_thumb' => $request->get_param('show_thumb') === null ? 1 : (int) $request->get_param('show_thumb'),
|
||||
'target_blank'=> (int) ($request->get_param('target_blank') ?? 0),
|
||||
'paginate' => $paginate,
|
||||
];
|
||||
$page = max(1, (int) ($request->get_param('page') ?? 1));
|
||||
return $this->payload(\AKSRT\Widgets\HotPostsWidget::query_payload($instance, $page), $page);
|
||||
}
|
||||
|
||||
public function rest_oneline_posts(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\WidgetOnelinePosts')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 8))),
|
||||
'style' => sanitize_key((string) ($request->get_param('style') ?? 'card')),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')),
|
||||
'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC',
|
||||
'cat' => max(0, (int) ($request->get_param('cat') ?? 0)),
|
||||
'limit_day' => max(0, (int) ($request->get_param('limit_day') ?? 0)),
|
||||
'pay_type' => sanitize_key((string) ($request->get_param('pay_type') ?? '')),
|
||||
];
|
||||
$html = \AKSRT\Widgets\WidgetOnelinePosts::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_recent_comments(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\RecentCommentsWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 5))),
|
||||
'show_avatar' => $request->get_param('show_avatar') === null ? 1 : (int) $request->get_param('show_avatar'),
|
||||
'outpost' => sanitize_text_field((string) ($request->get_param('outpost') ?? '')),
|
||||
'outer' => sanitize_text_field((string) ($request->get_param('outer') ?? '')),
|
||||
];
|
||||
$html = \AKSRT\Widgets\RecentCommentsWidget::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_category_block(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\CategoryBlockWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'category_id' => max(0, (int) ($request->get_param('cat') ?? $request->get_param('category_id') ?? 0)),
|
||||
'count' => max(1, min(12, (int) ($request->get_param('count') ?? 6))),
|
||||
'columns' => max(1, min(4, (int) ($request->get_param('columns') ?? 3))),
|
||||
'layout' => sanitize_key((string) ($request->get_param('layout') ?? 'card')),
|
||||
'paginate' => sanitize_key((string) ($request->get_param('paginate') ?? 'ajax')),
|
||||
];
|
||||
$context = sanitize_key((string) ($request->get_param('context') ?? 'homepage'));
|
||||
$page = max(1, (int) ($request->get_param('page') ?? 1));
|
||||
return $this->payload(\AKSRT\Widgets\CategoryBlockWidget::query_payload($instance, $page, $context), $page);
|
||||
}
|
||||
|
||||
public function rest_category_recommend(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\CategoryRecommendWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$raw_ids = $request->get_param('category_ids');
|
||||
if (is_string($raw_ids)) {
|
||||
$raw_ids = array_filter(array_map('intval', preg_split('/[\s,]+/', $raw_ids) ?: []));
|
||||
}
|
||||
$instance = [
|
||||
'category_ids' => is_array($raw_ids) ? $raw_ids : [],
|
||||
'posts_per_category' => max(1, min(8, (int) ($request->get_param('posts_per_category') ?? 5))),
|
||||
'columns' => max(1, min(4, (int) ($request->get_param('columns') ?? 2))),
|
||||
'show_views' => (int) ($request->get_param('show_views') ?? 0),
|
||||
'show_description' => $request->get_param('show_description') === null ? 1 : (int) $request->get_param('show_description'),
|
||||
'show_dates' => $request->get_param('show_dates') === null ? 1 : (int) $request->get_param('show_dates'),
|
||||
'show_more' => $request->get_param('show_more') === null ? 1 : (int) $request->get_param('show_more'),
|
||||
];
|
||||
$html = \AKSRT\Widgets\CategoryRecommendWidget::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_tag_cloud(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\TagCloudWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'post_tag')),
|
||||
'count' => max(1, min(80, (int) ($request->get_param('count') ?? 15))),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'count')),
|
||||
'color' => sanitize_html_class((string) ($request->get_param('color') ?? 'rand')),
|
||||
'show_count' => (int) ($request->get_param('show_count') ?? 0),
|
||||
'blank' => (int) ($request->get_param('blank') ?? 0),
|
||||
'fixed_width' => (int) ($request->get_param('fixed_width') ?? 0),
|
||||
'hide_empty' => (int) ($request->get_param('hide_empty') ?? 0),
|
||||
];
|
||||
$html = \AKSRT\Widgets\TagCloudWidget::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_categories(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\CategoriesWidget')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'count' => max(1, min(50, (int) ($request->get_param('count') ?? 8))),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'count')),
|
||||
'order' => sanitize_key((string) ($request->get_param('order') ?? 'DESC')),
|
||||
'parent' => max(0, (int) ($request->get_param('parent') ?? 0)),
|
||||
'include' => sanitize_text_field((string) ($request->get_param('include') ?? '')),
|
||||
'exclude' => sanitize_text_field((string) ($request->get_param('exclude') ?? '')),
|
||||
'show_count' => $request->get_param('show_count') === null ? 1 : (int) $request->get_param('show_count'),
|
||||
'hide_empty' => $request->get_param('hide_empty') === null ? 1 : (int) $request->get_param('hide_empty'),
|
||||
'hierarchical' => (int) ($request->get_param('hierarchical') ?? 0),
|
||||
];
|
||||
$html = \AKSRT\Widgets\CategoriesWidget::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_term_cards(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\WidgetTermCards')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'category')),
|
||||
'number' => max(1, min(30, (int) ($request->get_param('number') ?? 8))),
|
||||
'pc_row' => max(1, min(12, (int) ($request->get_param('pc_row') ?? $request->get_param('columns') ?? 2))),
|
||||
'm_row' => max(1, min(12, (int) ($request->get_param('m_row') ?? 1))),
|
||||
'columns' => max(1, min(12, (int) ($request->get_param('columns') ?? $request->get_param('pc_row') ?? 2))),
|
||||
'type' => sanitize_key((string) ($request->get_param('type') ?? 'style-1')),
|
||||
'height_scale' => max(20, min(300, (int) ($request->get_param('height_scale') ?? 60))),
|
||||
'mask_opacity' => max(0, min(90, (int) ($request->get_param('mask_opacity') ?? 10))),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'count')),
|
||||
'include' => sanitize_text_field((string) ($request->get_param('include') ?? '')),
|
||||
'hide_empty' => $request->get_param('hide_empty') === null ? 1 : (int) $request->get_param('hide_empty'),
|
||||
'target_blank' => (int) ($request->get_param('target_blank') ?? 0),
|
||||
];
|
||||
$html = \AKSRT\Widgets\WidgetTermCards::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
public function rest_term_aggregation(\WP_REST_Request $request) {
|
||||
if (!class_exists('\AKSRT\Widgets\WidgetTermAggregation')) {
|
||||
return $this->fail();
|
||||
}
|
||||
$instance = [
|
||||
'taxonomy' => sanitize_key((string) ($request->get_param('taxonomy') ?? 'category')),
|
||||
'term_ids' => sanitize_text_field((string) ($request->get_param('term_ids') ?? '')),
|
||||
'count' => max(1, min(20, (int) ($request->get_param('count') ?? 4))),
|
||||
'columns' => max(1, min(3, (int) ($request->get_param('columns') ?? 1))),
|
||||
'orderby' => sanitize_key((string) ($request->get_param('orderby') ?? 'date')),
|
||||
'order' => strtoupper(sanitize_key((string) ($request->get_param('order') ?? 'desc'))) === 'ASC' ? 'ASC' : 'DESC',
|
||||
'auto_terms' => max(1, min(4, (int) ($request->get_param('auto_terms') ?? 2))),
|
||||
'target_blank' => (int) ($request->get_param('target_blank') ?? 0),
|
||||
];
|
||||
$html = \AKSRT\Widgets\WidgetTermAggregation::render_html($instance);
|
||||
return new \WP_REST_Response(['success' => true, 'html' => $html], 200);
|
||||
}
|
||||
|
||||
private function fail(): \WP_REST_Response {
|
||||
return new \WP_REST_Response(['success' => false, 'code' => 'widget_unavailable', 'message' => __('小工具服务暂不可用。', 'aksrt'), 'data' => ['items' => [], 'page' => 1, 'max_pages' => 1, 'total' => 0]], 500);
|
||||
}
|
||||
|
||||
private function payload(array $payload, int $page): \WP_REST_Response {
|
||||
return new \WP_REST_Response([
|
||||
'success' => true,
|
||||
'code' => 'ok',
|
||||
'html' => (string) ($payload['html'] ?? ''),
|
||||
'paginate_html' => (string) ($payload['paginate_html'] ?? ''),
|
||||
'has_more' => !empty($payload['has_more']),
|
||||
'page' => (int) ($payload['page'] ?? $page),
|
||||
'max_pages' => (int) ($payload['max_pages'] ?? 1),
|
||||
'total' => (int) ($payload['total'] ?? 0),
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user