根据 JSON 结构创建 WordPress 插件选项

前几天,我在想如何让 WordPress 插件选项由 JSON 文件控制,以便人们在将来更轻松地添加其他设置,而无需调整代码本身。

本文提供了一个极其简单的 WordPress 插件示例,其中包含一个由 2 个部分和 3 个字段/选项组成的单个设置页面。

完整代码可以在 Github 上找到。

设置基础

该插件最初由 3 个文件组成。

  • 冒险.json
  • 冒险.php
  • 类.adventures.php
  • `adventures.php` 包含一个基本的插件注册:

    带有空类的 `class.adventures.php`:

    `adventures.json` 包含插件设置的 JSON 结构:

    {
        "settings": {
            "pages": [
                {
                    "title": "Adventures",
                    "capability": "manage_options",
                    "slug": "adv"
                }
            ],
            "sections": [
                {
                    "id": "portal_base",
                    "title": "Base configuration",
                    "description": "Lorem 1, ipsum dolor sit amet consectetur adipisicing elit. Cumque nulla in officiis. Laborum quisquam illo eaque, deserunt facere mollitia sint doloremque maiores, obcaecati reiciendis voluptate itaque iure fugiat quia architecto!",
                    "view": "section"
                },
                {
                    "id": "portal_appearance",
                    "title": "Appearance",
                    "description": "Lorem 2, ipsum dolor sit amet consectetur adipisicing elit. Cumque nulla in officiis. Laborum quisquam illo eaque, deserunt facere mollitia sint doloremque maiores, obcaecati reiciendis voluptate itaque iure fugiat quia architecto!",
                    "view": "section"
                }
            ],
            "fields": [
                {
                    "id": "adv_portal_key",
                    "title": "Portal Key",
                    "section": "portal_base",
                    "type": "text",
                    "placeholder": "Enter your portal key",
                    "view": "field.text"
                },
                {
                    "id": "adv_api_host",
                    "title": "Host API",
                    "section": "portal_base",
                    "type": "text",
                    "placeholder": "Enter API host",
                    "default": "https://api.mortenhartvig.dk",
                    "view": "field.text"
                },
                {
                    "id": "adv_portal_theme",
                    "title": "Theme",
                    "section": "portal_appearance",
                    "type": "select",
                    "options": {
                        "rounded.v1": "Round (V1)",
                        "squared.v1": "Square (V1)",
                        "standard": "Standard"
                    },
                    "default": "standard",
                    "view": "field.select"
                }
            ]
        }
    }

    读取 JSON 数据

    为您的设置创建一个属性,并在“class.adventures.php”中调用“set_settings()”:

    private $settings;
    
    public function __construct() {
        $this->set_settings();
    }

    创建 `set_settings()` 和 `get_json_data()`:

    private function set_settings() {
        $data = $this->get_json_data();
    
        $this->settings = $data['settings'];
    }
    
    private function get_json_data() {
        $file = ADV__PLUGIN_DIR . 'adventures.json';
    
        if (!file_exists($file)) {
            die('adventures.json not found');
        }
    
        return json_decode(file_get_contents($file), true);
    }

    如果您在“__construct”中添加“die(print_r($this->settings))”,则可以确认您确实已加载设置。

    dump of settings

    设置页面

    从构造函数调用`init_hooks()`:

    public function __construct() {
        $this->set_settings();
        $this->init_hooks();
    }

    创建 `init_hooks()`:

    private function init_hooks() {
        add_action('admin_menu', [$this, 'register_settings_pages']);
    }

    创建“register_settings_pages()”和“settings_page_callback()”。

    public function register_settings_pages() {
        foreach ($this->settings['pages'] as $page) {
            add_options_page($page['title'], $page['title'], $page['capability'], $page['slug'], [$this, 'settings_page_callback']);    
        }
    }
    
    public function settings_page_callback() {
        $this->render('settings.php');
    }

    创建`render()`:

    private function render($filename, $args) {
        if (is_array($args)) {
            $value = get_option($args['id']);
    
            if (empty($value) && isset($args['default'])) {
                $value = $args['default'];
            }
    
            $args = array_merge($args, ['value' => $value]);
        }
    
        $file = ADV__PLUGIN_VIEW . $filename;
    
        if (!str_ends_with($file,'.php')) {
            $file .= '.php';
        }
    
        if(!file_exists($file)) {
            die('File not found ' . $filename);
        }
    
        require $file;
    }

    创建“views/settings.php”:

    Adventures

    Settings page with headline

    章节

    在 `init_hooks` 中添加另一个动作:

    private function init_hooks() {
        add_action('admin_menu', [$this, 'register_settings_pages']);
        add_action('admin_init', [$this, 'register_settings_sections']);
    }

    创建 `register_settings_sections()` 和 `settings_section_callback()`:

    public function register_settings_sections() {
        foreach ($this->settings['sections'] as $section) {
            add_settings_section($section['id'], $section['title'], [$this, 'settings_section_callback'], ADV__PLUGIN_SLUG, $section);
        }
    }
    
    public function settings_section_callback($args) {
        $this->render($args['view'], $args);
    }

    创建“views/section.php”:

    字段

    在 `init_hooks` 中添加第三个动作:

    private function init_hooks() {
        add_action('admin_menu', [$this, 'register_settings_pages']);
        add_action('admin_init', [$this, 'register_settings_sections']);
        add_action('admin_init', [$this, 'register_settings_fields']);
    }

    创建`register_settings_fields()`和`settings_field_callback()`:

    public function register_settings_fields() {
        foreach ($this->settings['fields'] as $field) {
            add_settings_field($field['id'], $field['title'], [$this, 'settings_field_callback'], ADV__PLUGIN_SLUG, $field['section'], $field);
    
            register_setting(ADV__PLUGIN_SLUG, $field['id']);
        }
    }
    
    public function settings_field_callback($args) {
        $this->render($args['view'], $args);
    }

    创建 `views/field.select.php`:

     $val) {
        $html_options .= sprintf('', $key, selected($args['value'], $key, false), $val);
    }
    
    printf('', $args['id'], $args['id'], $html_options);

    创建“views/field.text.php”:

    ', 
    $args['id'], $args['id'], $args['value'], $args['placeholder']);

    保存

    要查看和保存您的选项,请向“settings.php”添加一个表单:

    Adventures

    更改一个选项并尝试。保存应该会成功。

    Settings successfully saved

    您的设置现已保存,可通过以下方式在整个网站访问:

    添加新字段

    将以下 JSON 添加到 `adventures.json`:

    {
        "id": "adv_api_token",
        "title": "Host API Token",
        "section": "portal_base",
        "type": "text",
        "placeholder": "Enter API host token",
        "default": "",
        "view": "field.text"
    }

    它将自动添加到您的设置中:

    added host api token