feat(路由显示): 添加路由匹配模式设置和功能实现

新增路由显示模式选项,支持首页显示、全站显示和URL路径匹配三种模式
在路径匹配模式下,可以通过规则列表配置需要显示雪花的URL路径
更新翻译文件和版本号至1.9.0
This commit is contained in:
tikkhun 2025-12-13 10:19:47 +08:00
parent 4698c4d793
commit 6618f67be2
4 changed files with 204 additions and 4 deletions

Binary file not shown.

View File

@ -128,8 +128,8 @@ msgid "Weight controls relative probability Weight is a non negative integer Wei
msgstr "权重用于控制随机生成的相对概率 权重为非负整数 权重为 0 表示禁用 某形状概率等于其权重除以所有形状权重之和 例如 dot 1 flake 4 flake 概率约为 dot 的四倍"
# Other settings
msgid "Home Display Duration Seconds"
msgstr "首页显示时长 秒"
msgid "Display Duration Seconds"
msgstr "显示时长 秒"
msgid "Duration in seconds for snow on home 0 means infinite"
msgstr "首页雪花显示时长 单位秒 0 表示无限"
@ -166,3 +166,28 @@ msgstr "水平摆动幅度基值在最小与最大之间随机 应用偏移缩
msgid "Select images or SVG"
msgstr "选择图片或 SVG"
# Route display mode
msgid "Display Routes Mode"
msgstr "显示路由模式"
msgid "Home"
msgstr "首页"
msgid "All Pages"
msgstr "所有页面"
msgid "Match URL Path"
msgstr "匹配 URL 路径"
msgid "Default Home Only choose All Pages to enable globally choose Match URL Path to enable only for matched routes"
msgstr "默认仅首页显示 选择所有页面开启全站显示 选择匹配 URL 路径仅在匹配的路径显示"
msgid "Match Routes"
msgstr "匹配规则"
msgid "One rule per line compare against request path example exact path /about prefix match with trailing star /blog/*"
msgstr "每行一条规则 与请求路径比较 例如精确路径 /about 前缀匹配可使用尾部星号 /blog/*"
msgid "Example /about\n/blog/*\n/shop"
msgstr "示例 /about\n/blog/*\n/shop"

78
readme.txt Normal file
View File

