УрокПерекрытие и изменение форм на сайте

Не секрет, что в Друпале огромное количество форм - логин, отправка контактов, создание материала и прочее. Друпал предоставляет возможности для разработчика в своей теме перекрыть любую форму на сайте.

Лично мне знание о перекрытии форм неоднократно облегчало работу, ибо зачастую в техническом задании сайта (или дизайне) есть мелочи, которые сделать просто необходимо, но не всегда знаешь как это сделать. А сделать это очень просто - сначала мы указываем в template.php, что форма будем перекрыта - а потом пишем функцию, которая изменяет её. Теперь о том, как это сделать на практике.

У каждой формы есть свой уникальный form_id. Чтобы перекрыть форму необходимо его узнать. Посмотреть его можно в исходном коде страницы - он спрятан в скрытый input с именем form_id. Лично я всегда использую firebug (плагин firefox), чтобы быстро найти form_id. Можно пользоваться и другими средствами браузера - например, в Chrome и последние версии Opera уже встроены так называемые "Developer tools", которые реализуют нечто наподобие firebug'a, только немного хуже (имхо). В общем, будем считать что каким-то образом этот form_id был найдет. Далее нас интересует значение value у этого input'a:

1_2.png

Далее открываем template.php и пишем туда следущее:

function ИМЯТЕМЫ_theme() {
  return array(
    'lesson_node_form' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}

Эта функция говорит Друпалу, что разработчик собирается изменять форму, у которой form_id равен lesson_node_form.

Теперь о функции, которая изменяет форму. Строится она по принципу ИМЯТЕМЫ_FORM_ID и получает саму форму в качестве параметра функции. На для нашего примера это будет выглядеть вот так:

function ИМЯТЕМЫ_lesson_node_form($form) {
  // здесь совершаем некие действия над формой
  // если неизвестно содержимое формы - пользуемся
  // функцией print_r($form) и смотрим исходный код страницы 
  // т.к. там этот вывод будет структурирован
 
  //после всех изменений возвращаем форму, предварительно отрендерив её
  return drupal_render($form);
}

Вот и вся хитрость. Работать с формой согласно Forms API Друпала.

Комментарии

Аватар пользователя als
als написал:

Наконец-то я нашел сайт, где доступным языком описана темизация Drupal'а не на уровне *.tpl.php, а на уровне препроцессинга и переопределения форм.
Спасибо! После прочтения ваших статей понимаю, что все, что я знал до сих пор о темизации - это алгебра, а что узнал сейчас - высшая математика.

08.05.2011 20:11
Аватар пользователя Spleshka
Spleshka написал:

Я рад что вам нравится :)

08.05.2011 20:18
Аватар пользователя Alexey
Alexey написал:

Спасибо большое, очень полезно!
А можете рассказать о form alter? и есть ли отличия для d6/d7?

13.05.2011 03:44
Аватар пользователя ден
ден написал:

Привет!
Подскажи пожалуйста как темизировать страницу регистрации. Везде в примерах про страницу логина написано, а мне нужно страницу регистрации темизировать - добавить туда доплнительные поля (кроме логина и мыла добавить фио и еще пару текстовых полей).
Модуль контентпрофайл не подходит, потому что он не на страницу регистрации добавляет поля, а в профиль - т.е. после регистрации пользователя нужно заставлять заходить в профиль. а это неудобно в моем случае.
Или есть другой модуль для этого?

01.06.2011 11:18
Аватар пользователя Spleshka
Spleshka написал:

В стандартную сборку друпала входит модуль profile. Включи его - он даёт возможность добавлять дополнительные поля к форме регистрации. У меня на сайте регистрация именно с помощью него и сделана.

01.06.2011 18:05
Аватар пользователя merezha
merezha написал:

Я правильно понимаю, что для новых форм использование хука theme_NAME_form() предпочтительней?

30.06.2011 12:38
Аватар пользователя Spleshka
Spleshka написал:

Что значит для новых форм? Вы имеете ввиду для создания форм?

30.06.2011 13:46
Аватар пользователя merezha
merezha написал:

Да, для создания новых

03.07.2011 14:52
Аватар пользователя Spleshka
Spleshka написал:

