УрокСоздание отдельного шаблона страницы для разных типов ноды

По умолчанию в друпале все страницы выводятся через шаблон page.tpl.php. Можно создавать шаблоны созданные по такому принципу: если путь выглядит как имясайта/node/10, то шаблон будет выглядеть как page-node-10.tpl.php. Если создать шаблон page-node.tpl.php, то все страницы, лежащие "ниже" урла имясайта/node/ будут автоматически перекрыты этим шаблоном.

То есть, если в корне вашей темы лежит файл page-node-tpl.php и выводит только переменную $content, то на странице абсолютно любой ноды будет выведен тольько контент, без колонок, табов и прочих аттрибутов.

Этот принцип работает для любого адресса, и любого уровня вложенности в него. Однако давайте рассмотрим неординарный вариант: допустим, перекрыть надо только страницы нод определённого типа материала. Для этого потребуется поместить в template.php следующий код:

/**
 * Implementation of template_preprocess_page().
 */
function ИМЯТЕМЫ_preprocess_page(&$variables) {
  if (arg(0) == 'node' && is_numeric(arg(1))) {
    $node = node_load(arg(1));	
    $sug[] = 'page-node-type-' . $node->type;
    $variables['template_files'] = $sug;
  } 
}
?>

Теперь друпал научится понимать шаблоны, построенные по любому типу ноды (если вы их перекрыли).

Пример: для типа материала story шаблон будет выглядеть так:

page-node-type-story.tpl.php

Сейчас я немного поясню код. Для этого мне придётся рассказать о функции arg(). Она возвращает составные части текущего урла страницы. То есть для страницы http://drupalace.ru/node/add/lesson оно вернёт:

arg(0) вернёт node
arg(1) вернёт add
arg(2) вернёт lesson

Значит, этой строкой я убеждаюсь, что нахожусь на странице с нодой (т.к. страница с нодой строится по урлу имяСайта/node/нид):

if (arg(0) == 'node' && is_numeric(arg(1))) {

Далее всё вообще прозрачно:

$node = node_load(arg(1));  //загружаю ноду, т.к. arg(1) на этой странице будет равен nid ноды	
$sug[] = 'page-node-type-'.$node->type; //создаю шаблон как мне хочется
$variables['template_files'] = $sug;  //передаю записанный шаблон для его обработки

Да, и ещё - arg() возвращает ДЕЙСТВИТЕЛЬНОЕ значение урла, т.е. даже если у вас на сайте стоит модуль pathauto и страница ноды выглядит не по шаблону имяСайта/node/нид, то arg() всё равно будет возвращать именно значения node и нид.

Применяется это к любым шаблонам и страницам. Просто я делал всё на примере node.

Вот и вся хитрость. Таким же образом можно создать себе шаблоны на абсолютно любой случай жизни :)

UPDATE

Код вывода немного оптимизировался:

/**
 * Implementation of template_preprocess_page().
 */
function ИМЯТЕМЫ_preprocess_page(&$variables) {
  if (isset($variables['node']) && $variables['node']->type) {
    $variables['template_files'][] = 'page-node-type-' . $variables['node']->type;
  } 
}

Комментарии

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

+1 Спасибо. В закладки однозначно.

07.12.2010 10:21
Аватар пользователя torvild
torvild написал:

Вот спасибо!
Теперь всё получилось!:HAPPY:

07.12.2010 14:42
Аватар пользователя Dmitrii
Dmitrii написал:

Можно не париться с arg() и node_load() - в ИМЯТЕМЫ_preprocess_page в $variables['node'] должен сидеть объект текущей ноды, если страница нодовая, а не вьюсовая или ещё какая.

PS: Какая-то подозрительно знакомая картинка в материале :)

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

Да, посмотрел внимательнее на апи друпале - действительно там может присутствовать в переменных объект ноды :) Спасибо. А картинку у тебя спёр, но самостоятельно перевернул её =)

08.12.2010 14:06
Аватар пользователя Евгений
Евгений написал:

Подскажите, пожалуйста, если я не сделаю function ИМЯТЕМЫ_preprocess_page(&$variables) в template.php , то я никак не смогу перекрыть page.tpl для определенного node_type?
Я сейчас курю тему от Fusion. Поэтому вопрос - необходимо ли "доделывать" их template.php или возможность перекрывать уже есть?

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

