Изменение HTML, создаваемого wp_list_comments()

2 февр. 2016 г., 23:47:11
Просмотры: 20K
Голосов: 10

Я разрабатываю тему WordPress, для которой хочу обернуть временную метку каждого комментария в элемент <span> для стилизации через CSS. Однако функция wp_list_comments(), которую я использую в шаблоне comments.php моей темы, похоже, не предоставляет опций для изменения создаваемого HTML:

<ol class="comment-list">
    <?php
        wp_list_comments( array(
            'style'       => 'ol',
            'format'      => 'html5',
            'short_ping'  => true,
        ) );
    ?>
</ol>

которая генерирует временные метки следующим образом:

<time datetime="2015-12-21T19:09:49+00:00"> 21 декабря 2015 в 19:09 </time>

Как я могу изменить вывод функции, чтобы добавить элемент <span> вокруг каждого элемента <time> без изменения core-файлов?

Я пытался искать в файле functions.php моей темы, а также в файлах WordPress wp-includes/comment.php и wp-includes/comment-template.php. Ни один из них не работает непосредственно со структурой тегов временных меток комментариев, генерируемых wp_list_comments(), поэтому там не было ничего, с чем можно было бы работать.

9
Комментарии

Вы видели исходный код функции wp_list_comments()? Вы уверены, что именно эта функция отвечает за это, а не, например, шаблон comments.php или совершенно другая часть?

kaiser kaiser
2 февр. 2016 г. 23:51:42

Вы точно уверены, что вам нужна обёртка <span>? Почему бы не применить стили напрямую к элементу <time>?

bosco bosco
3 февр. 2016 г. 00:11:12

Я согласен с @bosco, похоже, что <span> здесь не нужен. Иначе вам следует показать аргументы функции wp_list_comments(), чтобы понять, использует ли она callback или собственный walker. Скорее всего, вы используете встроенный Walker_Comment::html5_comment(). Вчера здесь задавали похожий вопрос.

birgire birgire
3 февр. 2016 г. 00:43:51

@birgie моя ошибка - я на самом деле убрал его использование wp_list_comments(), потому что думал, что это лишнее. Исправил O.o

bosco bosco
3 февр. 2016 г. 00:50:51

нашел ТОЧНО то, что мне нужно в этом файле: wp-includes/class-walker-comment.php - здесь я смог изменить html даты комментария. Я хотел стилизовать время иначе, чем дату, поэтому мне нужно было их разместить в отдельных тегах. спасибо всем!

marlakash marlakash
3 февр. 2016 г. 09:37:57

Надеюсь, ты не изменяешь файлы ядра напрямую! @marlakash

birgire birgire
3 февр. 2016 г. 13:33:24

был бы рад сделать это, но не уверен как... у меня мало опыта в написании плагинов и тому подобного. есть советы? @birgire

marlakash marlakash
4 февр. 2016 г. 00:23:51

Кстати, думаю лучше оставить мой предыдущий заголовок вопроса. Я бы никогда не нашел этот ответ через гугл. Он слишком специфичный... @birgire

marlakash marlakash
4 февр. 2016 г. 10:03:52

Я подготовил несколько вариантов для тебя, надеюсь ты сможешь адаптировать их под свои нужды @marlakash

birgire birgire
4 февр. 2016 г. 13:25:22
Показать остальные 4 комментариев
Все ответы на вопрос 1
2
14

Вот несколько способов переопределения стандартного вывода комментариев:

Способ №1 - Переопределение start_el() с помощью кастомного Walker

Определим наш собственный формат комментариев wpse:

// Аргументы для wp_list_comments()
$args = [
    'style'       => 'ol',
    'format'      => 'html5',
    'short_ping'  => true,
];

// Используем кастомный Walker, если он доступен
if( class_exists( 'WPSE_Walker_Comment' ) )
{
    $args['format'] = 'wpse';
    $args['walker'] = new WPSE_Walker_Comment;
}

wp_list_comments( $args );

С кастомным Walker для комментариев, который обрабатывает новый формат (PHP 5.4+):

/**
 * Кастомный Walker для комментариев
 *
 * @users Walker_Comment
 */
class WPSE_Walker_Comment extends Walker_Comment
{
    public function start_el( &$output, $comment, $depth = 0, $args = array(), $id = 0 )
    {
       // Наш кастомный формат 'wpse'
       if ( 'wpse' === $args['format'] )
       {
           $depth++;
           $GLOBALS['comment_depth'] = $depth;
           $GLOBALS['comment'] = $comment;

           // Начинаем буферизацию вывода
           ob_start();

           // Используем нативный html5 шаблон комментария
           $this->html5_comment( $comment, $depth, $args );

           // Наши модификации (оборачиваем <time> в <span>)
           $output .= str_replace( 
               [ '<time ', '</time>' ], 
               ['<span><time ', '</time></span>' ], 
               ob_get_clean() 
           );
       }
       else
       {
           // Стандартный вывод для нативных форматов
           parent::start_el( $output, $comment, $depth, $args, $id );
       }    
    }
} // конец класса

Обратите внимание, как мы обрабатываем наш кастомный формат комментариев. Мы также используем метод start_el() из родительского класса для нативных форматов, вызывая parent::start_el().

Также обратите внимание, что мы используем буферизацию вывода аналогично родительскому классу.

Способ №2 - Переопределение html5_comment() с помощью кастомного Walker

Мы можем напрямую переопределить нативный метод Walker_Comment::html5_comment() следующим образом:

// Аргументы для wp_list_comments()
$args = [
    'style'       => 'ol',
    'format'      => 'html5',
    'short_ping'  => true,
    'walker'      => new WPSE_Walker_Comment,
];

wp_list_comments( $args );

где наш кастомный класс Walker определен в functions.php как:

if ( !class_exists( 'WPSE_Walker_Comment' ) ) {

    /**
     * Кастомный Walker для комментариев
     *
     * @users Walker_Comment
     */
    class WPSE_Walker_Comment extends Walker_Comment {

        public function html5_comment( $comment, $depth, $args ) {
            // Разместите здесь модификации метода Walker_Comment::html5_comment()
        }
    }
    // конец WPSE_Walker_Comment
} // конец условия '!class_exists'

Здесь мы можем разместить наши модификации метода Walker_Comment::html5_comment(). Он достаточно длинный, поэтому я не стал добавлять его сюда.

Способ №3 - Кастомный callback

Здесь мы будем использовать параметр callback:

// Аргументы для wp_list_comments()
$args = [
    'style'       => 'ol',
    'format'      => 'html5',
    'short_ping'  => true,
];

// Используем кастомный callback, если он доступен
if( function_exists( 'wpse_comment_callback' ) )
{
    $args['format'] = 'wpse';
    $args['callback'] = 'wpse_comment_callback';
}

wp_list_comments( $args );

где мы определяем wpse_comment_callback() согласно нашим нуждам.

/**
 * Кастомный callback для комментариев
 */
function wpse_comment_callback( $comment, $depth, $args )
{
    // Модифицируем метод Walker_Comment::html5_comment() под наши нужды
    // и размещаем его здесь
}

где мы можем начать с имитации метода Walker_Comment::html5_comment(). Но нужно помнить, что все ссылки на $this должны быть заменены.

Способ №4 - Переопределение аргументов wp_list_comments() через фильтр

Мы также можем использовать фильтр wp_list_comments_args для модификации аргументов wp_list_comments() с помощью вышеописанных методов.

Существуют и другие подходы, но надеюсь, вы сможете адаптировать эти под свои нужды.

4 февр. 2016 г. 13:24:35
Комментарии

Почему бы не использовать фильтр для этого вместо ООП.

Brad Dalton Brad Dalton
12 февр. 2022 г. 10:48:11

Структура вывода дерева комментариев, вероятно, слишком сложна, чтобы её можно было настроить через один текстовый фильтр.

birgire birgire
17 февр. 2022 г. 18:14:12