12

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.

2
  • 1
    Did you already think about using custom post types and post_meta fields? So you could handle list views, add items, remove items, ...
    – Hannes
    Commented Jun 11, 2016 at 9:45
  • @Hannes thanks for reply, but I thinks this will be redundant in this case because amount of custom items are relatively fixed and probably won't be more than 20.
    – CROSP
    Commented Jun 11, 2016 at 11:25

3 Answers 3

10

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.

4
  • 1
    Thanks for answer, does this make sense in case of elements count less or equal 20, usually aprox. 5 items will be used ,so I don't think creating separate table is necessary.
    – CROSP
    Commented Jun 11, 2016 at 13:12
  • Do you mean 5 objects or 5 object members?
    – fuxia
    Commented Jun 11, 2016 at 13:15
  • I mean 5 objects (as I described in my question) will only used usually, because a lot of objects won't fit on the page.
    – CROSP
    Commented Jun 11, 2016 at 13:59
  • 3
    Then it might be easier to store them in options.
    – fuxia
    Commented Jun 11, 2016 at 14:33
5

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.

2
  • 1
    You can use the settings API and store the data elsewhere. The point is just that the settings API is crap.
    – fuxia
    Commented Jun 11, 2016 at 12:12
  • @toscho You're right. It's a wrapper for dirty stuffs. If we using Settings API only, we have to handle data by ourself.
    – Minh Tri
    Commented Jun 11, 2016 at 12:18
1
  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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.