feat(widgets): render icon fields with the universal icon picker

The widget FormRenderer icon case and the nav-menu item icon field now
emit the shared picker (preview + choose/clear + editable text input,
delegated events so lazy forms and repeater rows work). Icon values are
sanitized through aksrt_sanitize_icon_value on both save paths so inline
customsvg- markup survives; the widget admin screen enqueues the picker.
This commit is contained in:
kate522 committed 2026-09-06 12:59:12 +08:00
1 parent f629a4f373
commit 009f9874c0
6 files changed
+30 -20

No files matched your search

-1
View File
@@ -86,7 +86,6 @@
} }
.aksrt-widget-number, .aksrt-widget-number,
.aksrt-widget-icon,
.aksrt-widget-link, .aksrt-widget-link,
.aksrt-widget-background { .aksrt-widget-background {
display: grid; display: grid;
+20 -16
View File
@@ -21,18 +21,18 @@ class NavMenuOptions {
if ($hook !== 'nav-menus.php') { if ($hook !== 'nav-menus.php') {
return; return;
} }
$path = get_template_directory() . '/assets/js/admin-nav-menu-senior.js';
if (!file_exists($path)) {
return;
}
wp_enqueue_media(); wp_enqueue_media();
wp_enqueue_script( aksrt_icon_picker_assets();
'aksrt-admin-nav-menu-senior', $path = get_template_directory() . '/assets/js/admin-nav-menu-senior.js';
get_template_directory_uri() . '/assets/js/admin-nav-menu-senior.js', if (file_exists($path)) {
['jquery'], wp_enqueue_script(
(string) filemtime($path), 'aksrt-admin-nav-menu-senior',
true get_template_directory_uri() . '/assets/js/admin-nav-menu-senior.js',
); ['jquery'],
(string) filemtime($path),
true
);
}
} }
/** /**
@@ -57,11 +57,15 @@ class NavMenuOptions {
?> ?>
<p class="field-aksrt-icon description description-wide"> <p class="field-aksrt-icon description description-wide">
<label for="edit-menu-item-aksrt-icon-<?php echo esc_attr((string) $item_id); ?>"> <label for="edit-menu-item-aksrt-icon-<?php echo esc_attr((string) $item_id); ?>">
<?php esc_html_e('图标 class(如 fa fas fa-home)', 'aksrt'); ?><br> <?php esc_html_e('图标', 'aksrt'); ?>
<input type="text" id="edit-menu-item-aksrt-icon-<?php echo esc_attr((string) $item_id); ?>"
class="widefat" name="aksrt_menu_options[<?php echo esc_attr((string) $item_id); ?>][icon]"
value="<?php echo esc_attr($icon); ?>">
</label> </label>
<?php
echo aksrt_icon_picker_field(
sprintf('aksrt_menu_options[%d][icon]', $item_id),
sprintf('edit-menu-item-aksrt-icon-%d', $item_id),
$icon
);
?>
</p> </p>
<p class="field-aksrt-badge description description-thin"> <p class="field-aksrt-badge description description-thin">
<label for="edit-menu-item-aksrt-badge-<?php echo esc_attr((string) $item_id); ?>"> <label for="edit-menu-item-aksrt-badge-<?php echo esc_attr((string) $item_id); ?>">
@@ -127,7 +131,7 @@ class NavMenuOptions {
$raw = wp_unslash($_POST['aksrt_menu_options'][ $menu_item_db_id ]); $raw = wp_unslash($_POST['aksrt_menu_options'][ $menu_item_db_id ]);
$clean = [ $clean = [
'icon' => sanitize_text_field((string) ($raw['icon'] ?? '')), 'icon' => aksrt_sanitize_icon_value((string) ($raw['icon'] ?? '')),
'badge' => sanitize_text_field((string) ($raw['badge'] ?? '')), 'badge' => sanitize_text_field((string) ($raw['badge'] ?? '')),
'badge_class' => sanitize_html_class((string) ($raw['badge_class'] ?? '')), 'badge_class' => sanitize_html_class((string) ($raw['badge_class'] ?? '')),
'submenu_s' => !empty($raw['submenu_s']), 'submenu_s' => !empty($raw['submenu_s']),
+5 -1
View File
@@ -802,6 +802,10 @@ class SchemaProvider {
} }
} }
return $out; return $out;
case 'icon':
return function_exists('aksrt_sanitize_icon_value')
? aksrt_sanitize_icon_value((string) $value)
: sanitize_text_field((string) $value);
default: default:
return sanitize_text_field((string) $value); return sanitize_text_field((string) $value);
} }
@@ -993,7 +997,7 @@ class SchemaProvider {
// 自定义面板(验证码服务商等)按对象存储 // 自定义面板(验证码服务商等)按对象存储
'custom' => 'array', 'custom' => 'array',
'color' => 'string', 'color' => 'string',
'icon' => 'string', 'icon' => 'icon',
'media' => 'url', 'media' => 'url',
'upload' => 'url', 'upload' => 'url',
'gallery' => 'attachment_ids', 'gallery' => 'attachment_ids',
+1
View File
@@ -28,6 +28,7 @@ final class AdminFormController {
wp_enqueue_script('jquery-ui-sortable'); wp_enqueue_script('jquery-ui-sortable');
wp_enqueue_style('aksrt-widget-admin', AKSRT_URI . '/assets/widgets/admin.css', ['wp-color-picker'], AKSRT_VERSION); wp_enqueue_style('aksrt-widget-admin', AKSRT_URI . '/assets/widgets/admin.css', ['wp-color-picker'], AKSRT_VERSION);
wp_enqueue_style('aksrt-widget-preview', AKSRT_URI . '/assets/widgets/frontend.css', [], AKSRT_VERSION); wp_enqueue_style('aksrt-widget-preview', AKSRT_URI . '/assets/widgets/frontend.css', [], AKSRT_VERSION);
aksrt_icon_picker_assets(['wp-color-picker']);
wp_enqueue_script('aksrt-widget-admin-core', AKSRT_URI . '/assets/widgets/admin-core.js', [], AKSRT_VERSION, true); wp_enqueue_script('aksrt-widget-admin-core', AKSRT_URI . '/assets/widgets/admin-core.js', [], AKSRT_VERSION, true);
wp_enqueue_script('aksrt-widget-admin', AKSRT_URI . '/assets/widgets/admin.js', ['jquery', 'jquery-ui-sortable', 'wp-color-picker', 'aksrt-widget-admin-core'], AKSRT_VERSION, true); wp_enqueue_script('aksrt-widget-admin', AKSRT_URI . '/assets/widgets/admin.js', ['jquery', 'jquery-ui-sortable', 'wp-color-picker', 'aksrt-widget-admin-core'], AKSRT_VERSION, true);
wp_localize_script('aksrt-widget-admin', 'aksrtWidgetAdmin', [ wp_localize_script('aksrt-widget-admin', 'aksrtWidgetAdmin', [
+3 -1
View File
@@ -81,7 +81,9 @@ final class FieldSchema {
case 'color': case 'color':
return self::color((string) $value); return self::color((string) $value);
case 'icon': case 'icon':
return sanitize_text_field((string) $value); return function_exists('aksrt_sanitize_icon_value')
? aksrt_sanitize_icon_value((string) $value)
: sanitize_text_field((string) $value);
case 'textarea': case 'textarea':
return !empty($field['allow_html']) ? wp_kses_post((string) $value) : sanitize_textarea_field((string) $value); return !empty($field['allow_html']) ? wp_kses_post((string) $value) : sanitize_textarea_field((string) $value);
case 'text': case 'text':
+1 -1
View File
@@ -79,7 +79,7 @@ final class FormRenderer {
echo '<input class="widefat aksrt-widget-color" type="text" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_name) . '" value="' . esc_attr((string) $value) . '">'; echo '<input class="widefat aksrt-widget-color" type="text" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_name) . '" value="' . esc_attr((string) $value) . '">';
break; break;
case 'icon': case 'icon':
echo '<div class="aksrt-widget-icon"><i class="' . esc_attr((string) $value) . '" aria-hidden="true"></i><input class="widefat" type="text" id="' . esc_attr($field_id) . '" name="' . esc_attr($field_name) . '" value="' . esc_attr((string) $value) . '" placeholder="fa fas fa-star"></div>'; echo aksrt_icon_picker_field($field_name, $field_id, (string) $value);
break; break;
case 'link': case 'link':
self::link($widget, $key, is_array($value) ? $value : []); self::link($widget, $key, is_array($value) ? $value : []);