@ -0,0 +1,78 @@
=== Yoone Snow ===
Contributors: yoone
Tags: snow, snowfall, christmas, effects, canvas
Requires at least: 5.6
Tested up to: 6.6
Requires PHP: 7.4
Stable tag: 1.1.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
== Description ==
Yoone Snow 是一个在站点页面顶部绘制雪花效果的插件 使用 canvas 在前端生成不同形状的飘落元素 并提供后台设置页面进行配置 支持默认形状 emoji 字符 媒体图片以及文本作为雪花元素 每个元素都可以单独设置权重用来控制出现概率 插件同时提供尺寸范围 漂移速度范围 摆动幅度范围 最大在屏数量和首页显示时长等参数 便于在性能和效果之间做平衡
主要特性
- 形状类型支持 dot flake yuanbao coin santa hat candy cane christmas sock christmas tree reindeer christmas berry
- 支持添加 emoji 作为雪花元素 支持别名搜索与直接输入
- 支持添加媒体图片包括普通图片和 SVG 作为雪花元素
- 支持文本元素作为雪花元素
- 每类元素支持权重设置 权重为非负整数 权重为 0 时禁用该元素
- 提供尺寸范围 漂移速度范围 摆动幅度范围 最大在屏数量和首页显示时长等设置
- 后台形状选择下拉带内嵌预览 每项左侧显示绘制图案 便于直观选择
== Installation ==
手动安装
- 将插件文件夹上传到 `wp-content/plugins` 目录
- 在后台插件页面启用 Yoone Snow 插件
- 打开后台 `Settings -> Yoone Snow` 进入设置页进行配置
== Usage ==
- 在设置页的 Shapes 字段卡片区域管理所有雪花元素 支持 Default Emoji Media Text 四种类型
- Default 类型下可从下拉内嵌列表选择默认形状 左侧有图案预览 点击后会添加到下方卡片列表
- Emoji 类型可通过别名下拉或直接输入字符加入元素 别名示例 snow tree bell 等
- Media 类型通过按钮从媒体库选择图片或 SVG 并加入元素列表
- Text 类型输入文本并加入元素列表
- 每个元素卡片包含一个权重输入框 权重为非负整数 非法值会在保存时被矫正
== Settings ==
- Shapes 卡片列表 管理默认形状 emoji 媒体和文本元素 每个元素支持权重输入
- Display Duration Seconds 主页显示时长 单位秒 0 表示无限
- Max Snowflakes On Screen 在屏最大数量 0 表示根据视口面积自动控制 上限为 1000
- Snow Size 最小与最大半径 随机范围 在前端根据此范围生成不同尺寸
- Drift Speed Random Range 垂直漂移速度的随机范围 控制落下速度基线
- Swing Amplitude Random Range 水平摆动幅度随机范围 控制左右摆动基线
== FAQ ==
问 如何控制某个形状出现概率
答 在对应形状卡片的权重输入框设置权重 权重越大出现概率越高 权重为 0 时禁用该形状
问 如何添加自定义图片或 SVG 作为雪花
答 在 Media 面板点击 Add Images 按钮 从媒体库选择图片或 SVG 将自动添加到卡片列表并可设置权重
问 Emoji 如何快速添加
答 在 Emoji 面板通过下拉选择常用别名或在输入框中直接输入 emoji 字符 支持别名搜索和粘贴识别
问 性能如何设置
答 通过 Max Snowflakes On Screen 限制在屏数量 通过尺寸 漂移和摆动范围控制动画强度 如需更节省资源可调小上限与范围值
== Screenshots ==
1 设置页形状选择下拉内嵌预览示例
2 元素卡片列表与权重输入示例
3 媒体元素与 emoji 元素示例
== Changelog ==
= 1.1.0 =
- 增加形状选择下拉内嵌预览 每项左侧显示图案
- 将权重输入整合到卡片列表中 支持默认形状 emoji 媒体和文本
- 增强后台交互 包括 emoji 别名选择与建议列表 媒体多选以及文本快速添加
= 1.0.0 =
- 初始版本 支持基础雪花效果与默认形状选择
== Upgrade Notice ==
= 1.1.0 =
升级后请在设置页检查各元素权重与在屏最大数量 以确保性能与效果符合预期
== Localization ==
- 文本域为 `yoone-snow` 插件已加载本地化文本 可在 `languages` 目录提供翻译文件

View File