Страницу для определённого типа ноды - только перекрывать. Стандартно оно не подцеепится. Ну вам надо просто найти в template.php функцию fusion_preprocess_page и добавить туда код, предоставленный в статье

12.03.2011 18:14
Аватар пользователя Евгений
Евгений написал:

Спасибо!
Кстати, уведомления об ответе на мой коммент по почте можно как-нибудь включить?

14.03.2011 11:30
Аватар пользователя StranikS
StranikS написал:

Уменя задача такого рода, есть меню, каждая ссылка ведет на заранее созданную страницу, каждая страница содержит свой вид информации, например На странице "Каталог предприятий" должен выводится список всех зареганных на бирже предприятий!
Как мне быть? Писать новый модуль или еще что то, просто когда я по детски наивно вставил в ноду код срапечатки переменной ncotent яне увидел ничего, да и как я потом прочитал писать в ноду динамику может вылезти потом боком...

25.03.2011 13:51
Аватар пользователя Spleshka
Spleshka написал:

Вам нужно осваивать модуль VIEWS. Для ваших целей - незаменимая вещь!

27.03.2011 04:04
Аватар пользователя Захарка
Захарка написал:

помогите пожалуйста разобраться. Делаю все как надо. Перепроверил все 1000 раз. НО почему то не работает. в чем может быть косяк? а я пока перепроверю 1001 раз....

21.04.2011 16:27
Аватар пользователя Spleshka
Spleshka написал:

Кэш чистили? Название функции меняли?

22.04.2011 18:04
Аватар пользователя Денис
Денис написал:

