DUX主题使用的管理插件 Options Framework 1.9.0太老了,大多数添加的选项都属于一行需要配置一个,当遇到多参数的,想随意增加的,就困难了,比如DUX主题原本自带的幻灯片管理、通栏轮换图管理,作者都是固定写死了5个,扩展起来实在太麻烦了,特别最近搞多语言翻译插件整合到主题里,增加语言这就实在没招了,所以就打算二开这个Options Framework,过程很痛苦,但结局很美好,写一篇记录一下以备后用
首先第一部分,增加单独的一个自增多参数表单类型,因为我基于翻译搞的,所以起名为:translate
涉及文件:/includes/class-options-interface.php
在static function optionsframework_fields函数里找到
case "xxx":
....code....
break;
这样的代码块,在其下面增加一个新的case:
case 'translate':
unset($name, $code, $icon);
$translate_items = !empty($val) && is_array($val) ? $val : array(array(
'name' => '',
'code' => '',
'icon' => ''
));
$output .= '<div class="of-translate-repeater" data-repeater-name="' . esc_attr($option_name . '[' . $value['id'] . ']') . '">';
foreach ($translate_items as $index => $item) {
$output .= '<div class="of-translate-item repeater-item">';
$output .= '<div class="of-translate-fields">';
$output .= '<div class="of-translate-field">';
$output .= '<label>名称</label>';
$output .= '<input type="text"
name="' . esc_attr($option_name . '[' . $value['id'] . '][' . $index . '][name]') . '"
value="' . esc_attr(!empty($item['name']) ? $item['name'] : '') . '"
placeholder="' . esc_attr__('输入名称', 'options-framework') . '"
class="of-input" />';
$output .= '</div>';
$output .= '<div class="of-translate-field">';
$output .= '<label>代码</label>';
$output .= '<input type="text"
name="' . esc_attr($option_name . '[' . $value['id'] . '][' . $index . '][code]') . '"
value="' . esc_attr(!empty($item['code']) ? $item['code'] : '') . '"
placeholder="' . esc_attr__('输入代码', 'options-framework') . '"
class="of-input" />';
$output .= '</div>';
$output .= '<div class="of-translate-field">';
$output .= '<label>图标</label>';
$output .= '<input type="text"
name="' . esc_attr($option_name . '[' . $value['id'] . '][' . $index . '][icon]') . '"
value="' . esc_attr(!empty($item['icon']) ? $item['icon'] : '') . '"
placeholder="' . esc_attr__('输入图标代码', 'options-framework') . '"
class="of-input" />';
$output .= '</div>';
$output .= '</div>';
$output .= '<div class="of-translate-actions">';
$output .= '<button type="button" class="button of-remove-item" title="' . esc_attr__('删除', 'options-framework') . '">×</button>';
$output .= '</div>';
$output .= '</div>';
}
$output .= '<div class="of-translate-add">';
$output .= '<button type="button" class="button of-add-item">' . esc_html__('添加新项目', 'options-framework') . '</button>';
$output .= '</div>';
$output .= '<script type="text/template" class="of-translate-template">';
$output .= '<div class="of-translate-item repeater-item">';
$output .= '<div class="of-translate-fields">';
$output .= '<div class="of-translate-field">';
$output .= '<label>名称</label>';
$output .= '<input type="text"
name="' . esc_attr($option_name . '[' . $value['id'] . '][{{index}}][name]') . '"
value=""
placeholder="' . esc_attr__('输入名称', 'options-framework') . '"
class="of-input" />';
$output .= '</div>';
$output .= '<div class="of-translate-field">';
$output .= '<label>代码</label>';
$output .= '<input type="text"
name="' . esc_attr($option_name . '[' . $value['id'] . '][{{index}}][code]') . '"
value=""
placeholder="' . esc_attr__('输入代码', 'options-framework') . '"
class="of-input" />';
$output .= '</div>';
$output .= '<div class="of-translate-field">';
$output .= '<label>图标</label>';
$output .= '<input type="text"
name="' . esc_attr($option_name . '[' . $value['id'] . '][{{index}}][icon]') . '"
value=""
placeholder="' . esc_attr__('输入图标代码', 'options-framework') . '"
class="of-input" />';
$output .= '</div>';
$output .= '</div>';
$output .= '<div class="of-translate-actions">';
$output .= '<button type="button" class="button of-remove-item" title="' . esc_attr__('删除', 'options-framework') . '">×</button>';
$output .= '</div>';
$output .= '</div>';
$output .= '</script>';
$output .= '</div>';
break;
这最终是在配置options.php里要调用的,使用方法很简单
$options[] = array(
'name' => __('语言选择', 'haoui'),
'id' => 'translate_sort',
'std' => '',
'class' => 'mini',
'desc' => __('默认为空时不开启,填写则开启', 'haoui'),
'type' => 'translate');
type使用translate即可
现在只是创建了表单,接下来要进行数据写入的配置,涉及文件:/includes/class-options-sanitization.php
合适的位置增加:
代码块为隐藏内容,解锁需要先评论本文
评论后刷新解锁
这一块是对数据写入验证处理,涉及到上一步表单里三个input ID,分别是翻译所使用的name、code、icon,可以自己增加所需要的
接下来就是样式表css,涉及文件:/css/optionsframework.css
增加表单的样式表:
.of-translate-repeater {
margin: 10px 0;
}
.of-translate-item {
background: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
margin-bottom: 10px;
position: relative;
display: flex;
align-items: flex-start;
}
.of-translate-fields {
flex: 1;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.of-translate-field {
flex: 1;
min-width: 200px;
}
.of-translate-field label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #333;
font-size: 12px;
}
.of-translate-field input {
width: 100%;
}
.of-translate-actions {
width: 30px;
text-align: right;
padding-left: 10px;
}
.of-remove-item {
background: none !important;
border: none !important;
color: #a00 !important;
cursor: pointer;
font-size: 20px !important;
padding: 0 !important;
width: auto !important;
height: auto !important;
line-height: 1 !important;
box-shadow: none !important;
}
.of-remove-item:hover {
color: #dc3232 !important;
}
.of-add-item {
margin-top: 10px !important;
}
.of-translate-template {
display: none;
}
@media (max-width: 782px) {
.of-translate-item {
flex-direction: column;
}
.of-translate-fields {
width: 100%;
margin-bottom: 10px;
}
.of-translate-actions {
width: 100%;
text-align: left;
padding-left: 0;
}
}
新增项目,删除项目,使用到的交互JS,涉及文件:/js/options-custom.js
里面最后一行});下面增加一个:
jQuery(document).ready(function($) {
// 初始化可重复字段
$('.of-translate-repeater').each(function() {
var $repeater = $(this);
var template = $repeater.find('.of-translate-template').html();
// 添加新项目
$repeater.on('click', '.of-add-item', function(e) {
e.preventDefault();
var $items = $repeater.find('.of-translate-item:not(.of-translate-template)');
var index = $items.length;
// 替换模板中的占位符
var newItem = template.replace(/{{index}}/g, index);
$repeater.find('.of-translate-add').before(newItem);
});
// 删除项目
$repeater.on('click', '.of-remove-item', function(e) {
e.preventDefault();
var $item = $(this).closest('.of-translate-item');
// 如果有多个项目,允许删除
var $items = $repeater.find('.of-translate-item:not(.of-translate-template)');
if ($items.length > 1) {
$item.remove();
// 重新索引剩余项目
$repeater.find('.of-translate-item:not(.of-translate-template)').each(function(i) {
$(this).find('input').each(function() {
var name = $(this).attr('name');
if (name) {
var newName = name.replace(/\[\d+\]/, '[' + i + ']');
$(this).attr('name', newName);
}
});
});
} else {
// 如果只有一个项目,清空其值而不是删除
$item.find('input').val('');
}
});
});
});
使用方法
options.php里增加字段,type类型使用translate,如
$options[] = array(
'name' => __('语言选择', 'haoui'),
'id' => 'translate_sort',
'std' => '',
'class' => 'mini',
'desc' => __('默认为空时不开启,填写则开启', 'haoui'),
'type' => 'translate');
显示效果

使用方法
DUX主题里使用_hui('id');调用,比如_hui('translate_sort');
但是,因为储存的是数组,所以要对_hui('translate_sort')进行foreach循环,同样以翻译示例
$langs = _hui('translate_sort');
if (empty($langs)) {
return '<li class="menu-item"><span class="ignore" style="display:block;padding:8px 12px;opacity:.7;">未配置语言</span></li>';
}
$items = [];
foreach ($langs as $lang) {
$name = esc_html($lang['name']);
$code = esc_attr($lang['code']);
$icon = !empty($lang['icon']) ? '<i class="ediok icon-'.esc_html($lang['icon']).'" style="width:20px;height:15px;vertical-align:middle;margin-right:8px;" class="ignore"></i> ' : '';
$items[] = '<li class="menu-item menu-item-type-custom menu-item-object-custom"><a href="javascript:translate.changeLanguage(\'' . $code . '\');" class="ignore">' . $icon . $name . '</a></li>';
}
return '<ul style="list-style:none;padding:0;margin:0;display:flex;gap:15px;flex-wrap:wrap;justify-content:center;">' . implode("\n", $items) . '</ul>';
目前基于这个扩展,我把DUX里的幻灯轮播都改成了这种形式了
周涛博客








评论前必须登录!
注册