Вопрос или проблема
Существуют несколько хороших примеров и руководств по добавлению меню опций в плагин. (Тем не менее, многие из них кажутся запутанно старыми, но это уже другой вопрос, я предполагаю, что вещи, которые были актуальны 15 лет назад, все еще применимы в случае меню опций.)
Тем не менее, пользователи моего плагина должны иметь возможность создавать и сохранять несколько наборов опций, желательно произвольное количество наборов. Для большинства пользователей одного набора опций было бы достаточно. Но, безусловно, будут пользователи, которым нужно больше.
В моем плагине примерно 20 опций для настройки (пока что жестко закодированы в начале файла плагина). Поэтому мне интересно, какой может быть лучший подход к “умножению” этого набора из 20 опций, чтобы пользователи могли иметь второй набор этих же 20 опций, которые они могли бы настроить, третий набор и так далее. Дублирование значений не требуется, нужно просто разрешить добавление нового набора значений по мере необходимости. Например, должна быть кнопка “Создать новый набор опций” или что-то подобное, и, вероятно, лучший способ — предоставить пользователю новую вкладку/страницу опций для него. Желательно, чтобы для каждого набора была настройка, чтобы отметить его как активный или неактивный, чтобы мой плагин обрабатывал только активные наборы. Надеюсь, все это имеет смысл.
Мне интересно, может кто-то указать мне правильное направление и, возможно, предоставить несколько советов или идей для решения этой проблемы…? Решение должно быть бесплатным, я уже рассматривал возможность начать эксперименты просто с API настроек WordPress или Redux, но, я думаю, важно выбрать метод, который особенно подойдет для этой задачи “динамического добавления новых подменю” на ходу, если это вообще возможно.
Мне очень хотелось бы избежать предопределения и, таким образом, ограничения количества возможных наборов опций, но если мне придется пойти этим путем, то, вероятно, я предопределю его до 10 наборов максимум. Вопрос остается: какая техника будет хорошим выбором для работы с этими наборами опций, в отличие от обычного одного набора.
(Я почти новичок в WordPress и PHP, также не очень хорош в ООП, так что предпочел бы этого избежать. Также время немного является проблемой, этот плагин — лишь побочный продукт более крупного некоммерческого проекта, над которым я работаю.)
ИЗМЕНЕНИЕ:
Я думаю, что самым чистым подходом было бы одностраничное приложение, с выпадающим меню вверху для выбора между сохраненными наборами опций, чтобы форма оставалась на месте, а только значения ввода в ней изменялись.
Так что да, этот вопрос определенно больше о технической помощи и совете, какая техника будет хорошей для этого типа вещей в первую очередь, потому что, скорее всего, я потратил бы много и много времени, просто пробуя разные варианты. Я немного потерян в опциях, поскольку, похоже, существует так много способов сделать вещи, но я все же считаю, что критически важно выбрать правильный способ в данном случае, иначе это может быть тупиковым вариантом и началом с нуля.
Я забыл упомянуть, что плагин предназначен только для администраторов определенных сайтов WordPress, поэтому администраторы выбирали бы количество наборов, которые им нужны. И да, особенно обработка наборов обязательно будет включать цикл в код.
ИЗМЕНЕНИЕ 2:
Я думаю, что суть моего вопроса в том, можно ли этого добиться с помощью функций вроде settings_fields() и add_settings_field()… и как насчет использования Redux Framework?
Если да, есть ли идеи (предпочтительнее примеры кода), как я мог бы представить пользователю формы настроек, чтобы эти несколько наборов настроек могли быть фактически обработаны на фронтенде и на бэкенде? Надеюсь, это не сделает вопрос слишком широким, но я считаю, что в этом случае оба варианта подхода будут сильно влиять друг на друга.
Другие предложения, кроме этих, также сильно приветствуются. Для меня лучшим решением было бы что-то вроде “в наши дни вы можете сделать это, и это может быть самым простым способом” 🙂
Прежде чем принять что-либо как ответ, я надеюсь получить хотя бы второе мнение от кого-то здесь, поскольку я не спешу с моим плагином. Спасибо всем за прочтение и вклад!
Вот пример того, как управлять несколькими наборами опций. Он должен быть дополнен nonce для предотвращения CSRF-атаки, а также требуется немного оформления.
add_action("admin_menu", function () {
add_menu_page(
"Мультиопции"
, "Мультиопции"
, "manage_options" // возможность редактировать опции
, "MY_PLUGIN__multioptions"
, function () {
do_action("MY_PLUGIN/multioptions");
}
);
});
add_filter("MY_PLUGIN/list_options", function ($list_options) {
return [
"option1" => [
"label" => "Поднимите руки в воздух",
],
"option2" => [
"label" => "Поднимите руки",
],
"option3" => [
"label" => "В воздухе",
],
];
});
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"])?>&id_set=<?= htmlspecialchars($id_set)?>">
редактировать набор <?= htmlspecialchars($id_set)?></a>
</div>
<?php }?>
<div>
<form method="post">
<button name="add_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>
набор номер <?= htmlspecialchars($id_set)?>
</h3>
<?php if ("saved" === $message) {?>
<div id="message" class="notice notice-success is-dismissible updated">
<p>Сохранено</p>
</div>
<?php }?>
<form method="post">
<button name="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">сохранить</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"])) {
// сохранить набор
unset($_POST["save"]);
$values[$_GET["id_set"]] = $_POST;
update_user_meta($current_user->ID, "MY_PLUGIN__values", $values);
// перенаправление
wp_redirect($_SERVER["REQUEST_URI"] . "&message=saved", 303);
exit();
}
if (isset($_POST["add_set"])) {
// добавить набор
$values[] = [];
update_user_meta($current_user->ID, "MY_PLUGIN__values", $values);
// перенаправление
wp_redirect($_SERVER["REQUEST_URI"], 303);
exit();
}
});
Ответ или решение
Создание многосетевого меню опций для плагина WordPress
Для реализации функционала, позволяющего пользователям создавать и сохранять несколько наборов опций в вашем плагине WordPress, можно использовать возможности API настроек WordPress. В данной инструкции представлен пример кода, который поможет вам организовать интерфейс для управления наборами опций.
Шаги по реализации
-
Создание страницы меню для плагина. Добавьте функцию для создания меню в административной панели.
-
Определение параметров опций. Создайте фильтр, который будет возвращать массив опций, доступных для выбора.
-
Отображение набора опций. Разработайте функции, которые будут отвечать за отображение имеющихся наборов и формы для редактирования конкретного набора.
-
Сохранение опций. Обработайте логику сохранения созданных наборов и обновление значений в базе данных.
Пример кода
add_action("admin_menu", function () {
add_menu_page(
"Мультиопции",
"Мультиопции",
"manage_options",
"MY_PLUGIN__multioptions",
function () {
do_action("MY_PLUGIN/multioptions");
}
);
});
add_filter("MY_PLUGIN/list_options", function ($list_options) {
return [
"option1" => [
"label" => "Параметр 1",
],
"option2" => [
"label" => "Параметр 2",
],
"option3" => [
"label" => "Параметр 3",
],
];
});
add_action("MY_PLUGIN/multioptions", function () {
$current_user = wp_get_current_user();
$values = get_user_meta($current_user->ID, "MY_PLUGIN__values", true);
if (empty($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"]) ?>&id_set=<?= htmlspecialchars($id_set) ?>">
Редактировать набор <?= htmlspecialchars($id_set) ?></a>
</div>
<?php } ?>
<div>
<form method="post">
<button name="add_set">Добавить набор</button>
</form>
</div>
<?php
});
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>Набор номер <?= htmlspecialchars($id_set) ?></h3>
<?php if ("saved" === $message) { ?>
<div id="message" class="notice notice-success is-dismissible updated">
<p>Сохранено</p>
</div>
<?php } ?>
<form method="post">
<button name="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">Сохранить</button>
</form>
<?php
});
add_action("load-toplevel_page_MY_PLUGIN__multioptions", function () {
$current_user = wp_get_current_user();
$values = get_user_meta($current_user->ID, "MY_PLUGIN__values", true);
if (empty($values)) {
$values = [[]];
}
if (isset($_POST["save"])) {
// Сохранение набора
unset($_POST["save"]);
$values[$_GET["id_set"]] = $_POST;
update_user_meta($current_user->ID, "MY_PLUGIN__values", $values);
// Перенаправление
wp_redirect($_SERVER["REQUEST_URI"] . "&message=saved", 303);
exit();
}
if (isset($_POST["add_set"])) {
// Добавление нового набора
$values[] = [];
update_user_meta($current_user->ID, "MY_PLUGIN__values", $values);
// Перенаправление
wp_redirect($_SERVER["REQUEST_URI"], 303);
exit();
}
});
Пояснения к коду
-
Создание страницы меню. Используется действие
admin_menu
для добавления страницы настроек плагина в меню администратора. -
Определение опций. Фильтр
MY_PLUGIN/list_options
предоставляет список опций, которые можно настраивать. -
Отображение опций. Функция
MY_PLUGIN/multioptions
отвечает за отображение форм, позволяя пользователю выбрать или редактировать наборы опций. -
Сохранение данных. Логика обработки сохранения и добавления новых новых наборов осуществляется внутри действия
load-toplevel_page_MY_PLUGIN__multioptions
.
Заключение
Этот пример кода предоставляет базовую структуру для управления несколькими наборами настроек в плагине WordPress. Вы можете расширять его, добавляя больше опций, улучшая интерфейс и обрабатывая более сложные сценарии в зависимости от потребностей вашего проекта. Не забудьте добавить защита от CSRF, используя функции nonce для повышения безопасности вашего плагина.