Создание шаблона для вывода нужных полей статей (нод/node)

Главные вкладки

Аватар пользователя mrhuge mrhuge 21 октября 2011 в 1:48

Привет всем.

Имеются: статьи с картинками,
Цель: настроить вывод этих статей, отобранных по терминам таксономии (категориям), через свой шаблон. Например, сделать шаблон вывода только картинок статей в любом нужном месте сайта. Например, как маленький модуль "последние работы портфолио" в левой колонке сайта или как большой модуль в центральной колонке "все работы портфолио".

Перелопатил кучу материала по указанной теме на этом форуме, а также на drupal.org. Большинство предлагаемых решений устарело - они для drupal 6. А также многие решения излишне сложны - создается куча функций с кучей переменных, вплоть до правки самих модулей Друпала. Также одно из решений - просто использовать модуль Views, настроить через него вывод нужных полей нужным способом. Но реально есть ли смысл ставить Views? Он будет жрать ресурсы сервера.

У Drupal 7 достаточно мощный API. Думаю можно просто с его использованием отобрать нужные статьи по термину таксономии. Так вот, предлагаю следующее решение:

Создаем page--node--1.tpl.php в текущей теме Друпала. Это для того чтобы вызвать по адресу http://сайт/node/1 свой шаблон страницы. И в коде этого файла прописываем:

<?php $tax = '6'; // здесь мы присваиваем переменной значение нужного термина таксономии

$nids = taxonomy_select_nodes($tax); //с помощью этой функции отбираем ноды по термину таксономии
$nodes = node_load_multiple($nids); // с помощью этой функции загружаем все нужные ноды

foreach ($nodes as $key) { //перебираем все полученные ноды
$variables = get_object_vars($key); // с помощью этой функции получаем обычный массив значений статей, а не stdClass Object-ы, которые нельзя отобразить
echo '<div style="width:100px; border: 1px solid black;">'.$variables['body']['ru'][0]['summary'].'</div>';  //здесь выводим из массива краткое описание каждой ноды
echo '<div style="width:100px; border: 1px solid black;"><img src="/sites/default/files/styles/thumbnail/public/field/image/'.$variables['field_image']['ru'][0]['filename'].'"></div>'; //здесь выводим уменьшенное изображение из ноды
}
?>

Сбрасываем кеш, чтобы новый шаблон ноды заработал, и получается всё. С помощью такого просто кода мы отобрали нужные статьи нужной категории, а также отобразили поля этих статей нужным нам образом. И не понадобился никакой Views или кастомизация модулей Друпала. Этот код можно вставлять в любое место шаблона и вызывать отображение материалов там где нам нужно.

Как считаете, это оптимальный способ создания своего шаблона для вывода полей статей/нод? Или есть более правильный вариант?

Комментарии

Аватар пользователя kalabro kalabro 21 октября 2011 в 13:41

я считаю, неоптимальный. неоптимальный для друпала. вы просто всё слили в один файл и вшили id'шки и пути.
для следующего за вами разработчика будет неожиданностью, что на странице ноды с id=1 выводится список материалов по термину c id=6. а если окажется, что к этому термину привязана 1000 нод, то страница вообще может не открыться Lol
вообще создание страницы в друпале стандартное для любых модулей (если вы хотите его прогать сами, взгляните, как делает Node или тот же Views).
создается страница с помощью hook_menu() c вашим page callback. если нужен особый шаблон, он тоже создается и регистрируется в hook_theme() и задается в page callback с ключом #theme. для того чтобы получить render array для полей, есть функции field_get_items() и field_view_value() или field_view_field(). поля в шаблоне выводятся с помощью render(). кажется, что сложновато, но зато более гибко, и при переносе проблем не будет.

"mrhuge" wrote:
Он будет жрать ресурсы сервера.

там есть кеш и шикарный SQL UI!

Аватар пользователя mrhuge mrhuge 21 октября 2011 в 16:52

"kalabro" wrote:
на странице ноды с id=1 выводится список материалов по термину c id=6. а если окажется, что к этому термину привязана 1000 нод, то страница вообще может не открыться :))

Цель именно создать код, который можно использовать где угодно. Если создавать отдельную страницу, это опять же ограничивает. Нужно, чтобы можно было вывести что угодно в любом участке любой даже уже существующей страницы.

А можешь привести примеры готового кода использования описанного тобой функционала:

"kalabro" wrote:
создается страница с помощью hook_menu() c вашим page callback. если нужен особый шаблон, он тоже создается и регистрируется в hook_theme() и задается в page callback с ключом #theme

и

"kalabro" wrote:
чтобы получить render array для полей, есть функции field_get_items() и field_view_value() или field_view_field(). поля в шаблоне выводятся с помощью render()

Аватар пользователя mrhuge mrhuge 23 октября 2011 в 19:43

"kalabro" wrote:
я использую Views, а прогаю ченить поинтересней :)

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

