admin管理员组

文章数量:1122846

There are several good examples and tutorials on how to add an options menu to a plugin. (Many of these seem confusingly old though, but that's another thing, I'm assuming stuff from 15 years ago still applies when options menus are considered.)

However, the users of my plugin should be able to create and save multiple sets of options, preferably an arbitrary number of sets. For most users, one set of options would be enough. But there would definitely be users, who need more.

In my plugin, there are about 20 options to configure (so far just hard-coded in the beginning of the plugin file). So I'm interested what might be the best approach for sort of "multiplying" this set of 20 options, to allow the users to have a second set of these same 20 options they could configure, the third set and so on. No duplicating of values necessary, just allowing to add a new set of values as needed. Like, there would be button to "Create new option set" or similar and probably the best way would be to present the user a new option tab/page for them. Preferably there would be a setting for each set to be marked as active or inactive, so my plugin would then process only the active sets. Hopefully all this makes sense.

I wonder could someone point me to the right direction and maybe provide some tips or thoughts for tackling this kind of problem..? The solution should be something free, I have already considered starting experimenting with just the WordPress Settings API or Redux, but I think it's essential to choose a method that especially suits this need of "dynamically adding new sub-menus" on-the-go if that's even possible.

I'd very much like to avoid predefining and thus limiting the number of possible option sets, but if I have to go that route, then I would probably predefine it to something like 10 sets max. The question still stands, which technique would be a good choice to handle these option sets, as opposed to just the usual one set.

(I'm almost a beginner in WordPress and php, also not good in OOP so I'd rather avoid that. Also time is a bit of an issue, this plugin is only a by-product of a bigger nonprofit project I'm working on.)

EDIT:

I think the cleanest approach would be a single page experience, with a dropdown menu at the top for choosing between the saved option sets, so that the form stays in place and only the input values change in it.

So yes, this question is definitely more for asking technical help and advice which technique would be good for this kind of thing in the first place, because most likely I would waste lots and lots of time just going the trial and error route. I'm a bit lost with the options, since there seems to be so many ways to do things, still I believe it's crucial to pick the right way in this case, otherwise it might be a dead end and a start from scratch.

I forgot to mention, the plugin is aimed only for admins of certain WordPress sites, therefore the admins would choose the number of sets they need. And yes, especially processing the sets would definitely involve looping in the code.

EDIT 2:

I think the essence of my question is, can this be achieved using functions like settings_fields() and add_settings_field()... and optionally how about using Redux Framework?

If yes, any ideas (code examples preferred) how could I present the user the settings form(s) so that these multiple sets of settings can be actually handled in the front end, and in the back end? I hope this doesn't make the question too broad, but I believe in this case both choices of approach would heavily affect each other.

Other suggestions besides these also highly appreciated. For me, the top solution would be along the lines of "nowadays you can do this, and it might be the simplest way" :)

Before accepting anything as answer though, I'm hoping to get at least a second opinion from someone here, since I'm in no hurry with my plugin yet. Thanks everyone for reading and contributing!

There are several good examples and tutorials on how to add an options menu to a plugin. (Many of these seem confusingly old though, but that's another thing, I'm assuming stuff from 15 years ago still applies when options menus are considered.)

However, the users of my plugin should be able to create and save multiple sets of options, preferably an arbitrary number of sets. For most users, one set of options would be enough. But there would definitely be users, who need more.

In my plugin, there are about 20 options to configure (so far just hard-coded in the beginning of the plugin file). So I'm interested what might be the best approach for sort of "multiplying" this set of 20 options, to allow the users to have a second set of these same 20 options they could configure, the third set and so on. No duplicating of values necessary, just allowing to add a new set of values as needed. Like, there would be button to "Create new option set" or similar and probably the best way would be to present the user a new option tab/page for them. Preferably there would be a setting for each set to be marked as active or inactive, so my plugin would then process only the active sets. Hopefully all this makes sense.

I wonder could someone point me to the right direction and maybe provide some tips or thoughts for tackling this kind of problem..? The solution should be something free, I have already considered starting experimenting with just the WordPress Settings API or Redux, but I think it's essential to choose a method that especially suits this need of "dynamically adding new sub-menus" on-the-go if that's even possible.

I'd very much like to avoid predefining and thus limiting the number of possible option sets, but if I have to go that route, then I would probably predefine it to something like 10 sets max. The question still stands, which technique would be a good choice to handle these option sets, as opposed to just the usual one set.

(I'm almost a beginner in WordPress and php, also not good in OOP so I'd rather avoid that. Also time is a bit of an issue, this plugin is only a by-product of a bigger nonprofit project I'm working on.)

EDIT:

I think the cleanest approach would be a single page experience, with a dropdown menu at the top for choosing between the saved option sets, so that the form stays in place and only the input values change in it.

So yes, this question is definitely more for asking technical help and advice which technique would be good for this kind of thing in the first place, because most likely I would waste lots and lots of time just going the trial and error route. I'm a bit lost with the options, since there seems to be so many ways to do things, still I believe it's crucial to pick the right way in this case, otherwise it might be a dead end and a start from scratch.

I forgot to mention, the plugin is aimed only for admins of certain WordPress sites, therefore the admins would choose the number of sets they need. And yes, especially processing the sets would definitely involve looping in the code.

EDIT 2:

I think the essence of my question is, can this be achieved using functions like settings_fields() and add_settings_field()... and optionally how about using Redux Framework?

If yes, any ideas (code examples preferred) how could I present the user the settings form(s) so that these multiple sets of settings can be actually handled in the front end, and in the back end? I hope this doesn't make the question too broad, but I believe in this case both choices of approach would heavily affect each other.

Other suggestions besides these also highly appreciated. For me, the top solution would be along the lines of "nowadays you can do this, and it might be the simplest way" :)

