Вопрос или проблема
Мне нужно проанализировать содержимое виджета на основе его идентификатора.
Но виджет работает как функция, которая извлекает данные на основе своих аргументов, верно? Так что, когда я извлекаю данные виджета, я могу получить только его аргументы, а не фактический вывод.
Как я могу проанализировать содержимое виджета на основе его идентификатора?
Пример кода:
// Обновление раундов виджета автоматически
function automatize_games_rounds($instance, $widget, $args){
// Проверяем, есть ли заголовок
if (isset($instance['caption']) && !empty($instance['caption'])) {
// Если есть, содержит ли он слово "round"?
if (strpos(strtolower($instance['caption']), 'round')) {
// Если да, это тот виджет, который я ищу. Давайте получим его идентификатор.
$id = $args['widget_id'];
// Теперь мне нужно проанализировать вывод виджета, чтобы выполнить некоторые действия на основе его содержимого, но как я могу получить вывод виджета?
}
}
return $instance;
}
add_filter('widget_display_callback','automatize_games_rounds',10,3);
Если у вас есть аргументы, вы можете использовать the_widget(), чтобы вывести тот же виджет, который вы ищете.
Если у вас нет аргументов или они каким-то образом изменяются (хотя их можно извлечь из базы данных), вам нужно будет перебрать все область виджетов и все виджеты внутри каждой, чтобы сопоставить идентификатор, который вы ищете, и использовать the_widget().
На самом деле таким образом вы не можете отфильтровать данные каждого виджета. WordPress не предоставляет никакого нативного способа фильтровать окончательный вывод любого виджета. Но есть несколько других способов изменить содержимое любого виджета, и они:
1. Измените исходные файлы виджета.
Очевидно, что это не лучший метод, так как ваши изменения будут потеряны, если WordPress или плагин, создающий виджет, будет обновлён.
2. Скопируйте виджет в свой собственный плагин или тему и измените его там.
3. Замените оригинальную функцию обратного вызова отображения виджета на пользовательскую функцию, которая затем запускает оригинальную функцию обратного вызова отображения, но с фильтрами.
В основном, оригинальная функция обратного вызова отображения виджета переопределяется новой пользовательской функцией, которая запускает оригинальную функцию обратного вызова виджета, но использует буферизацию вывода, чтобы захватить вывод и пропустить его через фильтр перед отображением. Я нашел это здесь. Вот код, который можно использовать в теме или плагине и который предоставит фильтр widget_output
, вместе с типом виджета и уникальным идентификатором виджета в качестве параметров:
Сначала нам нужно заменить оригинальную функцию обратного вызова отображения виджета на нашу собственную пользовательскую функцию:
function the_dramatist_filter_dynamic_sidebar_params( $sidebar_params ) {
if ( is_admin() ) {
return $sidebar_params;
}
global $wp_registered_widgets;
$widget_id = $sidebar_params[0]['widget_id'];
$wp_registered_widgets[ $widget_id ]['original_callback'] = $wp_registered_widgets[ $widget_id ]['callback'];
$wp_registered_widgets[ $widget_id ]['callback'] = 'the_dramatist_custom_widget_callback_function';
return $sidebar_params;
}
add_filter( 'dynamic_sidebar_params', 'the_dramatist_filter_dynamic_sidebar_params' );
Затем нам нужно создать функцию, упомянутую в предыдущем блоке кода, которая, в свою очередь, запустит оригинальную функцию обратного вызова отображения виджета, но захватит её вывод, используя буферизацию вывода PHP. Затем фильтр widget_output
будет запущен на сгенерированном HTML-коде виджета перед его выводом на страницу:
function the_dramatist_custom_widget_callback_function() {
global $wp_registered_widgets;
$original_callback_params = func_get_args();
$widget_id = $original_callback_params[0]['widget_id'];
$original_callback = $wp_registered_widgets[ $widget_id ]['original_callback'];
$wp_registered_widgets[ $widget_id ]['callback'] = $original_callback;
$widget_id_base = $wp_registered_widgets[ $widget_id ]['callback'][0]->id_base;
if ( is_callable( $original_callback ) ) {
ob_start();
call_user_func_array( $original_callback, $original_callback_params );
$widget_output = ob_get_clean();
echo apply_filters( 'widget_output', $widget_output, $widget_id_base, $widget_id );
}
}
С этим на месте, вы можете сделать что-то подобное в плагине или теме, чтобы изменить вывод любого виджета:
function the_dramatist_widget_output_filter( $widget_output, $widget_id_base, $widget_id ) {
/* Чтобы нацелиться на конкретный идентификатор виджета: */
if ( 'target_widget_id' == $widget_id ) {
// Примените ваши желаемые операции поиска и замены здесь
}
return $widget_output;
}
add_filter( 'widget_output', 'the_dramatist_widget_output_filter', 10, 3 );
Надеюсь, вышеизложенное поможет.
Ответ или решение
Чтобы извлечь содержимое виджета на WordPress по его ID, следует учитывать, что виджет работает как функция, которая получает данные на основе своих аргументов. Это значит, что просто получив аргументы, вы не сможете получить фактический вывод виджета. Давайте рассмотрим несколько методов, как это сделать, чтобы вы могли решить проблему эффективно.
Общий Подход
К сожалению, WordPress не предоставляет нативного способа фильтрации окончательного вывода любого виджета. Тем не менее, существует несколько способов, которые позволят вам изменить содержимое виджета.
Способы Изменения Содержимого Виджета
-
Модификация Исходных Файлов Виджета
Хотя это возможно, этот метод не рекомендуется, так как любые изменения будут потеряны при обновлении WordPress или плагина, создающего виджет. -
Копирование Виджета в Вашу Тему или Плагин
Этот способ позволяет вам сохранить изменения при обновлениях, поскольку вы будете работать с независимой копией виджета. -
Замена Исходной Функции Вывода Виджета на Пользовательскую Функцию
Этот подход предполагает переопределение исходной функции вывода виджета, чтобы использовать захват выходных данных с помощью буферизации вывода. Это позволит вызвать фильтрацию полученного HTML-кода перед его отображением.
Пример Кода
Давайте разберем более подробно третий метод. Ниже приведен код, который можно использовать в теме или плагине для предоставления фильтра widget_output
, который позволяет изменять вывод любого виджета.
Замена Функции
Сначала необходимо заменить исходный колбэк функции виджета на пользовательскую:
function the_dramatist_filter_dynamic_sidebar_params( $sidebar_params ) {
if ( is_admin() ) {
return $sidebar_params;
}
global $wp_registered_widgets;
$widget_id = $sidebar_params[0]['widget_id'];
$wp_registered_widgets[ $widget_id ]['original_callback'] = $wp_registered_widgets[ $widget_id ]['callback'];
$wp_registered_widgets[ $widget_id ]['callback'] = 'the_dramatist_custom_widget_callback_function';
return $sidebar_params;
}
add_filter( 'dynamic_sidebar_params', 'the_dramatist_filter_dynamic_sidebar_params' );
Создание Пользовательской Функции
Теперь создадим функцию, которая будет захватывать вывод виджета:
function the_dramatist_custom_widget_callback_function() {
global $wp_registered_widgets;
$original_callback_params = func_get_args();
$widget_id = $original_callback_params[0]['widget_id'];
$original_callback = $wp_registered_widgets[ $widget_id ]['original_callback'];
$wp_registered_widgets[ $widget_id ]['callback'] = $original_callback;
if ( is_callable( $original_callback ) ) {
ob_start();
call_user_func_array( $original_callback, $original_callback_params );
$widget_output = ob_get_clean();
echo apply_filters( 'widget_output', $widget_output, $wp_registered_widgets[ $widget_id ]['callback'][0]->id_base, $widget_id );
}
}
Использование Фильтра
Теперь вы можете использовать полученный вами фильтр для изменения содержимого конкретного виджета:
function the_dramatist_widget_output_filter( $widget_output, $widget_id_base, $widget_id ) {
if ( 'target_widget_id' == $widget_id ) {
// Здесь могут быть ваши операции поиска и замены
}
return $widget_output;
}
add_filter( 'widget_output', 'the_dramatist_widget_output_filter', 10, 3 );
Заключение
Используя указанные методы, вы сможете извлечь и модифицировать содержимое любого виджета на WordPress по его ID. Эти техники не только дают вам больше контроля, но и позволяют поддерживать аккуратность и универсальность в вашей работе с виджетами. Однако стоит помнить, что редактирование исходных файлов — это ненадежный подход, в связи с чем использование методов создания пользовательских функций является предпочтительным.