
Ввиду повального незнания о возможностях темизации Друпала и использования Form API, большая часть разработчиков лишается возможности делать приятные сайты.
Данная статья призвана возбудить все-таки у людей интерес к использованию средств темизации.
Недавно я был участником дискуссии на тему идеальной формы комментирования. Так вот, помните на что похожа стандартная друпаловская форма комментариев?
Эта форма содержит в себе абсолютно все минусы, которые могут быть. Она громоздка, скучна и непонятна рядовому пользователю.
А на что в действительности способен Друпал?
Для начала, немного теории. Любую форму в пятой версии Друпала можно темизировать создав в файле шаблона template.php функцию phptemplate_FORM_ID($form), где FORM_ID - это идентификатор формы.
Форма комментирования имеет id равный comment-form, поэтому, для нее функция темизации будет называться phptemplate_comment_form:
function phptemplate_comment_form($form) {
}
Если вы все сделали правильно, то после того как вы впишите эту функцию в свой template.php, на сайте сразу пропадут все формы комментирования.
Дальше стоит разобраться, что находится в переменной $form, которая находится в параметрах функции. Вписываем волшебный print_r:
function phptemplate_comment_form($form) {
print_r($form);
}
После этого вы увидите кучу всякого кода сверху экрана. Если посмотреть в исходный код страницы, выглядеть это будет примерно так:
Это и есть массив формы. Справка по каждому из полей.
А теперь, к делу:
function phptemplate_comment_form($form) {
// убираем имя автора (если юзер залогинен)
if ($form['_author'])
unset($form['_author']['#type']);
// убираем все форматы форматирования из формы
unset($form['comment_filter']['format']);
// формируем один единственный формат ввода
// (будет сформирован формат, который выбран в админке по-умолчанию)
// тут же мы избавляемся и от ссылки "Подробнее о форматировании"
// просто не включив ее в состав формы
$form['comment_filter'][1] = array(
'#type' => 'value',
'#value' => variable_get('filter_default_format', 1)
);
$tips = _filter_tips(variable_get('filter_default_format', 1), FALSE);
$form['comment_filter']['format']['guidelines'] = array(
'#title' => t('Formatting guidelines'),
'#value' => theme('filter_tips', $tips, FALSE, $extra),
);
// убираем поле "домашняя страница" с формы
// так как в большинстве случаев оно лишнее
unset($form['homepage']);
// скрываем подпись у главного поля комментирования
$form['comment_filter']['comment']['#title'] = '';
// устанавливаем меньшее количество строк у поля
$form['comment_filter']['comment']['#rows'] = '7';
// это условие спасает нас, в случае залогиненного юзера
// (у залогиненных нет этих полей)
if (($form['mail'])&&($form['name'])) {
// оборачиваем всю правую часть в теги
// ниже, в описании стилей можно увидеть, что класс side
// выравнивается по правому краю
$form['name']['#prefix'] = '<div class="side">';
$form['name']['#suffix'] = '</div>';
$form['mail']['#prefix'] = '<div class="side">';
$form['mail']['#suffix'] = '</div>';
// оборачиваем поле для ввода в свои теги
$form['comment_filter']['#prefix'] = '<div class="main">';
$form['comment_filter']['#suffix'] = '</div>';
}
// оборачиваем в теги надпись о форматировании
// обратите внимание на css свойства класса guidelines
$form['comment_filter']['format']['guidelines']['#prefix'] =
'<div class="guidelines nolink">';
$form['comment_filter']['format']['guidelines']['#suffix'] = '</div>';
//подключаем файл с js-блиотекой на страницу
drupal_add_js(path_to_theme().'/comments.js');
//цепляем вызовы js-функций под код нашей формы
$form['#suffix'] .= '<script type="text/javascript">'.
'insertGuidelinesLink("'.t('What can I enter?').'");'.
'replaceButtons("#comment-form");'.
'</script>';
//выводим форму
$output .= drupal_render($form);
return $output;
}
JavaScript:
// файл comments.js в директории вашей темы
// (создать, если потребуется)
function replaceButtons(form) {
$(form+' .form-submit').each(function(){
id = $(this).attr('id');
text = $(this).attr('value');
$(this).css('display','none');
$(this).after('<a class="'+id+' button form-submit" href="#"><span>'+text+'</span></a>');
$('a.'+id).click(function(){
$('#edit-op').attr('value',$(this).text());
$(form).submit();
return false;
});
});
}
function insertGuidelinesLink(title) {
$('.guidelines.nolink').before('<a href="#" id="guidelink">'+title+'</a>');
$('.guidelines.nolink').removeClass('.nolink');
$('#guidelink').click(function(){
$(this).slideUp('fast');
$('.guidelines').slideDown('fast');
return false;
});
}
стили:
.main{
margin:0px 250px 0 0;
}
.side{
width:230px;
float:right;
clear:right;
margin:0 0 10px 0;
}
.main .form-item,.side .form-item{
margin:0;
}
.side input.form-text{
width:100%
}
#guidelink{
font-size:10px;
text-decoration:none;
border-bottom:dashed 1px;
}
.guidelines{
display:none;
margin:10px 0 0;
}
Итого, форма будет выглядеть так:

