自留地
切勿乱来!
     找回密码     哈林摇

WordPress Options Framework 1.9.0增加自增多参数表单(动态表单)

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');

显示效果

WordPress Options Framework 1.9.0增加自增多参数表单

使用方法

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里的幻灯轮播都改成了这种形式了

1 收藏 打赏
×
版权声明:本文采用知识共享 署名4.0国际许可协议 [BY-NC-SA] 进行授权
文章名称:《WordPress Options Framework 1.9.0增加自增多参数表单(动态表单)》
文章链接:https://www.ediok.cn/blog/2026/03/6651.html
本站资源仅供个人学习交流,请于下载后24小时内删除,不允许用于商业用途,否则法律问题自行承担。
分享到

评论 抢沙发

评论前必须登录!

 

关注互联网发展前沿,关注PHPCMS技术演进,钻研PHPCMS技术开发

问答社区 联系我们
后退
Alt+←
前进
Alt+→
刷新
F5
无法复制?

登录

登录即表示同意本站用户协议隐私政策
©2026 周涛博客 All rights reserved

注册

注册即表示同意本站用户协议隐私政策
©2026 周涛博客 All rights reserved

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

微信扫一扫

微信扫一扫