feat(widgets): replicate 12 reference widgets for full Zibll parity

- rewrite schemas for posts, tab_posts, oneline_posts, hot_posts,
  term_cards, term_aggregation, media_cards, combo_info, partners,
  recent_comments, posts_toc and slider_media_combo to mirror the
  modern reference modules field by field (options, defaults,
  dependencies, min/max/step, subheadings)
- port reference renderers: hot ranking with TOP badges, category
  aggregation card, graphic cover cards, partners CSS marquee,
  combo info cards with auto band palette, recent comment list
- rename 分类与标签聚合卡片 to 分类聚合卡片 and restrict it to
  categories (no tags/topics branch in this project)
- drop topics filter fields and the topics query branch; align
  orderby value domain with supported post meta
- add searchable sortable terms admin field type and spinner unit
  suffix rendering
- unify widget pagination and lazy loading on the REST client with
  the runtime-owned ias reveal trigger; remove the legacy
  post_ajax_trigger dual path
- align section-navs TOC with the reference contract (wznav ids,
  3-heading minimum, zib-widget box)
This commit is contained in:
2026-09-05 11:28:00 +08:00
parent 9dc278bd83
commit b639d57c5b
25 changed files with 1388 additions and 446 deletions
+232 -69
View File
@@ -38,9 +38,9 @@ final class WidgetSchemas {
];
case 'posts_toc':
return [
['id' => 'min_headings', 'type' => 'spinner', 'label' => '最少标题数量', 'default' => 3, 'min' => 1, 'max' => 20],
['id' => 'collapsed', 'type' => 'switcher', 'label' => '默认收起', 'default' => false],
['id' => 'offset', 'type' => 'spinner', 'label' => '滚动偏移', 'default' => 70, 'min' => 0, 'max' => 300],
['id' => 'title', 'type' => 'text', 'label' => '标题', 'default' => '文章目录'],
['id' => 'mini_title', 'type' => 'text', 'label' => '副标题', 'default' => ''],
['id' => 'in_affix', 'type' => 'switcher', 'label' => '侧栏随动(仅在侧边栏有效)', 'default' => false],
];
case 'quote':
return [
@@ -76,10 +76,11 @@ final class WidgetSchemas {
];
case 'recent_comments':
return [
['id' => 'count', 'type' => 'spinner', 'label' => '显示数量', 'default' => 6, 'min' => 1, 'max' => 50],
['id' => 'exclude_users', 'type' => 'text', 'label' => '排除用户 ID', 'default' => '', 'sanitize' => 'ids'],
['id' => 'exclude_posts', 'type' => 'text', 'label' => '排除文章 ID', 'default' => '', 'sanitize' => 'ids'],
['id' => 'show_source', 'type' => 'switcher', 'label' => '显示评论来源', 'default' => true],
['id' => 'limit', 'type' => 'spinner', 'label' => '显示数量', 'default' => 8, 'min' => 1, 'max' => 50, 'step' => 1],
['id' => 'outer', 'type' => 'text', 'label' => '排除用户ID', 'default' => '', 'sanitize' => 'ids', 'description' => '填写需要排除的用户ID,用逗号分割,例如:55,66,100'],
['id' => 'outpost', 'type' => 'text', 'label' => '排除文章ID', 'default' => '', 'sanitize' => 'ids', 'description' => '填写需要排除的文章ID,用逗号分割,例如:55,66,100'],
['id' => 'show_source', 'type' => 'switcher', 'label' => '显示来源', 'default' => false],
['id' => 'style', 'type' => 'radio', 'label' => '显示样式', 'default' => '', 'options' => ['' => '简约', 'style_2' => '风格2']],
];
case 'links':
return [
@@ -142,65 +143,137 @@ final class WidgetSchemas {
];
case 'partners':
return [
['id' => 'rows_pc', 'type' => 'spinner', 'label' => 'PC 行数', 'default' => 2, 'min' => 1, 'max' => 5],
['id' => 'rows_mobile', 'type' => 'spinner', 'label' => '移动端行数', 'default' => 1, 'min' => 1, 'max' => 4],
['id' => 'speed', 'type' => 'spinner', 'label' => '滚动速度', 'default' => 30, 'min' => 5, 'max' => 120],
['id' => 'items', 'type' => 'group', 'label' => '合作伙伴', 'max_items' => 60, 'fields' => self::media_card_fields()],
['id' => 'rows', 'type' => 'button_set', 'label' => 'PC端显示几行滚动', 'default' => 3, 'options' => [1 => '1行', 2 => '2行', 3 => '3行', 4 => '4行', 5 => '5行', 6 => '6行']],
['id' => 'm_rows', 'type' => 'button_set', 'label' => '移动端显示几行滚动', 'default' => 3, 'options' => [1 => '1行', 2 => '2行', 3 => '3行', 4 => '4行', 5 => '5行', 6 => '6行']],
['id' => 'style_type', 'type' => 'radio', 'label' => '选择合作伙伴卡片的呈现方式', 'default' => 'card', 'options' => ['card' => '图文卡片(适合正方形logo)', 'logo' => '纯 Logo', 'chip' => '精简胶囊']],
['id' => 'card_width', 'type' => 'spinner', 'label' => '单卡片宽度', 'default' => 200, 'min' => 80, 'max' => 500, 'step' => 10, 'unit' => 'px', 'dependency' => ['style_type', '==', 'card'], 'description' => 'PC端每张卡片的宽度(纯 Logo 模式下宽度会自适应图片,此项不生效)'],
['id' => 'card_height', 'type' => 'spinner', 'label' => '卡片高度', 'default' => 60, 'min' => 50, 'max' => 260, 'step' => 5, 'unit' => 'px', 'dependency' => ['style_type', '!=', 'chip'], 'description' => '每张卡片的高度,纯 Logo 模式建议 70-120'],
['id' => 'card_bg', 'type' => 'switcher', 'label' => '显示每张合作伙伴卡片的背景', 'default' => true],
['id' => 'card_radius', 'type' => 'slider', 'label' => '卡片圆角', 'default' => 16, 'min' => 0, 'max' => 60, 'step' => 1, 'unit' => 'px', 'dependency' => ['card_bg', '!=', '']],
['id' => 'speed', 'type' => 'slider', 'label' => '滚动速度(数越小越快)', 'default' => 3, 'min' => 0.1, 'max' => 10, 'step' => 0.1, 'unit' => 's'],
['id' => 'direction', 'type' => 'radio', 'label' => '滚动方向', 'default' => 'alternate', 'options' => ['alternate' => '奇数行左,偶数行右', 'left' => '全部向左', 'right' => '全部向右']],
['id' => 'pause_hover', 'type' => 'switcher', 'label' => '鼠标悬停暂停', 'default' => true],
['id' => 'show_widget_bg', 'type' => 'switcher', 'label' => '模块背景', 'default' => false, 'description' => '显示整个模块外层背景'],
['id' => 'go_link', 'type' => 'switcher', 'label' => '外链重定向', 'default' => true, 'description' => '开启后,将链接转为内部go跳转链接'],
['id' => 'end_fade', 'type' => 'switcher', 'label' => '两端渐隐', 'default' => true, 'description' => '开启后,卡片两端会渐隐,使卡片无缝连接'],
['id' => 'link_type', 'type' => 'radio', 'label' => '合作伙伴获取方式', 'default' => 'link', 'options' => ['link' => '通过链接获取', 'manual' => '手动添加']],
['id' => 'link_cats', 'type' => 'terms', 'label' => '选择链接分类', 'taxonomy' => 'link_category', 'default' => [], 'dependency' => ['link_type', '==', 'link'], 'description' => '需显示的链接分类,留空则为全部'],
['id' => 'link_limit', 'type' => 'spinner', 'label' => '最大获取数量', 'default' => 50, 'min' => 0, 'step' => 5, 'unit' => '个', 'dependency' => ['link_type', '==', 'link']],
['id' => 'link_orderby', 'type' => 'select', 'label' => '排序方式', 'default' => 'name', 'dependency' => ['link_type', '==', 'link'], 'options' => ['name' => '名称排序', 'updated' => '更新时间', 'rating' => '链接评分', 'rand' => '随机排序']],
['id' => 'page_links_order', 'type' => 'radio', 'label' => '顺序', 'default' => 'ASC', 'dependency' => ['link_type', '==', 'link'], 'options' => ['ASC' => '升序', 'DESC' => '降序']],
[
'id' => 'partners', 'type' => 'group', 'label' => '添加合作伙伴', 'item_label' => '合作伙伴', 'max_items' => 60, 'dependency' => ['link_type', '==', 'manual'],
'default' => [],
'fields' => [
['id' => 'title', 'type' => 'textarea', 'label' => '名称', 'default' => '', 'attributes' => ['rows' => 1], 'description' => '卡片第一行文案,建议简短'],
['id' => 'desc', 'type' => 'textarea', 'label' => '简介', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 2], 'description' => '卡片第二行文案,支持 HTML(仅在图文卡片模式下显示)'],
['id' => 'image', 'type' => 'upload', 'label' => 'Logo图片', 'default' => '', 'library' => 'image', 'description' => '如果样式选择为图文卡片,则建议全部为正方形图片'],
['id' => 'link', 'type' => 'link', 'label' => '链接', 'default' => []],
],
],
];
case 'combo_info':
return [['id' => 'items', 'type' => 'group', 'label' => '信息卡片', 'max_items' => 30, 'fields' => array_merge(self::media_card_fields(), [['id' => 'tags', 'type' => 'text', 'label' => '标签', 'default' => '']])]];
return array_merge(self::obs_animation_fields(), [
['id' => 'pc_row', 'type' => 'button_set', 'label' => 'PC端单行排列数量', 'default' => 4, 'options' => [2 => '2个', 3 => '3个', 4 => '4个', 6 => '6个']],
['id' => 'm_row', 'type' => 'button_set', 'label' => '移动端单行排列数量', 'default' => 1, 'options' => [1 => '1个', 2 => '2个']],
['id' => 'pc_gap', 'type' => 'button_set', 'label' => 'PC端卡片间距', 'default' => 10, 'options' => [5 => '10px', 10 => '20px']],
['id' => 'm_gap', 'type' => 'button_set', 'label' => '移动端卡片间距', 'default' => 5, 'options' => [5 => '10px', 10 => '20px']],
['id' => 'card_radius', 'type' => 'slider', 'label' => '卡片圆角', 'default' => 16, 'min' => 0, 'max' => 30, 'step' => 1, 'unit' => 'px'],
['id' => 'top_band', 'type' => 'switcher', 'label' => '显示顶部渐变背景', 'default' => true],
['id' => 'top_band_height', 'type' => 'slider', 'label' => '色带高度', 'default' => 150, 'min' => 100, 'max' => 400, 'step' => 20, 'unit' => 'px', 'dependency' => ['top_band', '==', '1']],
['id' => 'go_link', 'type' => 'switcher', 'label' => '外链重定向', 'default' => true, 'description' => '开启后,将链接转为内部go跳转链接'],
['id' => 'cta_text', 'type' => 'text', 'label' => '默认按钮文案', 'default' => '立即体验', 'description' => '每张卡片可单独覆盖'],
['id' => 'cta_color', 'type' => 'palette', 'label' => '默认按钮颜色', 'default' => '', 'options' => self::cta_palette()],
['id' => 'cards', 'type' => 'group', 'label' => '添加卡片', 'item_label' => '卡片', 'max_items' => 30, 'default' => [], 'fields' => [
['id' => 'title', 'type' => 'textarea', 'label' => '卡片标题', 'default' => '', 'attributes' => ['rows' => 1]],
['id' => 'icon', 'type' => 'icon', 'label' => '图标', 'default' => ''],
['id' => 'icon_image', 'type' => 'upload', 'label' => '图片图标', 'default' => '', 'library' => 'image', 'description' => '图标和图片图标二选一,设置图片将覆盖图标'],
[
'id' => 'tags', 'type' => 'group', 'label' => '标签', 'item_label' => '标签', 'max_items' => 20, 'default' => [],
'fields' => [
['id' => 'text', 'type' => 'text', 'label' => '标签文字', 'default' => ''],
['id' => 'color', 'type' => 'palette', 'label' => '标签颜色', 'default' => '', 'options' => self::tag_palette()],
],
],
['id' => 'desc', 'type' => 'textarea', 'label' => '简介描述', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 3], 'description' => '卡片描述文案,超出会自动省略(默认3行)'],
['id' => 'link', 'type' => 'link', 'label' => '链接', 'default' => []],
['id' => 'cta_text', 'type' => 'text', 'label' => '按钮文案(可选)', 'default' => '', 'description' => '留空则使用默认按钮文案'],
['id' => 'cta_color', 'type' => 'palette', 'label' => '按钮颜色(可选)', 'default' => '', 'options' => self::cta_palette()],
['id' => 'band_color', 'type' => 'select', 'label' => '顶部色带配色', 'default' => 'auto', 'options' => ['auto' => '自动(按序循环)', 'blue' => '蓝紫', 'cyan' => '青蓝', 'green' => '青绿', 'yellow' => '橙黄', 'pink' => '粉红', 'purple' => '紫罗兰', 'gray' => '中性灰']],
]],
]);
case 'media_cards':
return array_merge(self::obs_animation_fields(), [
['id' => 'pc_row', 'type' => 'button_set', 'label' => 'PC端单行排列数量', 'default' => 4, 'options' => self::row_options()],
['id' => 'm_row', 'type' => 'button_set', 'label' => '移动端单行排列数量', 'default' => 2, 'options' => self::row_options(), 'description' => '请根据此模块放置位置的宽度合理调整单行数量,避免显示不佳'],
['id' => 'mask_opacity', 'type' => 'slider', 'label' => '遮罩透明度', 'default' => 10, 'min' => 0, 'max' => 90, 'step' => 1, 'unit' => '%', 'description' => '图片上显示的黑色遮罩层的透明度'],
['id' => 'height_scale', 'type' => 'spinner', 'label' => '封面长宽比例', 'default' => 30, 'min' => 5, 'max' => 300, 'step' => 5, 'unit' => '%'],
['id' => 'font_size_pc', 'type' => 'spinner', 'label' => 'PC端字体大小', 'default' => 18, 'min' => 10, 'max' => 80, 'step' => 2, 'unit' => 'px'],
['id' => 'font_size_m', 'type' => 'spinner', 'label' => '移动端字体大小', 'default' => 14, 'min' => 10, 'max' => 80, 'step' => 2, 'unit' => 'px'],
['id' => 'font_bold', 'type' => 'switcher', 'label' => '粗体显示', 'default' => false],
['id' => 'font_color', 'type' => 'color', 'label' => '文字颜色', 'default' => ''],
['id' => 'covers', 'type' => 'group', 'label' => '添加封面', 'item_label' => '内容', 'max_items' => 40, 'default' => [], 'fields' => self::cover_fields(), 'description' => '<div class="c-yellow">由于移动端多数浏览器不支持视频背景功能,所以移动端不会显示视频!</div>'],
]);
case 'icon_cards':
return self::icon_cards_fields();
case 'icon_cover_cards':
return self::icon_cover_cards_fields();
case 'media_cards':
default:
return [['id' => 'cards', 'type' => 'group', 'label' => '卡片', 'max_items' => 40, 'fields' => self::media_card_fields()]];
}
}
private static function content(string $slug): array {
if ($slug === 'term_cards' || $slug === 'term_aggregation') {
return [
['id' => 'taxonomy', 'type' => 'select', 'label' => '分类法', 'default' => 'category', 'options' => ['category' => '分类', 'post_tag' => '标签']],
['id' => 'term_ids', 'type' => 'text', 'label' => '分类/标签 ID', 'default' => '', 'sanitize' => 'ids'],
['id' => 'count', 'type' => 'spinner', 'label' => '数量', 'default' => 8, 'min' => 1, 'max' => 50],
['id' => 'pc_row', 'type' => 'spinner', 'label' => 'PC 单行数量', 'default' => 4, 'min' => 1, 'max' => 12],
['id' => 'm_row', 'type' => 'spinner', 'label' => '移动端单行数量', 'default' => 2, 'min' => 1, 'max' => 6],
];
switch ($slug) {
case 'posts':
return self::posts_fields();
case 'tab_posts':
return self::tab_posts_fields();
case 'oneline_posts':
return self::oneline_posts_fields();
case 'hot_posts':
return self::hot_posts_fields();
case 'term_cards':
return self::term_cards_fields();
case 'term_aggregation':
return self::term_aggregation_fields();
}
return [];
}
$fields = self::post_query_fields();
if ($slug === 'hot_posts') {
$fields[] = ['id' => 'show_thumbnail', 'type' => 'switcher', 'label' => '显示缩略图', 'default' => true];
}
if ($slug === 'oneline_posts') {
$fields[] = ['id' => 'autoplay', 'type' => 'switcher', 'label' => '自动滚动', 'default' => true];
}
if ($slug === 'tab_posts') {
return self::tab_posts_fields();
}
return $fields;
private static function posts_fields(): array {
return [
['id' => 'load_mode', 'type' => 'radio', 'label' => '模块加载方式', 'default' => 'ajax', 'options' => ['detail' => '直接加载', 'ajax' => 'ajax懒加载'], 'description' => 'ajax懒加载:当页面加载完后,根据用户需要在加载当前模块内容,可提高页面渲染效率'],
['id' => 'cat', 'type' => 'text', 'label' => '分类限制', 'default' => '', 'sanitize' => 'reference_ids', 'description' => '限制请填写对应的ID,多个ID请用英文逗号隔开。如:1,2,3。支持负数进行排除,例如:-1,-2,-3。'],
['id' => 'zibpay_type', 'type' => 'checkbox', 'label' => '商品类型筛选', 'default' => [], 'options' => self::pay_types(), 'description' => '不做其它筛选'],
['id' => 'limit_day', 'type' => 'spinner', 'label' => '发布时间限制', 'default' => 0, 'min' => 0, 'step' => 5, 'unit' => '天', 'description' => '仅显示最近多少天发布的文章,为0则不限制'],
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => '', 'options' => self::posts_orderby()],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '降序', 'asc' => '升序']],
['id' => 'style', 'type' => 'radio', 'label' => '列表样式', 'default' => 'list', 'options' => ['list' => '列表样式', 'card' => '卡片样式', 'mini' => 'mini列表'], 'description' => '<div class="c-yellow">注意:不同样式尺寸不同,请根据放置的位置合理选择。例如:放在宽度较小的侧边栏,则需选择mini样式,否则显示效果不佳</div>'],
['id' => 'mini_opt', 'type' => 'checkbox', 'label' => 'mini列表配置', 'default' => [], 'dependency' => ['style', '==', 'mini'], 'options' => self::mini_opt_options(), 'description' => '不做其它筛选'],
['id' => 'count', 'type' => 'spinner', 'label' => '显示数量', 'default' => 12, 'min' => 4, 'max' => 20, 'step' => 1, 'unit' => '篇'],
['id' => 'paginate', 'type' => 'radio', 'label' => '翻页按钮', 'default' => '', 'options' => ['' => '不翻页', 'ajax' => 'AJAX追加列表翻页', 'number' => '数字翻页按钮']],
];
}
private static function tab_posts_fields(): array {
return [
['id' => 'style', 'type' => 'radio', 'label' => '列表样式', 'default' => 'mini', 'options' => ['list' => '列表样式', 'card' => '卡片样式', 'mini' => 'mini列表']],
['id' => 'mini_opt', 'type' => 'checkbox', 'label' => 'mini列表配置', 'default' => [], 'dependency' => ['style', '==', 'mini'], 'options' => ['show_thumb' => '显示缩略图', 'show_number' => '显示编号(开启翻页后,只在第一页有效)', 'show_meta' => '显示作者、时间、点赞等信息']],
['id' => 'count', 'type' => 'spinner', 'label' => '显示数量', 'default' => 6, 'min' => 4, 'max' => 20, 'step' => 1],
['id' => 'style', 'type' => 'radio', 'label' => '列表样式', 'default' => 'mini', 'options' => ['list' => '列表样式', 'card' => '卡片样式', 'mini' => 'mini列表'], 'description' => '<div class="c-yellow">注意:不同样式尺寸不同,请根据放置的位置合理选择。例如:放在宽度较小的侧边栏,则需选择mini样式,否则显示效果不佳</div>'],
['id' => 'mini_opt', 'type' => 'checkbox', 'label' => 'mini列表配置', 'default' => [], 'dependency' => ['style', '==', 'mini'], 'options' => self::mini_opt_options(), 'description' => '不做其它筛选'],
['id' => 'count', 'type' => 'spinner', 'label' => '显示数量', 'default' => 6, 'min' => 4, 'max' => 20, 'step' => 1, 'unit' => '篇'],
['id' => 'paginate', 'type' => 'radio', 'label' => '翻页按钮', 'default' => '', 'options' => ['' => '不翻页', 'ajax' => 'AJAX追加列表翻页', 'number' => '数字翻页按钮']],
[
'id' => 'tabs', 'type' => 'group', 'label' => '栏目', 'max_items' => 10,
'id' => 'tabs', 'type' => 'group', 'label' => '栏目', 'max_items' => 10, 'item_label' => '栏目',
'default' => [
['title' => '热门推荐', 'orderby' => 'views'],
['title' => '最近更新', 'orderby' => 'modified'],
['title' => '猜你喜欢', 'orderby' => 'rand'],
],
'fields' => [
['id' => 'title', 'type' => 'textarea', 'label' => '标题(必填)', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]],
['id' => 'title', 'type' => 'textarea', 'label' => '标题(必填)', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1], 'description' => '栏目显示的标题,支持HTML代码,注意代码规范'],
['id' => 'cat', 'type' => 'text', 'label' => '分类限制', 'default' => '', 'sanitize' => 'reference_ids'],
['id' => 'topics', 'type' => 'text', 'label' => '专题限制', 'default' => '', 'sanitize' => 'reference_ids', 'description' => '多个 ID 用英文逗号隔开,支持负数排除。'],
['id' => 'limit_day', 'type' => 'spinner', 'label' => '发布时间限制', 'default' => 0, 'min' => 0, 'step' => 5, 'max' => 3650],
['id' => 'zibpay_type', 'type' => 'checkbox', 'label' => '商品类型筛选', 'default' => [], 'options' => self::pay_types(), 'description' => '不做其它筛选'],
['id' => 'limit_day', 'type' => 'spinner', 'label' => '发布时间限制', 'default' => 0, 'min' => 0, 'step' => 5, 'unit' => '天', 'description' => '仅显示最近多少天发布的文章,为0则不限制'],
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => '', 'options' => self::posts_orderby()],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '降序', 'asc' => '升序']],
],
@@ -208,26 +281,82 @@ final class WidgetSchemas {
];
}
private static function posts_orderby(): array {
private static function oneline_posts_fields(): array {
return [
'' => '默认排序', 'modified' => '更新时间', 'date' => '发布时间', 'views' => '浏览数量',
'like' => '点赞数量', 'comment_count' => '评论数量', 'favorite' => '收藏数量',
'rand' => '随机排序',
['id' => 'cat', 'type' => 'text', 'label' => '分类限制', 'default' => '', 'sanitize' => 'reference_ids', 'description' => '限制请填写对应的ID,多个ID请用英文逗号隔开。如:1,2,3。支持负数进行排除,例如:-1,-2,-3。'],
['id' => 'zibpay_type', 'type' => 'checkbox', 'label' => '商品类型筛选', 'default' => [], 'options' => self::pay_types(), 'description' => '不做其它筛选'],
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => '', 'options' => self::posts_orderby()],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '降序', 'asc' => '升序']],
['id' => 'style', 'type' => 'radio', 'label' => '列表样式', 'default' => 'card', 'options' => ['list' => '列表样式', 'card' => '卡片样式', 'mini' => 'mini列表'], 'description' => '<div class="c-yellow">注意:不同样式尺寸不同,请根据放置的位置合理选择。例如:放在宽度较小的侧边栏,则需选择mini样式,否则显示效果不佳</div>'],
['id' => 'count', 'type' => 'spinner', 'label' => '显示数量', 'default' => 12, 'min' => 4, 'max' => 20, 'step' => 1, 'unit' => '篇'],
];
}
private static function post_query_fields(): array {
private static function hot_posts_fields(): array {
return [
['id' => 'category_ids', 'type' => 'text', 'label' => '分类 ID', 'default' => '', 'sanitize' => 'ids'],
['id' => 'tag_ids', 'type' => 'text', 'label' => '标签 ID', 'default' => '', 'sanitize' => 'ids'],
['id' => 'pay_type', 'type' => 'select', 'label' => '付费内容类型', 'default' => '', 'options' => self::pay_types()],
['id' => 'limit_day', 'type' => 'spinner', 'label' => '最近天数', 'default' => 0, 'min' => 0, 'max' => 3650],
['id' => 'orderby', 'type' => 'select', 'label' => '排序', 'default' => 'date', 'options' => ['date' => '发布时间', 'modified' => '更新时间', 'views' => '浏览量', 'comments' => '评论数', 'likes' => '点赞数', 'favorites' => '收藏数', 'downloads' => '下载量', 'rand' => '随机']],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'DESC', 'options' => ['DESC' => '降序', 'ASC' => '升序']],
['id' => 'count', 'type' => 'spinner', 'label' => '数量', 'default' => 8, 'min' => 1, 'max' => 50],
['id' => 'style', 'type' => 'button_set', 'label' => '列表样式', 'default' => 'card', 'options' => ['list' => '列表', 'card' => '卡片', 'mini' => 'Mini']],
['id' => 'paginate', 'type' => 'select', 'label' => '翻页方式', 'default' => 'none', 'options' => ['none' => '不翻页', 'numbered' => '数字分页', 'load_more' => '加载更多', 'infinite' => '无限加载']],
['id' => 'load_mode', 'type' => 'select', 'label' => '加载方式', 'default' => 'sync', 'options' => ['sync' => '同步', 'ajax' => 'AJAX 延迟加载']],
['id' => 'orderby', 'type' => 'radio', 'label' => '榜单类型', 'default' => 'views', 'options' => [
'views' => '热门榜单(按阅读量排序)',
'like' => '超赞榜单(按点赞量排序)',
'comment_count' => '话题榜单(按评论量排序)',
'favorite' => '收藏榜单(按收藏量排序)',
]],
['id' => 'limit_day', 'type' => 'spinner', 'label' => '限制时间(最近X天)', 'default' => 0, 'min' => 0, 'max' => 999999, 'step' => 1, 'unit' => '天', 'description' => '设置多少天内发布的文章有效,为0则不限制时间'],
['id' => 'count', 'type' => 'spinner', 'label' => '最大显示数量', 'default' => 6, 'min' => 1, 'max' => 20, 'step' => 1, 'unit' => '篇'],
['id' => 'target_blank', 'type' => 'switcher', 'label' => '新窗口打开', 'default' => false],
];
}
private static function term_cards_fields(): array {
return array_merge(self::obs_animation_fields(), [
['id' => 'term_id', 'type' => 'terms', 'label' => '添加分类', 'taxonomy' => 'category', 'default' => [], 'description' => '选择并排序需要的分类,如选择的分类下没有封面则不会显示'],
['id' => 'type', 'type' => 'radio', 'label' => '卡片样式', 'default' => 'style-1', 'options' => ['style-1' => '简单样式', 'style-2' => '样式二', 'style-3' => '样式三', 'style-4' => '样式四']],
['id' => 'height_scale', 'type' => 'spinner', 'label' => '卡片长宽比例', 'default' => 60, 'min' => 20, 'max' => 300, 'step' => 5, 'unit' => '%'],
['id' => 'pc_row', 'type' => 'button_set', 'label' => 'PC端单行排列数量', 'default' => 2, 'options' => self::row_options()],
['id' => 'm_row', 'type' => 'button_set', 'label' => '移动端单行排列数量', 'default' => 2, 'options' => self::row_options(), 'description' => '请根据此模块放置位置的宽度合理调整单行数量,避免显示不佳'],
['id' => 'mask_opacity', 'type' => 'slider', 'label' => '遮罩透明度', 'default' => 10, 'min' => 0, 'max' => 90, 'step' => 1, 'unit' => '%', 'description' => '图片上显示的黑色遮罩层的透明度'],
['id' => 'target_blank', 'type' => 'switcher', 'label' => '新窗口打开', 'default' => false],
]);
}
private static function term_aggregation_fields(): array {
return array_merge(self::obs_animation_fields(), [
['id' => 'pc_row', 'type' => 'slider', 'label' => '单行布局', 'default' => 2, 'min' => 1, 'max' => 2, 'step' => 1, 'unit' => '个', 'description' => '请根据此模块放置位置的宽度合理调整单行数量'],
['id' => 'term_id', 'type' => 'terms', 'label' => '添加分类', 'taxonomy' => 'category', 'default' => [], 'description' => '选择并排序需要的分类,如选择的分类下没有文章则不会显示'],
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => 'modified', 'options' => self::posts_orderby(), 'dependency' => ['term_id', '!=', '']],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '降序', 'asc' => '升序'], 'dependency' => ['term_id', '!=', '']],
['id' => 'count', 'type' => 'spinner', 'label' => '最大文章数量', 'default' => 4, 'min' => 1, 'max' => 20, 'step' => 1, 'unit' => '篇', 'dependency' => ['term_id', '!=', ''], 'description' => '<div class="c-yellow">请确保所选的分类内的文章数量均超过此数量,否则会出现布局错位的问题!</div>'],
['id' => 'target_blank', 'type' => 'switcher', 'label' => '新窗口打开', 'default' => false, 'dependency' => ['term_id', '!=', '']],
]);
}
private static function obs_animation_fields(): array {
return [
['id' => 'obs_animation', 'type' => 'select', 'label' => '入场动画', 'default' => '', 'options' => self::animation_options(), 'description' => '页面滚动到此模块时触发的入场动画[注意:需合理配置适当启用]'],
['id' => 'animation_repeat', 'type' => 'switcher', 'label' => '重复动画', 'default' => false, 'dependency' => ['obs_animation', '!=', ''], 'description' => '每次滚动到此模块都触发动画[注意:有性能消耗,部分老旧浏览器会有闪烁问题]'],
];
}
private static function row_options(): array {
return [1 => '1个', 2 => '2个', 3 => '3个', 4 => '4个', 6 => '6个', 12 => '12个'];
}
private static function mini_opt_options(): array {
return [
'show_thumb' => '显示缩略图',
'show_number' => '显示编号(开启翻页后,只在第一页有效)',
'show_meta' => '显示作者、时间、点赞等信息',
];
}
private static function posts_orderby(): array {
return [
'modified' => '更新时间',
'date' => '发布时间',
'views' => '浏览数量',
'like' => '点赞数量',
'comment_count' => '评论数量',
'favorite' => '收藏数量',
'rand' => '随机排序',
];
}
@@ -319,25 +448,34 @@ final class WidgetSchemas {
['id' => 'button', 'type' => 'switcher', 'label' => '显示翻页按钮', 'default' => true],
['id' => 'pagination', 'type' => 'switcher', 'label' => '显示指示器', 'default' => true],
['id' => 'effect', 'type' => 'select', 'label' => '切换动画', 'default' => 'slide', 'options' => ['slide' => '滑动', 'fade' => '淡出淡入', 'cube' => '3D方块', 'coverflow' => '3D滑入', 'flip' => '3D翻转']],
['id' => 'spacebetween', 'type' => 'spinner', 'label' => '幻灯片间距', 'default' => 20, 'min' => 0, 'max' => 500, 'step' => 5],
['id' => 'speed', 'type' => 'spinner', 'label' => '切换速度', 'default' => 0, 'min' => 0, 'max' => 3000, 'step' => 100],
['id' => 'spacebetween', 'type' => 'spinner', 'label' => '幻灯片间距', 'default' => 20, 'min' => 0, 'max' => 500, 'step' => 5, 'unit' => 'PX'],
['id' => 'speed', 'type' => 'spinner', 'label' => '切换速度', 'default' => 0, 'min' => 0, 'max' => 3000, 'step' => 100, 'unit' => '毫秒', 'description' => '设置为“0”,则为自动模式:根据幻灯片大小自动设置最佳速度'],
['id' => 'autoplay', 'type' => 'switcher', 'label' => '自动播放', 'default' => true],
['id' => 'interval', 'type' => 'spinner', 'label' => '停顿时间', 'default' => 4, 'min' => 0, 'max' => 20, 'dependency' => ['autoplay', '!=', '']],
['id' => 'interval', 'type' => 'spinner', 'label' => '停顿时间', 'default' => 4, 'min' => 0, 'max' => 20, 'unit' => '秒', 'dependency' => ['autoplay', '!=', '']],
];
$fields = [
['id' => 'layout_ratio', 'type' => 'slider', 'label' => '幻灯片宽度占比', 'default' => 60, 'min' => 0, 'max' => 100],
['id' => 'slide_scale', 'type' => 'spinner', 'label' => '幻灯片长宽比', 'default' => 50, 'min' => 0, 'max' => 500, 'step' => 5],
['id' => 'obs_animation', 'type' => 'select', 'label' => '入场动画', 'default' => '', 'options' => self::animation_options(), 'description' => '页面滚动到封面区域时触发的入场动画[注意:需合理配置适当启用]'],
['id' => 'animation_repeat', 'type' => 'switcher', 'label' => '重复动画', 'default' => false, 'dependency' => ['obs_animation', '!=', ''], 'description' => '每次滚动到封面区域都触发动画[注意:有性能消耗,部分老旧浏览器会有闪烁问题]'],
['type' => 'subheading', 'content' => 'PC端布局配置'],
['id' => 'layout_ratio', 'type' => 'slider', 'label' => '幻灯片宽度占比', 'default' => 60, 'min' => 0, 'max' => 100, 'step' => 1, 'unit' => '%'],
['id' => 'slide_scale', 'type' => 'spinner', 'label' => '幻灯片长宽比', 'default' => 50, 'min' => 0, 'max' => 500, 'step' => 5, 'unit' => '%'],
['id' => 'pc_row', 'type' => 'button_set', 'label' => '右侧卡片列数', 'default' => 2, 'options' => [1 => '1列', 2 => '2列', 3 => '3列', 4 => '4列']],
['id' => 'pc_col', 'type' => 'button_set', 'label' => '右侧卡片行数', 'default' => 2, 'options' => [1 => '1行', 2 => '2行', 3 => '3行', 4 => '4行']],
['id' => 'm_layout_type', 'type' => 'radio', 'label' => '移动端布局方式', 'default' => 'vertical', 'options' => ['default' => '保持PC端布局', 'vertical' => '上下布局', 'hide_slide' => '隐藏幻灯片', 'hide_cover' => '隐藏卡片']],
['type' => 'subheading', 'content' => '移动端布局方式'],
['id' => 'm_layout_type', 'type' => 'radio', 'label' => '布局方式', 'default' => 'vertical', 'options' => ['default' => '保持PC端布局', 'vertical' => '上下布局', 'hide_slide' => '隐藏幻灯片', 'hide_cover' => '隐藏卡片']],
['id' => 'm_row', 'type' => 'button_set', 'label' => '移动端卡片单行数量', 'default' => 2, 'dependency' => ['m_layout_type', 'any', 'hide_slide,vertical'], 'options' => [1 => '1个', 2 => '2个', 3 => '3个', 4 => '4个', 6 => '6个']],
['id' => 'm_cover_ratio', 'type' => 'spinner', 'label' => '移动端卡片长宽比', 'default' => 45, 'min' => 5, 'max' => 300, 'step' => 5, 'dependency' => ['m_layout_type', 'any', 'hide_slide,vertical']],
['id' => 'slides', 'type' => 'group', 'label' => '幻灯片内容', 'max_items' => 30, 'min_items' => 1, 'default' => $combo_slides, 'fields' => $slide_fields],
['id' => 'm_cover_ratio', 'type' => 'spinner', 'label' => '移动端卡片长宽比', 'default' => 45, 'min' => 5, 'max' => 300, 'step' => 5, 'unit' => '%', 'dependency' => ['m_layout_type', 'any', 'hide_slide,vertical']],
['type' => 'subheading', 'content' => '左侧幻灯片'],
['id' => 'slides', 'type' => 'group', 'label' => '幻灯片内容', 'item_label' => '幻灯片', 'max_items' => 30, 'min_items' => 1, 'default' => $combo_slides, 'fields' => $slide_fields, 'description' => '注意:当添加的幻灯片内容只有一个的时候,则不会以幻灯片的形式展示(不能滑动切换,相当于单个图片或视频)<div class="c-yellow">由于移动端多数浏览器不支持视频背景功能,所以移动端不会显示视频!</div>'],
['id' => 'option', 'type' => 'accordion', 'label' => '幻灯片设置', 'default' => ['button' => true, 'pagination' => true, 'effect' => 'slide', 'spacebetween' => 20, 'speed' => 0, 'interval' => 4, 'autoplay' => true, 'loop' => true], 'fields' => $combo_option],
['id' => 'covers', 'type' => 'group', 'label' => '右侧图文视频卡片', 'max_items' => 30, 'default' => array_fill(0, 4, ['image' => $asset_uri . 'user_t.jpg', 'title' => '']), 'fields' => [
['id' => 'image', 'type' => 'upload', 'label' => '图片背景', 'default' => '', 'library' => 'image'], ['id' => 'video', 'type' => 'upload', 'label' => '视频背景', 'default' => '', 'library' => 'video'], ['id' => 'hide', 'type' => 'radio', 'label' => '显示规则', 'default' => '', 'options' => ['' => '全部显示', 'pc' => 'PC端不显示', 'm' => '移动端不显示']], ['id' => 'title', 'type' => 'textarea', 'label' => '文字', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1]], ['id' => 'link', 'type' => 'link', 'label' => '跳转链接', 'default' => []],
]],
['id' => 'mask_opacity', 'type' => 'slider', 'label' => '遮罩透明度', 'default' => 0, 'min' => 0, 'max' => 90], ['id' => 'font_size_pc', 'type' => 'spinner', 'label' => 'PC端字体大小', 'default' => 16, 'min' => 10, 'max' => 80, 'step' => 2], ['id' => 'font_size_m', 'type' => 'spinner', 'label' => '移动端字体大小', 'default' => 14, 'min' => 10, 'max' => 80, 'step' => 2], ['id' => 'font_bold', 'type' => 'switcher', 'label' => '粗体显示', 'default' => false], ['id' => 'font_color', 'type' => 'color', 'label' => '文字颜色', 'default' => ''],
['type' => 'subheading', 'content' => '右侧图文视频卡片'],
['id' => 'covers', 'type' => 'group', 'label' => '右侧图文视频卡片', 'item_label' => '卡片', 'max_items' => 30, 'default' => array_fill(0, 4, ['image' => $asset_uri . 'user_t.jpg', 'title' => '']), 'fields' => self::cover_fields(), 'description' => '<div class="c-yellow">注意:由于移动端多数浏览器不支持视频背景功能,所以移动端不会显示视频!</div>'],
['type' => 'subheading', 'content' => '卡片样式配置'],
['id' => 'mask_opacity', 'type' => 'slider', 'label' => '遮罩透明度', 'default' => 0, 'min' => 0, 'max' => 90, 'step' => 1, 'unit' => '%', 'description' => '图片上显示的黑色遮罩层的透明度'],
['id' => 'font_size_pc', 'type' => 'spinner', 'label' => 'PC端字体大小', 'default' => 16, 'min' => 10, 'max' => 80, 'step' => 2, 'unit' => 'px'],
['id' => 'font_size_m', 'type' => 'spinner', 'label' => '移动端字体大小', 'default' => 14, 'min' => 10, 'max' => 80, 'step' => 2, 'unit' => 'px'],
['id' => 'font_bold', 'type' => 'switcher', 'label' => '粗体显示', 'default' => false],
['id' => 'font_color', 'type' => 'color', 'label' => '文字颜色', 'default' => ''],
];
}
return $fields;
@@ -447,6 +585,32 @@ final class WidgetSchemas {
];
}
/** 图文视频封面卡片单元(移动端不显示视频)。 */
private static function cover_fields(): array {
return [
['id' => 'image', 'type' => 'upload', 'label' => '图片背景', 'default' => '', 'library' => 'image'],
['id' => 'video', 'type' => 'upload', 'label' => '视频背景', 'default' => '', 'library' => 'video', 'description' => '(必填)图片背景、视频背景至少二选一,如果同时设置则PC端视频优先(PC端视频加载失败则显示图片),移动端只显示图片'],
['id' => 'hide', 'type' => 'radio', 'label' => '显示规则', 'default' => '', 'options' => ['' => '全部显示', 'pc' => 'PC端不显示', 'm' => '移动端不显示']],
['id' => 'title', 'type' => 'textarea', 'label' => '文字', 'default' => '', 'allow_html' => true, 'attributes' => ['rows' => 1], 'description' => '支持HTML代码'],
['id' => 'link', 'type' => 'link', 'label' => '跳转链接', 'default' => []],
];
}
private static function cta_palette(): array {
return ['' => '默认'] + self::text_palette();
}
private static function tag_palette(): array {
return ['' => '默认'] + self::zib_palette();
}
private static function text_palette(): array {
return [
'c-red' => '红色', 'c-red-2' => '深红', 'c-yellow' => '黄色', 'c-yellow-2' => '深黄', 'c-cyan' => '青色',
'c-blue' => '蓝色', 'c-blue-2' => '深蓝', 'c-green' => '绿色', 'c-green-2' => '深绿', 'c-purple' => '紫色', 'c-purple-2' => '深紫',
];
}
private static function card_fields(bool $link = false): array {
$fields = [['id' => 'title', 'type' => 'text', 'label' => '标题', 'default' => ''], ['id' => 'description', 'type' => 'textarea', 'label' => '说明', 'default' => '']];
if ($link) {
@@ -478,13 +642,12 @@ final class WidgetSchemas {
private static function notice_post_fields(): array {
return [
['id' => 'cat', 'type' => 'text', 'label' => '分类限制', 'default' => '', 'sanitize' => 'reference_ids'],
['id' => 'topics', 'type' => 'text', 'label' => '专题限制', 'default' => '', 'sanitize' => 'reference_ids'],
['id' => 'orderby', 'type' => 'select', 'label' => '排序方式', 'default' => '', 'options' => self::posts_orderby()],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '升序', 'asc' => '降序']],
['id' => 'order', 'type' => 'radio', 'label' => '顺序', 'default' => 'desc', 'options' => ['desc' => '降序', 'asc' => '升序']],
];
}
private static function pay_types(): array {
return ['' => '全部', 'reading' => '付费阅读', 'download' => '付费下载', 'gallery' => '付费图库', 'video' => '付费视频', 'vip' => 'VIP 专属'];
return ['1' => '付费阅读', '2' => '付费下载', '5' => '付费图片', '6' => '付费视频'];
}
}