Красота?
Решение полностью Drupal-правильное, W3C-валидное и кросс-браузерное.
P.S. Cовсем забыл про капчу. Пользуйтесь моей скрытой капчей и будет вам счастье.
39 комментариев
# | Aurum
Все четко. Спасибо! :)
# | netbear
Посмотрел, ничего особенного в плане темизации не увидел...Если уж сказал, что супертемизация, так хоть кнопки на красивые поменяй, посмотри на них повнимательней, явно выпадают из общего дизайна.
# | fun_vit
супер. спасибо...
# | Другой Славянск-на-Кубани
Спасибо за хорошо комментрированный код.
# | ingolmo
Здорово. А не подскажите можно ли и если можно то как в эту форму добавить авторизацию по openid?
# | neochief
На сколько мне известно, готового решения нет пока. Но, думаю, это тоже реализуемо.
# | igorek
А чекбокс "оповещать меня по почте..." разве есть в стандартной форме добавления комментариев в друпале, я что-то такого не нашел у себя?
Если есть, то скажите где такая настройка делается, а если нет, то как это сделано.
Спасибо!
# | Дмитрий
Спасибо, стал немного умнее :)
# | Влад Савицкий
Форматы ввода скрываются и показывается только один - который выбран по умолчанию, а остальные оказываются недоступны...
Это так задумано или всё же ошибка?
# | neochief
Это так задумано. Если это не требуется, никто не заставляет их скрывать. Но в моей практике еще не было сайтов, где стоило оставлять форматы ввода с выбором (разве что для административных аккаунтов), а рядовой юзер их или не замечает или не понимает.
# | Seo оптимизатор
А я никакой разницы не вижу. Мне что старая отправка комментариев, что новая.
# | miko
Спасибо за интересную статью и красивый дизайн. Долго бьюсь с формой логина, так и не удалось найти способ как ее темизировать, по человечески. Нет ли каких-нибудь мыслей по этому поводу? Буду очень признателен!
# | neochief
Все то же самое. Вот, к примеру, добавление ссылки на "Забыли пароль?" в форму логина:
# | miko
Спасибо за оперативный ответ, neochief!
Такой функции я не нашел... В user.module есть user_login_block() собственно там и определяется форма, Насколько я понимаю... но она разве "темабильна"? Я читал где-то, что только theme.... можно оверрайдить в template.php. Это не правда? Я пробовал ее переопределиь, но при этом перестает правильно работать модуль. Например форма постоянно висит на экране, даже если User зашел. Нормальная форма исчезает. Или вообще может не логинится...
# | neochief
... А если почитать внимательно статью, то можно найти такие строки:
Любую форму в пятой версии Друпала можно темизировать создав в файле шаблона template.php функцию phptemplate_FORM_ID($form), где FORM_ID - это идентификатор формы.
# | Андрей
красиво сделано. решпект
# | Ukrnet
Реализация нормальная, но!
Вот, например для вашего сайта это не удобно, т.к. после нажатия таба, попадаешь на форму поиска и + на кнопку поиска, а только потом на формы имени и т.д.
# | neochief
Наконец понял, что вы имеете в виду. Проблему здесь устранил, но в статью добавлять не буду, чтобы не усложнять слишком. Проблема решается помещением дополнительных полей физически под текстовое поле комментария (в статье, они в реальности поверх, поэтому и происходит такой конфуз с tab-order'ом). Это достигается изменением веса этих полей, к примеру:
Еще одним способом является установка атрибута tabindex у всех элементов формы, делается это так:
К сожалению, при изменении tabindex почему-то перестал работать BUEditor (кнопочки сверху поля), поэтому я прибегнул все-таки к первому способу. А вы уже выбирайте по ситуации ;)
# | Gena
Это просто праздник! Спасибо огромное. Буду пробовать.
А еще уроки будут?
# | neochief
будут, но сроки не обещаю :)
# | miller
да, симпатично, но юзабельнее ли?
исходный вариант, как минимум, обычнее/привычнее
# | neochief
а вы спросите обычного человека про исходный вариант ;)
# | Гость
а можно ли вставить картинку со своего диска?
# | worona
Первая тема была красивая..., раньше.
"видешь на рисунке" - исправьте на "видишь" - АНТИ-СПАМ
# | Жора
Очень крутая форма получилась
# | Лера Мулина
Вот хочу Вас спросить: как такую форму можно сделать. Что-то я в статье не нашла по этому информации. И еще, подскажите, пожалуйста, как сделать то, что реализовано у Вас. Ответы на комментарии располагаются под ними с небольшим сдвигом вправо. Понимаю, что это через css, но пока не могу найти, где именно.
# | Лера Мулина
А, все. Нашла. В управлениях комментариями. Древовидный развернутый список. Все оказалось проще, чем я думала :)
# | antoha
"Любую форму в пятой версии Друпала можно темизировать создав в файле шаблона template.php "
Под шестеркой производил кто-нибудь эти манипуляции?
# | antoha
Видимо вопрос с темизацие стоит в 6ке очень остро...
# | Роман
В друпал 6 добавьте функцию (вместо andreas02 название вашей темы)
function andreas02_theme() {
return array(
// The form ID.
'comment_form' => array(
// Forms always take the form argument.
'arguments' => array('form' => NULL),
),
);
# | Михаил
Это больше чем о форме комментирования. Здесь затронуто несколько вещей, которые я не мог понять даже прочитав книгу.
Ваше объяснение куда лучше и внятнее. Огромное спасибо.
# | Kamil
Согласен что форма выглядит чище без лишних наворотов. Вопрос такой, а где взять/купить такую же форму?
# | Юрий
Как убрать поле "ТЕМА" ? Что бы не создавались нелепые огрызки от первых слов комментария в качестве темы?
# | Dmitry
В папкой с темой откройте файл comment.tpl.php и удалите <?php print $title ?>
# | Александр
а как у вас сделана форма комментирования? (кстати тут скрыта каптча Анти-спама... по крайней мере в FF она глючит если сделать несколько раз просмотр и потом добавить)
# | Александр
почитал про нивидимую каптчу и понял, что видимо это был кеш... браузера.. но все равно как то не очень хорошо от того, что после нажатия кнопки "добавить комментарий" - мне выходит сообщение, что у меня каптча введена неверно :-( я начал было её искать и нашел в коде... :-)
хотел уточнить - интересует вот такие вот AJAX фичи для комментов... как это у вас сделано?
# | Александр
откуда у вас модуль ajax_comment? пожалуйста поделитесь с сообществом. искал его на drupal.org - и все что нашел - ajax_comment.txt.tar модуль ajax_comment 5.x-0.0dev - версия никакая, ну а в списке проектов друпала такого модуля и подавно нет. Ведь модуль то существует, почему его нигде нет? или я не там искал...
# | neochief
Единственной причиной почему на д.орге еще не сделали нормальной реализации данного модуля, является невозможность "врезаться" в нужный функционал комментов без патчей ядра. Исходя из этого, автору [мне] не хочется отгрести задач по поддержке. Поэтому модуль остается в личной коллекции, а также идет в бонус сайтам моего производства. Может быть модуль появится на публике позже, и, возможно, не на лицензии GPL, хотя, все может быть.
# | Александр
Спасибо за подробный ответ! Жаль! ну значит будем пробовать написать свой модуль ajax_comment ;-) и спотыкаться о всем (кто разрабатывал подобный модуль) известные грабли.. как только изобретем - можно будет (если есть желание) сравнить и улучшить оба "велосипеда".
Оставить комментарий