Before accepting anything as answer though, I'm hoping to get at least a second opinion from someone here, since I'm in no hurry with my plugin yet. Thanks everyone for reading and contributing!

Share Improve this question edited Sep 27, 2024 at 14:16 Ant Ax asked Sep 21, 2024 at 17:35 Ant AxAnt Ax 11 bronze badge 4
  • when there is something that is repeated, there is lots a time a loop in the code. edit your question to explain if you ask more for a technical help or for a interface help in order to be practical. each user can choose the number of sets or it's decided by another person ? – mmm Commented Sep 21, 2024 at 20:45
  • Thank you. I edited the question to add a bit more explanation to the end. – Ant Ax Commented Sep 22, 2024 at 10:31
  • to avoid dead end, the most important is to take time to think about data structures. once they are in place, you can create basic form to edit them and use these data on the website. and in a few months e.g., you can improve the edit form with javascript without interrupting the use of these data. – mmm Commented Sep 23, 2024 at 7:35
  • for the question about the framework, that depends if you forecast to make more projects with this framework. using a framework often take time at the start but then, you save time on next projects. – mmm Commented Sep 23, 2024 at 7:37
Add a comment  | 

1 Answer 1

Reset to default 0

here an example of how to manage multiple set of options. it needs to be completed by a nonce to avoid CSRF attack and it needs also a little bit of layout.

    add_action("admin_menu", function () {
        
        add_menu_page(
              "Multioptions"
            , "Multioptions"
            , "manage_options" // capability to be allowed to edit options
            , "MY_PLUGIN__multioptions"
            , function () {
                do_action("MY_PLUGIN/multioptions");
            }
        );
        
    });


    add_filter("MY_PLUGIN/list_options", function ($list_options) {
        
        return [
            "option1" => [
                "label" => "Put your hands up in the air",
            ],
            "option2" => [
                "label" => "Put your hands up",
            ],
            "option3" => [
                "label" => "In the air",
            ],
        ];
        
    });


    add_action("MY_PLUGIN/multioptions", function () {
        
        $current_user = wp_get_current_user();
        $values = $current_user->MY_PLUGIN__values;
        
        if ("" === $values) {
            $values = [[]];
        }
        
        
        ?>
            
            <div class="MY_PLUGIN__multioptions">
                
                <?php
                
                if (    !isset($_GET["id_set"])
                    ||  !isset($values[$_GET["id_set"]])
                ) {
                    do_action("MY_PLUGIN/multioptions/show_sets", $values);
                } else {
                    do_action("MY_PLUGIN/multioptions/edit_a_set", $_GET["id_set"], $values[$_GET["id_set"]]);
                }
                
                ?>
                
            </div>
            
            <style>
                .MY_PLUGIN__multioptions div
                {
                    margin : 2em;
                }
            </style>
            
        <?php
        
        
    });


    add_action("MY_PLUGIN/multioptions/show_sets", function ($values) {
        
        ?>
            
            <?php foreach (array_keys($values) as $id_set) {?>
                <div>
                    <a href="?page=<?= htmlspecialchars($_GET["page"])?>&amp;id_set=<?= htmlspecialchars($id_set)?>">
                        edit set <?= htmlspecialchars($id_set)?></a>
                </div>
            <?php }?>
            
            <div>
                <form method="post">
                    <button name="add_set">add a set</button>
                </form>
            </div>
            
        <?php
        
    }, 10, 1);


    add_action("MY_PLUGIN/multioptions/edit_a_set", function ($id_set, $values_set) {
        
        $list_options = apply_filters("MY_PLUGIN/list_options", NULL);
        
        $message = $_GET["message"] ?? "";
        
        ?>
            
            <h3>
                set number <?= htmlspecialchars($id_set)?>
            </h3>
            
            <?php if ("saved" === $message) {?>
                <div id="message" class="notice notice-success is-dismissible updated">
                    <p>Saved</p>
                </div>
            <?php }?>
            
            <form method="post">
                
                <button name="save">save</button>
                
                <?php foreach ($list_options as $option_key => $tab_option) {?>
                    
                    <div>
                        <label>
                            <?= htmlspecialchars($tab_option["label"])?>
                            <input
                                type="checkbox"
                                name="<?= htmlspecialchars($option_key)?>"
                                <?= !isset($values_set[$option_key]) ? "" : " checked=\"checked\""?>
                            />
                        </label>
                    </div>
                    
                <?php }?>
                
                <button name="save">save</button>
                
            </form>
            
        <?php
        
        
    }, 10, 2);


    add_action("load-toplevel_page_MY_PLUGIN__multioptions", function () {
        
        $current_user = wp_get_current_user();
        $values = $current_user->MY_PLUGIN__values;
        
        if ("" === $values) {
            $values = [[]];
        }
        
        
        if (isset($_POST["save"])) {
            
            // save a set
            
            unset($_POST["save"]);
            $values[$_GET["id_set"]] = $_POST;
            
            update_user_meta($current_user->ID, "MY_PLUGIN__values", $values);
            
            
            // redirection
            
            wp_redirect($_SERVER["REQUEST_URI"] . "&message=saved", 303);
            exit();
            
        }
        
        
        if (isset($_POST["add_set"])) {
            
            // add a set
            
            $values[] = [];
            update_user_meta($current_user->ID, "MY_PLUGIN__values", $values);
            
            
            // redirection
            
            wp_redirect($_SERVER["REQUEST_URI"], 303);
            exit();
            
        }
        
        
        
    });

本文标签: plugin developmentadding an options menu that allows saving multiple sets of said options