да, и у меня не работает :(

у меня урл страницы : сайт.ru/content/proba
это тип материала с машинным именем: page-w

вставляю в темплейт.пхп код такой:

function dimkarta_preprocess_page(&$variables) {
 
  if (arg(0) == 'content' && is_numeric(arg(1))) {
	$node = node_load(arg(1));	
	$sug[] = 'page-node-type-'.$node->type;
	$variables['template_files'] = $sug;
  } 
}

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

page-content-proba.tpl.php
page-node-type-page_w.tpl.php

не работает :(.страница выводится стандартным шаблоном.

22.04.2011 10:23
Аватар пользователя Spleshka
Spleshka написал:

content/proba - этот урл через arg() вы не получите. Функция arg() по прежнему получает 'node' и её айди. Используйте вариант который в статье, он вам подойдёт

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

помоему в вашем случае:
1. должно быть page-node-type-page_w.tpl.php
2. ненадо проверять на content. оставте node. контент помоему используется при pathauto, который заменяет такого плана адрес node/2234 на content/proba

22.04.2011 13:09
Аватар пользователя hohol
hohol написал:

вопрос к автору. а в чем отличия будут если создать файл node-ТИП_КОНТЕНТА.tpl.php ???

22.04.2011 13:19
Аватар пользователя Spleshka
Spleshka написал:

сейчас перекрывается СТРАНИЦА вывода для материала, а node-тип_контента.tpl.php перекроет только вывод МАТЕРИАЛА. Разница, думаю, очевидна.

22.04.2011 18:06
Аватар пользователя Захарка
Захарка написал:

подскажите как сделать шаблон для страницы если путь у меня по терминам идет... taxonomy/term/[id]

22.04.2011 16:18
Аватар пользователя Spleshka
Spleshka написал:
<?php
/**
 * implementation of template_preprocess_page()
 */
function ИМЯТЕМЫ_preprocess_page(&$variables) {
 
  if (arg(0) == 'taxonomy' && arg(1) == 'term' && ctype_digit(arg(2))) {
	// перекрываемый шаблон тут
  } 
}
?>
22.04.2011 18:07
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

А какое имя файла tpl.php будет в данном случае?
А может еще подскажите как сделать отдельный шаблон для пункта меню http://сайт/пункт_меню/....... и там, где в url встречается "пункт_меню", был отдельный page.tpl.php. Возможно ли привязаться к urlом pathauto?

08.08.2011 02:43
Аватар пользователя Spleshka
Spleshka написал:

Какой пропишите - такой и будет. Например

function ИМЯТЕМЫ_preprocess_page(&$variables) { 
  if (arg(0) == 'taxonomy' && arg(1) == 'term' && ctype_digit(arg(2))) {
    $variables['template_files'][] = 'page-taxonomy-term-'. arg(2);
  } 
}

В этом случае шаблон будет page-taxonomy-term-НОМЕР_ТЕРМИНА.tpl.php. Можно ли привязаться урлом к pathauto - да, но придётся делать дополнительный запрос в базу, проверяя, есть ли у текущей страницы синоним от pathauto.

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

Кстати, что именно вам надо перекрыть-то?

22.04.2011 18:07
Аватар пользователя Тайный поклонник
Тайный поклонник написал:
<?php
function themename_preprocess_page(&$variables) {
  if ($variables['node']->type != "") {
    $variables['template_files'][] = "page-node-" . $variables['node']->type;
  }
}
?>
http://drupal.org/node/249726
23.04.2011 00:42
Аватар пользователя Villain
Villain написал:

А как в Drupal 7 организовать свой page-тип_материала.tpl.php ?

26.04.2011 16:58
Аватар пользователя Spleshka
Spleshka написал:
/**
 * implementation of template_preprocess_page()
 */
function ИМЯТЕМЫ_preprocess_page(&$variables) {
 
  if (isset($variables['node']) && $variables['node']->type) {
	$variables['theme_hook_suggestions'][] = 'page-'. $variables['node']->type;
  } 
}

Шаблон для типа материала page будет page-page.tpl.php. Я всё же рекоммендую использоваеть такую функцию:

/**
 * implementation of template_preprocess_page()
 */
function ИМЯТЕМЫ_preprocess_page(&$variables) {
 
  if (isset($variables['node']) && $variables['node']->type) {
	$variables['theme_hook_suggestions'][] = 'page-node-type-'. $variables['node']->type;
  } 
}

В этом случае для типа материала page шаблон будет page-node-type-page.tpl.php. Это предотвращает случай, когда у вас на сайте есть, например, страница /news и тип материала news (шаблон для них в первом случае будет одинаковый page-news.tpl.php) - вы (или другой разработчик) можете запутаться.

26.04.2011 19:32
Аватар пользователя Villain
Villain написал:

Спасибо огромное. Теперь когда я почти профи в создании page-тип_материала.tpl.php, ) позволю себе внести небольшую поправку:

  if (isset($variables['node']) && $variables['node']->type) {
	$variables['theme_hook_suggestions'][] = 'page__node_type_'. $variables['node']->type;
  }

Знак - надо заменить на _ . И тогда получится вот такой шаблон page--node-type-news.tpl.php

27.04.2011 13:58
Аватар пользователя Жека
Жека написал:

Спасибо и от меня - предлагаю этот коммент про drupal 7 - поместить в саму статью

30.08.2012 10:35
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

Спасибо! Отличный пример и все получилось, но!
Данный код так же темизирует редактирование материала. Отредактировать не получится, если нет print $content но я в своих шаблонах не использую эту строку и все вывожу вьюсами.
И как быть?
Нашел статью http://drupal.org/node/154091 что только не пробовал, не получатся вывести страницу редактирования :(

17.07.2011 23:55
Аватар пользователя Spleshka
Spleshka написал:

А быть вот таким образом:

/**
 * implementation of template_preprocess_page()
 */
function ИМЯТЕМЫ_preprocess_page(&$variables) {
 
  if (isset($variables['node']) && $variables['node']->type && !arg(2)) {
	$sug[] = 'page-node-type-'.$variables['node']->type;
	$variables['template_files'] = $sug;
  } 
}
19.07.2011 14:08
Аватар пользователя Тайный поклонник
Тайный поклонник написал:

Спасибо, буду пробовать!
Пока вышел из положения таким костылём: if (arg(2)=='edit'){ print $content }
А вообще- спасибо за сайт! Предлагаю еще осветить тему views, Все по созданию и шаблонизации т.к. написать можно ну ооочень много всего интересного.

21.07.2011 21:27
Аватар пользователя Neltharian
Neltharian написал:

Не подошел мне ваш вариант (6,24) нашел вот тут то что у меня сработало. чтоб не путатся изменил немного финальное название файла шаблона

01.09.2011 22:37
Аватар пользователя SerVal
SerVal написал:

Привет. Обращаюсь с огромной просьбой. Есть необходимость для одной страницы сайта (бильярд) подкорректировать оформление. Ссылка на страницу после модуля pathauto выглядит как page/bilyard.html Создание файла page-bilyard.tpl.php картины не меняет, вопрос - что где прописать, чтобы заработало? Нужно что-то прописать в template.php? Спасибо заранее !

25.03.2012 14:12
Аватар пользователя Сергей
Сергей написал:

Добрый день, не могу ни как разобраться. существыет путь
аренда/квартиры/название материала1. (ноде/55)
и
сдать/квартиру/ названия материала2 (ноде/86)
вот не могу разобраться как сделать что бы при аренде и при снятии можно было по разному оформить(материалов много, и под каждый писать новый фаил не вариант)
Проще говоря page-arenda-kvartira.tpl.php (работает прекрасно, но как сделать что бы задать дизайн для страниц со статьей т.к. в этом примере дизайн задается для каталога статей) 6-ая версия

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

Разделить по типам материала, как в статье и написано. В чем сложности возникли?

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

Все сделал как у Вас написано. Для начала скопировал содержание node-product-left-right.tpl.php (файл ранее используемого шаблона для всех товаров), в новый файл page-node-type-camin.tpl.php (созданный по вашему примеру, для материалов типа camin). В результате после обновления страница данного типа, появляется пустая страница.

10.09.2012 14:32
Аватар пользователя Максим
Максим написал:

У меня заработало с таким кодом(Drupal 7).

function mytheme_preprocess_page(&$variables) {
if (isset($variables['node'])) {
$variables['theme_hook_suggestions'][] = 'page__node__'. $variables['node']->type;
}
}

21.06.2013 15:38
Аватар пользователя creatorbat
creatorbat написал:

А у меня уже на первом этапе - Implementation of template_preprocess_page ничё не получается (
Кричит что не может переопределить ничего. А ещё куда-то лезть боюсь, ибо нуб... А так хотелось включить Full Width для статей, убрать лишние блоки и колонки... Огорчён сильно. Даже руки опустились..

19.09.2013 01:57
Аватар пользователя Мария
Мария написал:

т.е. если я не внесла в функцию ИМЯТЕМЫ_preprocess_page необходимые изменения, шаблон вида page--video.tpl.php (video - это мой тип материала) не будет работать?
Сейчас у меня работают такие шаблоны:
page--front.tpl.php
node--video.tpl.php
А файл template.tpl.php моей темы вообще пустой.

Заранее спасибо за ответ!

05.11.2013 22:26
Аватар пользователя Сергей
Сергей написал:

И охота вам с этим друпалом возиться, ппц

26.11.2013 07:10
Аватар пользователя mailfox
mailfox написал:

а с чем предлагаешь возиться?

26.11.2013 08:13
Аватар пользователя Сергей
Сергей написал:

ZF

26.11.2013 13:22
Аватар пользователя vlad36mir
vlad36mir написал:

Столкнутся с проблемой после добавления вышеуказанного кода перестают работать шаблоны вида page-node-10.tpl.php
решил проблему добавлением кода
$variables['template_files'][] = 'page-node-' . $variables['node']->nid;

12.02.2014 16:06
Аватар пользователя Вадим
Вадим написал:

Здравствуйте!

Излазил все что можно... и парюсь уже оч. много времени...
Скажите по какой причине могут не работать стандартные решения для изменения шаблона на страницах, т.е. те решения для которых не требуются написание кода в ТЕМПЛЕЙТЕ (т.е. то что прописано в самом первом абзаце вашей статьи)

26.02.2014 05:16
Аватар пользователя Дмитрий
Дмитрий написал:

Спасибо!
Самый полезный блог по Drupal! В момент очередного "мертвого затыка" иду сюда и нахожу решение.

21.02.2015 03:23
Аватар пользователя Sergejkot
Sergejkot написал:

Спасибо! Очень сильно помогли!

08.04.2015 14:23

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