Для создания новых форм можно использовать любое название функции, хоть function blabla() { //form }

27.07.2011 00:01
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

Fatal error: Cannot redeclare hts_theme() (previously declared in....и т.д.
такое получается при темизации например формы поиска и формы авториза
грубо говоря я регестрирую:

function ИМЯТЕМЫ_theme() {
return array(
'lesson_node_form' => array(
'arguments' => array('form' => NULL),
),
);
}

а затем

function ИМЯТЕМЫ_theme() {
return array(
'my_new_form' => array(
'arguments' => array('form' => NULL),
),
);
}

вот такая ошибка вылазит, мол функция определена уже выше. Как быть с этим?
b dskf

12.07.2011 00:48
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

Что никто не столкнулся с этим или не темизировал более одной формы на своем сайте???

12.07.2011 12:21
Аватар пользователя Тайный поклонник
Тайный поклонник написал:
function yourthemename_theme(){
  return array(
    'search_block_form' => array(
      'arguments' => array('form' => NULL),
    ),
	'user_login_block' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}
function yourthemename_search_block_form($form){
$form['search_block_form']['#title'] = t('');
$form['search_block_form']['#size'] = 15;
$form['submit']['#type'] = 'image_button';
$form['submit']['#src'] = drupal_get_path('theme', 'hts').'/images/search-btn.png';
$form['submit']['#attributes']['class'] = 'subbutton';
 $form['search_block_form']['#value'] = 'поиск по сайту';
  $form['search_block_form']['#attributes'] = array(
	'onBlur'=> "if (this.value.length == 0) {this.value='{$form['search_block_form']['#value']}'}",
	'onFocus'=> "if (this.value== '{$form['search_block_form']['#value']}') {this.value=''}"
  ); 
	return drupal_render($form);
}
 
function yourthemename_user_login_block($form) {
 
  unset($form['name']['#title']);
  unset($form['pass']['#title']);  
 
  $form['name']['#value'] = 'Имя пользователя';
  $form['name']['#attributes'] = array(
	'onBlur'=> "if (this.value.length == 0) {this.value='{$form['name']['#value']}'}",
	'onFocus'=> "if (this.value== '{$form['name']['#value']}') {this.value=''}"
  ); 
  $form['submit']['#value'] = 'Войти';
 
  return drupal_render($form);
}

Это темизация поиска и формы входа. Все что касается регистрации для function yourthemename_theme() пишите в одном массиве, так проще будет найти убрать или поправить.

12.07.2011 12:52
Аватар пользователя Spleshka
Spleshka написал:

Здесь 2 раза объявляется одна и та же функция. Должно быть так:

function ИМЯТЕМЫ_theme() {
  return array(
    'lesson_node_form' => array(
      'arguments' => array('form' => NULL),
    ),
    'my_new_form' => array(
      'arguments' => array('form' => NULL),
    ),
  );
}
19.07.2011 14:02
Аватар пользователя one
one написал:

Дополните статью вариантом для 7 версии , с учетом изменившегося api .

15.11.2011 10:25
Аватар пользователя Tyaro
Tyaro написал:

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

05.02.2012 20:32
Аватар пользователя Spleshka
Spleshka написал:

В template.php надо писать код, который будет взаимодействовать с формами. Системное имя темы - это название файла.info (например, garland.info - название темы garland).

06.02.2012 20:43
Аватар пользователя Tyaro
Tyaro написал:

Спасибо, работает. Проблема была в том что в названии темы был разделитель точка. Только изучаю php

07.02.2012 19:09
Аватар пользователя Tyaro
Tyaro написал:

В идеале хотелось бы получить такую тему для отправки коментов как у Вас на сайте, как темизировать вывод комментариев мне понятно, а вот с вводом огромные проблемы. Друпал 6

05.02.2012 20:49
Аватар пользователя AmiGator
AmiGator написал:

действительно, для Drupal 7 хотелось бы. что то не получается ничего :(

11.02.2012 21:00
Аватар пользователя Spleshka
Spleshka написал:

Для седьмого Друпала в теме можно указывать hook_form_alter(), которым можно изменять формы напрямую.

13.02.2012 15:54
Аватар пользователя AmiGator
AmiGator написал:

насколько я понимаю, действовать нужно как описано в статье http://drupal.org/node/154137 так вот менять стандартную форму поиска у меня получилось, а вот альтернативу в виде модуля search api который создает форму search_api_page_search_form_search не получается :(
делаю по аналогии
$form['search_api_page_search_form_search']['#size'] = 40;
и ничего не меняется :(

13.02.2012 20:36
Аватар пользователя Spleshka
Spleshka написал:

В данном случае по аналогии не получится. Сделайте debug($form) и посмотрите какие элементы находятся внутри массива формы.

14.02.2012 04:07
Аватар пользователя vegas
vegas написал:

Опечатка (предложение перед последним примером кода): "На для нашего примера это будет выглядеть вот так". Видимо, надо "Но" ;)

08.05.2013 02:46

Комментировать