"kalabro" wrote:
field_get_items() и field_view_value() или field_view_field(). поля в шаблоне выводятся с помощью render()

Кстати спасибо за эти хорошие функции. Тут даже есть пример использования http://api.drupal.org/api/drupal/modules--field--field.module/function/f...
а именно:

<?php
$node = node_load($nid);
$image = field_get_items('node', $node, 'field_NAME');
foreach ($image as $key=>$value) {
$output = field_view_value('node', $node, 'field_NAME', $image[$key], array(
  'type' => 'image',
  'settings' => array(
    'image_style' => 'thumbnail', //place your image style here
    'image_link' => 'content',
  ),
));
print render($output);
}
?>

Надо будет попробовать. Вопрос только какой способ будет экономичнее в плане запросов к базе.

"RxB" wrote:
В мемориз с пометкой "Как не надо делать"

Для конкретного случая именно так и надо будет делать.

Аватар пользователя kalabro kalabro 23 октября 2011 в 20:13

"mrhuge" wrote:
Просто стало интересно

читайте исходные коды
"mrhuge" wrote:
Вопрос только какой способ будет экономичнее в плане запросов к базе.

экономичнее в плане запросов к базе будет свертстать html-ку и отдать её nginx'ом Wink

Аватар пользователя mrhuge mrhuge 23 октября 2011 в 20:22

"kalabro" wrote:
экономичнее в плане запросов к базе будет свертстать html-ку и отдать её nginx'ом ;)

Не поспоришь Smile

В общем, вопрос топика еще нуждается в исследовании.

Аватар пользователя mak-vardugin mak-vardugin 23 октября 2011 в 20:43

Комрад, вьюс, вьюс и еще раз вьюс, его и закешировать можно и цсс подключить вижу есть огромная тяга к интиму по-этому ваш путь правильный и единственно верный!

Аватар пользователя mrhuge mrhuge 24 октября 2011 в 4:01

Так, хорошо, давайте закончим спам (как бы хороша ни была женщина в красном, ну никак ее ни на свидание, ни в койку не пригласишь) и продолжим целевое обсуждение.

Расширенная задача: необходимо, чтобы на главной странице выводился список работ портфолио в виде картинок-ссылок и форма связи, созданная с помощью drupal forms api.

Как верно заметила Катя-kalabro, страницу можно создать с помощью hook_menu. Вот прекрасная простая статья в деталях о том, как создать страницу в drupal: http://iflight.su/blog/programmnoe-sozdanie-stranicy-v-drupal-7

Так вот, будет ли следующий способ оптимальным для решения задачи?

1) создаем и включаем модуль, который генерирует страницу по любому адресу, как описано по ссылке выше,
2) в настройках Друпала выставляем эту страницу, как главную,
3) в результате содержимое главной страницы возвращает функция из созданного модуля,
4) в новосозданной функции прописываем возврат формы, созданной в этом же модуле: return drupal_get_form('my_form');
5) теперь надо прописать еще и возврат либо вывода картинок портфолио через Views, либо вывода их через field_view_value (как предложила Катя) либо через перебор массива таксономии (как предложил я).

Так вот как лучше впихнуть в созданный модуль реализацию пункта 5?

Замысел этого всего: сделать крутую главную страницу сайта на которой будет и вывод статей и вывод формы и вообще вывод всего чего хочется.

Аватар пользователя kalabro kalabro 24 октября 2011 в 10:04

если вам нужно и форму и список нод в одной области, то как-то так:


<?php
/* Пример откуда-то из моих запасов */
function MYMODULE_keys_page($node) {
  
$name 'my_view_name';
  
$build = array();
  
  
// Форма
  
$build['content'][] = drupal_get_form('my_form_id'$node->nid);
  
  if (
module_exists('views')) {
    
// Load the view and render it.
    // Ну или views_embed_view()
    
if ($view views_get_view($name)) {
      
$view->args[0] = $node->nid;
      
$build['content'][] = array('#markup' => $view->execute_display() . '<br />');
    }
  }
  
  return 
$build;

}

?>

Опять же, я бы вряд ли стала так делать главную Smile

Аватар пользователя mrhuge mrhuge 26 октября 2011 в 3:18

"kalabro" wrote:
если вам нужно и форму и список нод в одной области, то как-то так:

Катя, спс за решение. Скоро попробую. В принципе еще можно попробовать создать доп. регион. В этот регион вывести блок Views только на главной либо сделать отображение региона с Views по условию.

"mak-vardugin" wrote:
как вы сие кэшировать будите? Для главной точно вьюс, вьюс и еще раз вьюс.

Как я понял, в том что написала Катя и производится вывод Views через views_get_view($name). В чем будут проблемы с кешированием в этом случае?

Аватар пользователя mak-vardugin mak-vardugin 26 октября 2011 в 13:15

как я понял вы её склоняли к эротике PHP запросу, а не вьюхе как она вам первая и предалагала

"kalabro" wrote:
я использую Views, а прогаю ченить поинтересней :)