@ -2,13 +2,44 @@
/*
Plugin Name: Yoone Snow
Description: 首页 canvas 雪花效果
Version: 1.7.0
Version: 1.9.0
Author: Yoone
*/
if (!defined('ABSPATH')) { exit; }
function yoone_snow_is_enabled() {
$mode = get_option('yoone_snow_display_routes_mode', 'home');
if ($mode === 'all') {
return true;
}
if ($mode === 'match') {
$routes = get_option('yoone_snow_display_routes', array());
if (is_string($routes)) {
$routes = array_filter(array_map('trim', explode("\n", $routes)));
}
if (!is_array($routes)) {
$routes = array();
}
$requestUri = isset($_SERVER['REQUEST_URI']) ? (string)$_SERVER['REQUEST_URI'] : '';
$path = parse_url($requestUri, PHP_URL_PATH);
$path = is_string($path) ? $path : '';
foreach ($routes as $rule) {
$r = trim((string)$rule);
if ($r === '') { continue; }
if (substr($r, -1) === '*') {
$prefix = substr($r, 0, -1);
if ($prefix === '' || strpos($path, $prefix) === 0) {
return true;
}
} else {
if ($path === $r) {
return true;
}
}
}
return false;
}
return function_exists('is_front_page') ? is_front_page() : false;
}
@ -64,6 +95,14 @@ function yoone_snow_enqueue_assets() {
$script_ver = @filemtime(plugin_dir_path(__FILE__) . 'js/snow-canvas.js');
$deps = array($shape_index_handle);
$needs_utils = false;
$mixed_items_option = get_option('yoone_snow_mixed_items', array('dot','flake'));
if (is_string($mixed_items_option)) {
$mixed_items_option = array_filter(array_map('trim', explode(',', $mixed_items_option)));
}
$allowed_shapes = array('dot','flake','yuanbao','coin','santa_hat','candy_cane','christmas_sock','christmas_tree','reindeer','christmas_berry');
$mixed_items_sanitized = array_values(array_unique(array_intersect(is_array($mixed_items_option) ? $mixed_items_option : array('dot','flake'), $allowed_shapes)));
if (empty($mixed_items_sanitized)) { $mixed_items_sanitized = array('dot','flake'); }
$media_urls = array();
foreach ($mixed_items_sanitized as $key) {
if ($key === 'dot') { $deps[] = $shape_dot_handle; }
if ($key === 'flake') { $deps[] = $shape_flake_handle; }
@ -726,7 +765,7 @@ function yoone_snow_register_settings() {
// 添加首页显示时长字段 输入为数字最小值为 0
add_settings_field(
'yoone_snow_home_duration',
esc_html__('Home Display Duration Seconds', 'yoone-snow'),
esc_html__('Display Duration Seconds', 'yoone-snow'),
function() {
// 读取当前设置值 并渲染数字输入框
$current = intval(get_option('yoone_snow_home_duration', 0));
@ -861,6 +900,64 @@ function yoone_snow_register_settings() {
'yoone_snow',
'yoone_snow_section'
);
// 路由显示模式设置
register_setting('yoone_snow_options', 'yoone_snow_display_routes_mode', array(
'type' => 'string',
'sanitize_callback' => function($value) {
$val = strtolower(trim((string)$value));
$allowed = array('home','all','match');
return in_array($val, $allowed, true) ? $val : 'home';
},
'default' => 'home',
));
add_settings_field(
'yoone_snow_display_routes_mode',
esc_html__('Display Routes Mode', 'yoone-snow'),
function() {
$current = get_option('yoone_snow_display_routes_mode', 'home');
echo '<label style="margin-right:12px;"><input type="radio" name="yoone_snow_display_routes_mode" value="home" ' . checked($current, 'home', false) . ' /> ' . esc_html__('Home', 'yoone-snow') . '</label>';
echo '<label style="margin-right:12px;"><input type="radio" name="yoone_snow_display_routes_mode" value="all" ' . checked($current, 'all', false) . ' /> ' . esc_html__('All Pages', 'yoone-snow') . '</label>';
echo '<label><input type="radio" name="yoone_snow_display_routes_mode" value="match" ' . checked($current, 'match', false) . ' /> ' . esc_html__('Match URL Path', 'yoone-snow') . '</label>';
echo '<p class="description">' . esc_html__('Default Home Only choose All Pages to enable globally choose Match URL Path to enable only for matched routes', 'yoone-snow') . '</p>';
},
'yoone_snow',
'yoone_snow_section'
);
// 路由匹配规则列表设置
register_setting('yoone_snow_options', 'yoone_snow_display_routes', array(
'type' => 'array',
'sanitize_callback' => function($value) {
if (is_string($value)) {
$value = preg_split('/\\r?\\n/', $value);
}
if (!is_array($value)) { $value = array(); }
$out = array();
foreach ($value as $item) {
$s = trim((string)$item);
if ($s !== '') { $out[] = $s; }
}
return array_values(array_unique($out));
},
'default' => array(),
));
add_settings_field(
'yoone_snow_display_routes',
esc_html__('Match Routes', 'yoone-snow'),
function() {
$current = get_option('yoone_snow_display_routes', array());
if (is_string($current)) {
$current = preg_split('/\\r?\\n/', $current);
}
if (!is_array($current)) { $current = array(); }
$text = implode("\n", array_map('strval', $current));
$placeholder = esc_attr__("Example /about\n/blog/*\n/shop", 'yoone-snow');
echo '<textarea name="yoone_snow_display_routes" rows="6" style="width:420px;" placeholder="' . $placeholder . '">' . esc_textarea($text) . '</textarea>';
echo '<p class="description">' . esc_html__('One rule per line compare against request path example exact path /about prefix match with trailing star /blog/*', 'yoone-snow') . '</p>';
},
'yoone_snow',
'yoone_snow_section'
);
}
// 添加设置页面到后台菜单 条目在设置菜单下