Вопрос или проблема
Я пытаюсь добавить несколько мета-боксов для пользовательского типа записи через класс. Я использую параметр "register_meta_box_cb"
при регистрации пользовательского типа записи, чтобы указать функцию обратного вызова для добавления мета-боксов.
Пример кода – (набросок моего кода) –
class ABC
{
public static function add_customposttype()
{
$abc_o = new ABC();
$abc_o->reg();
}
public function reg()
{
$args = array(
"label" => "ABC",
"description" => "Новый CPT",
"public" => true,
"register_meta_box_cb" => array($this, "meta_box_callback")
);
register_post_type("abc", $args);
}
public function meta_box_callback()
{
$meta_fields = get_all_meta_fields(); // Это возвращает мне массив объектов классов 'c_box, b_box и a_box'
foreach($meta_fields as $object)
{
add_meta_box($object->name, $object->label, array($object, 'render_meta_box'), 'abc', $object->context, $object->priority);
}
}
}
class c_box
{
public $name;
public $label;
public $context;
public $priority;
public function __construct()
{
$this->name="c_box";
$this->label="C Box";
$this->context="normal";
$this->priority = 'high';
}
public function render_meta_box($post)
{
echo "<p>Это C Box</p>"; // Никогда не выполняется
}
}
class b_box
{
public $name;
public $label;
public $context;
public $priority;
public function __construct()
{
$this->name="b_box";
$this->label="B Box";
$this->context="normal";
$this->priority = 'high';
}
public function render_meta_box($post)
{
echo "<p>Это B Box</p>"; // Никогда не выполняется
}
}
class a_box
{
public $name;
public $label;
public $context;
public $priority;
public function __construct()
{
$this->name="a_box";
$this->label="A Box";
$this->context="normal";
$this->priority = 'high';
}
public function render_meta_box($post)
{
echo "<p>Это A Box</p>"; // Никогда не выполняется
}
}
Таким образом, у меня есть разные классы, определенные для различных мета-боксов. Я хочу, чтобы у всех них была общая функция render_meta_box
, чтобы я мог создавать объекты всех этих классов, помещать их в массив и проходить по нему, чтобы вызывать функцию render_meta_box
для всех по очереди.
По сути, мета-бокс будет иметь свой собственный класс с функцией render_meta_box
и некоторыми другими функциями, и я могу создать объект каждого из таких классов и запускать их функции одну за другой, таким образом упрощая добавление новых мета-боксов в будущем.
Проблема, с которой я сталкиваюсь, заключается в том, что когда я определяю метод render_meta_box
в отдельных классах с HTML-кодом, который нужно вывести, похоже, что add_meta_box
никогда не выполняет эту функцию обратного вызова. Я пытался выяснить, могу ли я вывести что-то в методе render_meta_box
, но он никогда не доходил до этого оператора вывода.
Я что-то упускаю? Я думал, что могу вызывать методы render_meta_box
с помощью разных объектов, чтобы они все выполнялись по-разному. Мой подход некорректен?
Заранее спасибо!
и добро пожаловать!
Было бы полезно иметь код, который более полный и показывает, как вы вызываете эти методы. Однако одна вещь, которую я вижу и которая вероятно является причиной хотя бы части вашей проблемы, это способ, которым вы вызываете add_meta_box()
.
add_meta_box()
должен вызываться во время действия add_meta_boxes
. Я никогда не пробовал запускать его в качестве функции обратного вызова register_post_type()
раньше. Но, предполагая, что вы запускаете register_post_type()
во время init
, я предполагаю, что add_meta_box()
также будет выполняться во время init
– до того, как функция станет доступной.
Если WP фактически пытается запустить add_meta_box()
до того, как она станет доступной, вы должны увидеть Фатальную ошибку
в ваших журналах PHP из-за вызова несуществующей функции.
Чтобы устранить неполадки, сначала подтвердите, что ваш register_meta_box_cb
работает, просто вызвав функцию, которая будет die;
или записывать что-то в файл.
После того как вы подтвердите, что это работает, вы можете попробовать, чтобы register_meta_box_cb
вызывал функцию, которая добавит действие к add_meta_boxes
. Пусть обратный вызов этого действия add_meta_boxes
выполняет ваш цикл add_meta_box()
.
Дайте мне знать, если это не сработает или вам нужна дополнительная помощь!
Итак, я выяснил, что пошло не так.
Это было так тривиально, как неправильное имя переменной класса. Я использовал переменную с именем field_label
в классе и получал к ней доступ неправильно, как $this->label
, что означало, что она имела значение NULL.
Мой подход к добавлению мета-боксов во время регистрации типа записи, тем не менее, работает отлично.
Ответ или решение
Ваша задача по добавлению мета-боксов для пользовательского типа записи с использованием классов в WordPress является довольно распространенной, и решение проблемы, с которой вы столкнулись, важно для правильного функционирования вашего кода. Мы подробно разберём ключевые моменты регистрации пользовательского типа записи и добавления мета-боксов.
Структура Класса
-
Определение Класса: Вы уже создали основной класс
ABC
, который отвечает за регистрацию пользовательского типа записи (CPT) и мета-боксов. Также у вас есть классы для различных видов мета-боксов (c_box
,b_box
,a_box
), которые инкапсулируют свойства и методы этих мета-боксов. -
Регистрация Пользовательского Типа Записи:
В методеreg()
вы правильно используете параметрregister_meta_box_cb
, чтобы указать на функцию обратного вызова для добавления мета-боксов. Это позволяет вам управлять мета-боксами при регистрации пользовательского типа записи.
Добавление Мета-Боксов
Метод meta_box_callback
использует массив объектов мета-боксов для добавления каждого из них с помощью конструкции add_meta_box()
. Это хороший подход, который помогает централизовать логику создания мета-боксов.
Проблемы с Вызовом render_meta_box
Если render_meta_box
никогда не вызывается, причины могут быть разными.
-
Действие
add_meta_boxes
: как правильно отмечено, добавление мета-боксов должно происходить в момент, когда они доступны. Вызов функцииadd_meta_box()
должен происходить в хукеadd_meta_boxes
. Это значит, что вам нужно:- Вместо использования параметра
register_meta_box_cb
вregister_post_type
, добавьте действие наadd_meta_boxes
, чтобы вызывать метод для добавления мета-боксов.
public function reg() { $args = [ "label" => "ABC", "description" => "New CPT", "public" => true, ]; register_post_type("abc", $args); add_action('add_meta_boxes_abc', [$this, 'meta_box_callback']); }
- Вместо использования параметра
-
Корректное Определение Атрибутов В Классах Мета-Боксов: Вы должны убедиться, что в классах мета-боксов правильно заданы все свойства. Важно, чтобы название атрибута
label
действительно соответствовало тому, что вы используете в массиве объектов.
Финальная Структура Кода
Вот как может выглядеть модифицированный код с учетом всех изменений:
class ABC {
public static function add_customposttype() {
$abc_o = new ABC();
$abc_o->reg();
}
public function reg() {
$args = [
"label" => "ABC",
"description" => "New CPT",
"public" => true,
];
register_post_type("abc", $args);
add_action('add_meta_boxes_abc', [$this, 'meta_box_callback']);
}
public function meta_box_callback() {
$meta_fields = get_all_meta_fields(); // Этот метод должен возвращать массив объектов классов мета-боксов.
foreach ($meta_fields as $object) {
add_meta_box($object->name, $object->label, [$object, 'render_meta_box'], 'abc', $object->context, $object->priority);
}
}
}
class c_box {
public $name = "c_box";
public $label = "C Box";
public $context = "normal";
public $priority = 'high';
public function render_meta_box($post) {
echo "<p>This is a C Box</p>";
}
}
class b_box {
public $name = "b_box";
public $label = "B Box";
public $context = "normal";
public $priority = 'high';
public function render_meta_box($post) {
echo "<p>This is a B Box</p>";
}
}
class a_box {
public $name = "a_box";
public $label = "A Box";
public $context = "normal";
public $priority = 'high';
public function render_meta_box($post) {
echo "<p>This is an A Box</p>";
}
}
Заключение
Ваш подход к организации кода и создание мета-боксов через классы является разумным и модульным. Убедитесь, что вы правильно используете хуки и проверяйте названия переменных. После внесения этих изменений ваш код должен работать так, как вы ожидаете, обеспечивая возможность добавления новых мета-боксов в будущем без значительных сложностей.