Where to store plugin settings fields

The question:

I am developing plugin right now, and I have one questions about best practices and conventions.

What I need ?

My plugin is going to store some predefined object, list of objects (or just arrays/key-value pairs) and it will be possible to add new object and fill its fields.
For example my object will have following content

{
  "id": 123,
  "url": "http://google.com/",
  "enabled" : true,
  "name": "hello_world",
  "api_key" : "api_key"
}

Simple JSON object.

And on Plugin Admin configuration page it will be possible to add, edit or remove such objects.

What is my question ?

What is the best way of storing such data. I have installed a lot of different plugins in order to see how does custom data from settings is stored. There some options I have seen

  1. Using Settings API provided by WordPress. Even UI is handled by wordpress, you can just call the function and it will create proper input field and than save all settings into options table. All checks and security is handled by wordpress as well. But is it possible to create dynamic admin page where you can add new items ?

  2. Using old Options API is also stored in the options table, but gives more freedom to developer to handle all validation.

  3. Creating new database table and save data in it.

I don’t think I am going to use third method.

Please suggest better way to do this or maybe you know the plugin already implemented such functionality in a right way. I would grateful for any help.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

It depends on how you are going to use the stored data.

If you want to run complex queries against the values, use a custom table with indexes optimized for those queries.

If you will always just fetch all the values for a given object, create a non-public custom post type, and store the data as post meta.

Do not store the data in a serialized string, like the options API does it. This is a nightmare when you want to change it per command line SQL, because the serialized format is PHP specific.

The “Settings API” imposes some very outdated markup, and the code for the registration and storage is rather counter-intuitive. I wouldn’t recommend to use it.

Method 2

Where to store plugin settings fields?

Options table FTW. It’s cached and easy to do CRUD.

Settings API or Options API?

Basically, you can use Options API without Settings API but you cannot use Settings API without Options API. Even when you just need to add some fields to a existing WordPress page, you still need get_option() to retrieve data for your view template.

But by using a existing WordPress page, your data will be fragmented and hard to retrieve/maintain because it’s stored with different option_name. It might confuse end-users as well.

When using Options API only, as the author of the plugin, you can add news sections/fields whenever you want but other people can’t. Because view template is hardcoded without hooks which work like do_settings_sections() and do_settings_fields(). Of course, you can you use do_action() but it’s will be much more complicated.

Using Options API gives more freedom to developer to handle all validation is incorrect. Settings API has sanitize_callback which also allow developer to do whatever they want with input data.

So, why don’t use both of them?

For example, let say a setting page using both Settings API and Options API with option_group is my_app_group and option_name is my_app:

$options = get_option('my_app');

?><div class="wrap">
    <h1><?= __('Plugin Settings', 'textdomain') ?></h1>
    <form class="form-table" method="post" action="options.php">
        <?php settings_fields('my_app_group') ?>
        <table>
            <tr>
                <td>
                    <label for="my_app[name]">
                        <?= __('App Name', 'textdomain') ?>
                    </label>
                </td>
                <td>
                    <input type="text" name="my_app[name]" value="<?= $options['name'] ?>">
                </td>
            </tr>
            <tr>
                <td>
                    <label for="my_app[app_key]">
                        <?= __('App Key', 'textdomain') ?>
                    </label>
                </td>
                <td>
                    <input type="text" name="my_app[app_key]" value="<?= $options['app_key'] ?>">
                </td>
            </tr>
            <?php do_settings_fields('my_app_group', 'default') ?>
        </table>
        <?php do_settings_sections('my_app_group') ?>
        <?php submit_button() ?>
    </form>
</div><?php

Now, all data is stored in options table under my_app option name then it’s easy to retrieve/maintain. Other developers can also add new sections/fields to your plugin too.

Method 3

  1. Yes
  2. this is actually the same as point 1, just without the helpers

  3. Now this depends on how you want to use your setting. The instinct is that at 99% of the cases this will just add unneeded complexity to your code and hurt performance.

As long as we are talking about setting and not content or widgets, the settings API is what you should use. It takes some time to get used to it, but it doesn’t impose any limitation on the type of GUI or settings structure you can have. Whatever you can do with a html form you can also do with the settings API.

But wait, there is an alternative, and that is to use the customizer. If your settings have front end implications you should consider using it


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment