Стилизация древовидных комментариев в Wordpress

Анна Шабан в 11:14, 26.02.2009

Вдогонку к статье о создании темы с древовидными комментариями расскажу как можно эти комментарии оформить. Если вы знакомы с “помощниками” всех веб разработчиков (например Firebug для FF, IE Developer Toolbar для IE, DOM Inspector для Opera), то вам не составит труда узнать какие именно классы использует при выводе комментариев функция wp_list_comments(). А для тех, кто не знаком с такими замечательными плагинами или попросту нет желания тратить время на “изучение внутренностей” я приведу несколько примеров стилизации.

Заранее хочу предупредить, что цвета подбирались быстро и без особых заморочек исходя из того, что при использовании предложенных вариантов цветовая гамма будет “переопределена”. Цель статьи - раскрыть список классов и показать примеры визуального форматирования древовидных комментариев.

Для оформления нам понадобится файл  со стилями (style.css). Собственно говоря, почти все наши изменения будут именно в этом фале. Начнем.

Чтобы не пришлось лишний раз  заглядывать в предыдущую статью, привожу код файла комментариев (comments.php):


<?php
if (! e m p t y ($_SERVER['SCRIPT_FILENAME']) && 'comments.php' == basename($_SERVER['SCRIPT_FILENAME']))
	die ('Please do not load this page directly. Thanks!');
if ( post_password_required() ) {
	echo 'This post is password protected. Enter the password to view comments.';
	return;
} ?>

<?php if ( have_comments() ) : ?>
	<h2 id="comments"><?php comments_number('Нет комментариев', 'Один комментарий', 'Комментариев % ' );?></h2>
	<ol class="commentlist">
		<?php wp_list_comments(); ?>
	</ol>
	<div class="navigation">
		<div class="alignleft"><?php previous_comments_link() ?></div>
		<div class="alignright"><?php next_comments_link() ?></div>
	</div>	

<?php else : // If there are no comments yet ?>
	<h2><?php _e('Нет комментариев'); ?></h2>
<?php endif; ?>

<?php if ( comments_open() ) : ?>
	<h2><?php comment_form_title('Оставить комментарий'); ?></h2>

	<?php if ( get_option('comment_registration') && !$user_ID ) : ?>
		<p><?php printf(__('Вы должны <a href="%s">войти</a>, чтобы оставить комментарий.'), get_option('siteurl')."/wp-login.php?redirect_to=".urlencode(get_permalink()));?></p>
	<?php else : ?>

		<div id="respond">
		<form action="<?php echo get_option('siteurl'); ?>/wp-comments-post.php" method="post" id="commentform">
			<div id="cancel-comment-reply">
				<small><?php cancel_comment_reply_link() ?></small>
			</div>
			<?php if ( $user_ID ) : ?>

			<p>
				<?php printf(__('Вы вошли как %s.'), '<a href="'.get_option('siteurl').'/wp-admin/profile.php">'.$user_identity.'</a>'); ?>
				<a href="<?php echo wp_logout_url(get_permalink()); ?>" title="<?php _e('Выйти') ?>"><?php _e('Выйти »'); ?></a>
			</p>

			<?php else : ?>

			<p><input type="text" name="author" id="author" value="<?php echo $comment_author; ?>" size="22" tabindex="1" />
			<label for="author"><small><?php _e('Имя'); ?> <?php if ($req) _e('(обязательно)'); ?></small></label></p>

			<p><input type="text" name="email" id="email" value="<?php echo $comment_author_email; ?>" size="22" tabindex="2" />
			<label for="email"><small><?php _e('Эл. почта (будет скрыта)');?> <?php if ($req) _e('(обязательно)'); ?></small></label></p>

			<p><input type="text" name="url" id="url" value="<?php echo $comment_author_url; ?>" size="22" tabindex="3" />
			<label for="url"><small><?php _e('Сайт'); ?></small></label></p>

			<?php endif; ?>
			<?php comment_id_fields(); ?>
			<!--<p><small><strong>XHTML:</strong> <?php printf(__('You can use these tags: %s'), allowed_tags()); ?></small></p>-->

			<p><textarea name="comment" id="comment" tabindex="4"></textarea></p>

			<p>
				<input name="submit" type="submit" id="submit" tabindex="5" value="<?php echo attribute_escape(__('Отправить')); ?>" />
			</p>
			<?php do_action('comment_form', $post->ID); ?>

		</form>
		</div>
	<?php endif; // If registration required and not logged in ?>

<?php else : // Comments are closed ?>
	<p><?php _e('Извините, обсуждение закрыто.'); ?></p>
<?php endif; ?>

Рассмотрим несколько вариантов и начнем с более понятного (нужно будет внести совсем немного изменений).

Вариант 1 (простой)

Вам нужны комментарии, отделенные друг от друга линиями. Для достижения этой цели в файл style.css добавляем следующие стили:


/* styles for comments with border */
	.commentlist {list-style: none; padding: 0px; border-bottom: 1px dotted #edb844; }
	.vcard *{margin: 10px 10px 0px 0px;  float: left;}
	.fn {padding-top: 5px; font: normal bold 16px Georgia; color: #edb844;}
	.says {padding-top: 9px; font: italic 12px Arial;  color: #8e8361;}
	.comment { padding: 10px 0px 0px 20px;}
	.children { margin-top: 10px; list-style: none; padding: 0px;}
	.children .comment {border-top: 1px dotted #edb844; padding-left: 25px; }
	.depth-1 {border-top: 1px dotted #edb844;}
	.commentmetadata {clear: left; padding-top: 10px;}
	.commentmetadata a {text-decoration: none; font: 12px Arial; color: #8e8361;}
	.reply {padding-bottom: 10px;}

.commentlist - список комментариев (в теге <ol></ol> - см. comments.php выше);

.vcard - обертка для автора;

.fn - собственно автор;

.says - текст “Сказал”;

.comment - каждый комментарий лежит в теге <li></li> с таким классом;

.children - вложенный комментарий в теге <ul></ul>;

.depth-1 - комментарий верхнего (первого) уровня (в теге <li></li>);

.commentmetadata - контейнер для даты и времени;

.reply - ссылка “Ответить”;

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

Оформление комментариев. Вариант 1

Оформление комментариев. Вариант 1

Если вам нужна постраничная разбивка, то заходим в админку, меню “Настройки”, пункт “Обсуждение” и ставим галочку напротив “Разбивать комментарии на страницы по 50 на каждой и по умолчанию отображать последнюю страницу. Сверху отображать старые комментарии “, где можно вместо 50 указать любое число (хоть 1 поставьте ;) ). Если вы не хотите отображать аватары, то этом пункте выберите в “Отображение аватара” -  “Не показывать аватары”.

Если вдруг после того, как вы поставили постраничную разбивку комментариев, вы видите список комментариев полностью (т.е. не по страницам), возможно в вашем файле comments.php не хватает функций <?php previous_comments_link() ?> и <?php next_comments_link() ?>. Добавьте их после

<ol class=”commentlist”>
<?php wp_list_comments(); ?>
</ol>

и вы увидите ссылки “Старые комментарии” и “Новые комментарии” (или что-то похожее по смыслу).

Вариант 2 (немного сложнее)

Каждый комментарий в своем блоке с фоном и границей. Изменяем стили из предыдущего варианта (классы используются те же)


/* styles for comments in block with background and border */
	.commentlist {border-right: 2px solid #edb844;  border-bottom: 2px solid #edb844; list-style: none; padding: 0px; }
	.vcard *{margin: 10px 10px 0px 0px;  float: left;}
	.fn {padding-top: 5px; font: normal bold 16px Georgia; color: #edb844;}
	.says {padding-top: 9px; font: bold 12px Arial;  color: #333;}
	.comment { border-top: 2px solid  #edb844; border-left: 2px solid  #edb844; background-color: #6e5f31;  padding: 10px 0px 0px 20px;}
	.comment p {margin-top: 0px; padding-right: 10px;}
	.children  { margin-top: 10px; list-style: none; padding: 0px;}
	.children .comment {background-color: #7e6f41; border: 2px solid  #edb844; border-bottom: 0px; border-right: 0px; padding-left: 25px; }
	.commentmetadata {clear: left; padding-top: 10px;}
	.commentmetadata a {text-decoration: none; font: bold 12px Arial; color: #333;}
	.reply {padding-bottom: 10px;}
	.reply a {color: #333;}

и смотрим на страницу с комментариями

Оформление комментариев. Вариант 2

Оформление комментариев. Вариант 2

Для отображения даты и времени в формате “18.02.2009 в 21:30″, а не “18 Февраль 2009 21:30″ нужно открыть файл “..\wordpress\wp-includes\comment-template.php”, найти в нем блок


<div class="comment-meta commentmetadata">
	<a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>">
		<?php printf(__('%1$s at %2$s'), get_comment_date(),  get_comment_time()) ?>
	</a>
	<?php edit_comment_link(__('(Edit)'),'  ','') ?>
</div>

и немного подкорректировать, чтобы в результате получилось так:


<div class="comment-meta commentmetadata">
	<a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>">
		<?php printf(__('%1$s at %2$s'), get_comment_date('d.m.Y'),  get_comment_time('G:i')) ?>
	</a>
	<?php edit_comment_link(__('(Edit)'),'  ','') ?>
</div>

Обратите внимание на функции get_comment_date(’d.m.Y’)get_comment_time(’G:i’), где d.m.Y - это день.месяц.год, а G:i - Часы:минуты (21:30). Регистр G:i имеет значение, если вы напишете g:i, то время будет отображаться в формате 12 часов (9:30).

Вариант 3 (еще немного сложнее, но все возможно)

Нужно сделать для каждого комментария свой бекграунд - зебра для родителей и для детей. Поскольку скопировать и вставить стили быстрее, чем править страшный и непонятный файл comment-template.php - значит применяем оформление:


/* styles for tree comments with different background for each comment 	*/
	.commentlist {padding: 0px 0px 0px 20px; }
	.commentlist li * {list-style: none; }
	.reply * {float: right; display: inline; margin : 5px; color: #584621;}
	.fn {padding-top: 5px; font: normal bold 16px Georgia; color: #edb844;}
	.vcard *{margin: 0px 10px 0px 0px;}
	.comment p {margin-top: 0px; padding-bottom: 5px;}
	.commentmetadata a {text-decoration: none; color: #584621;}
	.comment {border: 1px solid  #584621; padding: 5px;}

	.fon {background-color: #6e5f31;}
	.fon2 {background-color: #8e6306;}
	.thread-odd {background-color: #6e5f31;}
	.thread-even {background-color:  #8e6306;}

Многие из вышеописанных классов уже встречались в предыдущих вариантах. А вот четыре последних требуют некоторых пояснений.

.thread-odd и .thread-even - заложенные в вордпрессе классы, в которых можно прописать стилизацию для четных и нечетных комментариев (используются для первого уровня вложенности).

.fon и .fon2 - добавленные мною классы, которые определяют фон комментариев начиная со второго уровня.

Что нужно добавить в comment-template.php? Совсем немного. Открываем его (т.е. файл “..\wordpress\wp-includes\comment-template.php”) и находим функцию “get_comment_class“, в ней строки


// Alt for top-level comments
	if ( 1 == $comment_depth ) {
		if ( $comment_thread_alt % 2 ) {
			$classes[] = 'thread-odd';
			$classes[] = 'thread-alt';
		} else {
			$classes[] = 'thread-even';
		}
		$comment_thread_alt++;
	}

заменяем на


// Alt for top-level comments
	if ( 1 == $comment_depth ) {
		if ( $comment_thread_alt % 2 ) {
			$classes[] = 'thread-odd';
			$classes[] = 'thread-alt';

			$GLOBALS['oddcomt'] = 'fon';

		} else {
			$classes[] = 'thread-even';

			$GLOBALS['oddcomt'] = 'fon2';

		}
		$comment_thread_alt++;
	}

$GLOBALS['oddcomt'] = ‘fon’; - добавляем класс “fon”, который устанавливает цвет фона такой же как и в классе “thread-odd”;

$GLOBALS['oddcomt'] = ‘fon2′; - класс “fon2″ и класс “thread-even” задают одинаковый цвет фона для комментариев;

Что это нам дает? Теперь мы знаем отправную точку (т.е. цвет, прописанный в классе для первого уровня комментариев), нам нужно задать “противоположный” цвет (т.е. класс, устанавливающий фон для комментариев нижних уровней). Много слов, не очень понятно, но еще немного и все прояснится :)

Далее находим в этом же файле функцию “start_el” и переставляем, убираем, добавляем некоторые строки, чтобы получилось вот так:


function start_el(&$output, $comment, $depth, $args) {
		$depth++;
		$GLOBALS['comment_depth'] = $depth;

		global $backg;		

		if ("2" == $depth){
			$backg = $GLOBALS['oddcomt'];
		}		

		if (strcmp($depth,"1")>0) {
			if ("fon" == $backg ) $backg = "fon2";
			else $backg = "fon";
		}		

		if ( ! e m p t y ($args['callback']) ) {
			call_user_func($args['callback'], $comment, $args, $depth);
			return;
		}

		$GLOBALS['comment'] = $comment;
		extract($args, EXTR_SKIP);		

		if ( 'div' == $args['style'] ) {
			$tag = 'div';
			$add_below = 'comment';
		} else {
			$tag = 'li';
			$add_below = 'div-comment';
		}
?>
		<<?php echo $tag ?> <?php comment_class(e m p t y ( $args['has_children'] ) ? ' '.$backg : 'parent '.$backg) ?> id="comment-<?php comment_ID() ?>">

		<?php if ( 'ul' == $args['style'] ) : ?>
		<div id="div-comment-<?php comment_ID() ?>" >
		<?php endif; ?>

		<div class="reply">
			<?php comment_reply_link(array_merge( $args, array('add_below' => $add_below, 'depth' => $depth, 'max_depth' => $args['max_depth']))) ?>
		</div>

		<div class="comment-author vcard">
			<?php if ($args['avatar_size'] != 0) echo get_avatar( $comment, $args['avatar_size'] ); ?>
			<?php printf(__('<cite class="fn">%s</cite>'), get_comment_author_link()) ?>
		</div>

		<div class="comment-meta commentmetadata">
			<a href="<?php echo htmlspecialchars( get_comment_link( $comment->comment_ID ) ) ?>">
				<?php printf(__('%1$s, %2$s'),  get_comment_time('G:i'), get_comment_date('d.m.Y')) ?>
			</a>
		</div>

		<?php if ($comment->comment_approved == '0') : ?>
				<em><?php _e('Your comment is awaiting moderation.') ?></em>
				<br />
		<?php endif; ?>

		<?php comment_text();  ?>		

		<?php if ( 'ul' == $args['style'] ) : ?>
		</div>
		<?php endif; ?>
<?php
	}

$backg - задает цвет фона комментариев, начиная со второго уровня вложенности;

$depth - как видно из названия это глубина вложенности;

Получаем класс, если находимся на втором уровне вложенности комментариев:
if (”2″ == $depth){
$backg = $GLOBALS['oddcomt'];
}

Если не первый уровень, то меняем класс (устанавливаем “противоположный” цвет):
if (strcmp($depth,”1″)>0) {
if (”fon” == $backg ) $backg = “fon2″;
else $backg = “fon”;
}

После всех совершенных действий вы увидите такие комментарии:

Оформление комментариев. Вариант 3

Оформление комментариев. Вариант 3

Вы можете скачать архив styling-tree-comments-files, в котором находятся отредактированные файлы  comments.php, comment-template.php и style.css. В последнем “активными” являются стили для последнего варианта оформления, остальные закомментированы.

Приведенные выше способы стилизации древовидных комментариев наглядно демонстрируют только три из множества вариантов оформления.

Возможно, в скором времени плагины для древовидных комментариев будут больше “окрылять” блогеров (и не только) и не придется им вручную подкручивать и дорабатывать, а достаточно будет установить и немного настроить “для себя”.

Комментарии

m1kola

в 13:30, 12.04.2009

Спасибо.
Эта и первая статья мне очень помогли больше разобраться.

Но у меня есть одно замечание.
ИМХО, не стоит редактировать файлы движка. Ибо при каждом обновлении нужно будет редактировать движок.

Если я не ошибаюсь, это всё можно сделать как описано в кодексе: http://codex.wordpress.org/Template_Tags/wp_list_comments

Т.е. берём
и в файле functions.php добавляем свою функцию с именем mytheme_comment. А там уже можно указать все нужные параметры.

Быть может я ошибаюсь…

Павел Башмаков

в 14:56, 12.04.2009

To m1kola:
Нет, вы не ошибаетесь. Правильно так, как вы и говорите - функции добавлять в functions.php, который локальный для темы. Причем всегда надо пытаться всеми силами избежать ускушения править код движка.

Анна Шабан

в 15:43, 14.04.2009

To m1kola:
Все правильно. Обычно я стараюсь следовать этому принципу, но во время написания статьи было достаточно другой работы, отнимающей много времени, и этот вариант показался более простым и быстрым. В скором времени скорректирую статью.

dottefpodia

в 4:52, 19.05.2009

Работаю менеджером. Хочу сделать интернет магазин. Порекомендуйте человека или организацию, кто поможет мне в этом. Главное чтоб человек, который его делает был адекватный и недорого.

Павел Башмаков

в 16:27, 21.05.2009

Можно попробовать поискать на developers.org.ua, там много разных людей, которые интересуются и проектами и программистами. В целом, очень хороший украинский ресурс для программистов и всего, что с ними связано.

Kuralesov

в 16:24, 04.09.2009

А почему у вас так мало читателей, по мне отличный блог.

Mixa

в 21:21, 23.09.2009

Я пока заюзал дефолтные стили с кубрика, во всех браузерах все класно, кроме, конечно же, всенародно любимого 6 эксплорера..
Аватар и дата комментария сьежают. Знаю что проблема из-за position:absolute, но как пофиксить — не знаю… :(

Пример: babay.com.ua/?p=6#comments

VasyaSeoEpta

в 3:43, 23.10.2009

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

SesShoord

в 5:49, 22.12.2009

Кто оставил: Власова Юлия
Город: Москва
Телефон: 7657090
E-mail: paulpc@mail.ru

Тема сообщения:
Составляем список кидал! Кто пострадал от таких уродов как paulpc@mail.ru, кличка paulpc24, зовут Павел, проживает в Германии, Ruhstorf торгует и разводит на Молоток. ру и др. он-лайн торговых площадках. Втюхивает ДЕФЕКТНЫЙ товар, выдавая его за рабочий! Кинул множество людей на Ebay.de (ник: paschkab) - за что его там и заблокировали! Постоянно меняет имена - БУДЬТЕ БДИТЕЛЬНЫ! Последнее имя: boikopavel@mail.ru, где “Бойко” - это его настоящая фамилия.
Пишите кого он уже кинул - внесём в базу и постоянно будем выкладывать на всех досках объявлений.
Также обращаем: особое внимание! - не заключать с ним сделки дороже 30 ЕВРО - ОН ОБЯЗАТЕЛЬНО ВАС КИНЕТ, поскольку у него 3-е маленьких детей, а он безработный иммигрант из Казахстана, которому нужно прокормить этих малышей. И, поверьте, он сделает все, чтобы купить хотя бы какую-нибудь дешевую сухую смесь для детишек.

AleksandrBank

в 18:37, 04.01.2010

Продаем кредитные карты Visa с балансами 800$-5000$, доставка в любой регион, гарантия, ищем постоянных партнеров, кардинг взлом кредитных карт, дамп с пин кардинг, дампы карт, дампы кредитных карт, продам дампы карт, пишите нам на емайл kredstore@gmail.com

RusSpeeva

в 16:39, 05.03.2010

Hello all

Мне посоветовали сделать ландшафтный дизайн. Порекомендуйте пожалуйста какой камень лучше использовать? В какую фирму лучше обратится, чтобы качественно сделали?

Оставить комментарий