Вывод списка заголовков материалов, сгруппированный по типам нод

Понадобилось вывести заголовки всех имеющихся на сайте публикаций. Но не просто списком, а группами по типам нод, с сортировкой по дате создания. Так как нод на вывод ожидалось немалое количество, обязательно должна была присутствовать постраничная «листалка» с настраиваемым лимитом вывода.

С помощью модуля Views подобные задачи решаются «на раз». Но это для лодырей. Нам же легкие пути не интересны. Пишем сниппет.

«Набросал» два варианта кода, выводящего нужные нам данные в нужном виде.

В первом случае информация выводиться в «табличном» виде, используя функцию theme_table() Друпала. Во втором варианте была задействована функция theme_item_list(), и данные отображаются «списками».

Вариант раз (табличный)

<?php

  $limit = 20;
  $sql = "SELECT n.nid, n.created, n.title, n.type
  FROM {node} n
  WHERE n.status = 1
  ORDER BY n.created DESC"
;
  $result = pager_query(db_rewrite_sql($sql), $limit);
  $types = node_get_types('names');
  while ($node = db_fetch_object($result))
  {
  $output[$types[$node->type]][] = array(array('data' => l($node->title,"node/$node->nid")));
  }
  foreach ($output as $types[$node->type] => $table) {
  print theme('table', array('data' => $types[$node->type]), $table);
  }
  print theme('pager', NULL, $limit);
 
?>

Вариант два (списком)

<?php

  $limit = 20;
  $sql = "SELECT n.nid, n.created, n.title, n.type
  FROM {node} n
  WHERE n.status = 1
  ORDER BY n.created DESC"
;    
  $result = pager_query(db_rewrite_sql($sql), $limit);
  $types = node_get_types('names');
  while ($node = db_fetch_object($result))
  {
  $output[$types[$node->type]][] = array('data' => l($node->title,"node/$node->nid"));
  }
  foreach ($output as $types[$node->type]=> $item) {
  $output = $types[$node->type];
  $output .= theme('item_list',$item);
  print $output;
  }
  print theme('pager', NULL, $limit);
 
?>

Результатом работы сниппета будет вывод данных следующего вида:

Тип ноды 1

  • Нода один
  • Нода два
  • Нода три
  • ...

Тип ноды 2

  • Нода один
  • Нода два
  • Нода три
  • ...

Тип ноды 3

  • Нода один
  • Нода два
  • Нода три
  • ...

...

тут кнопки «листалки»(пэйджера)

Dalay

Комментарии

Спасибо ,,,,,,,

Спасибо! А как изменить код чтобы выводилось, допустим, по 2 последних ноды из каждого типа?

Первое, что пришло в голову - добавить вложенный «фильтрующий» цикл for в уже имеющийся foreach. Выглядеть это будет так:

  $limit = 20;
  $node_limit_by_type = 2; /* Вводим для удобства новую переменную, где значением будет желаемый лимит на количество нод для каждого типа. */
 
  $sql = "SELECT n.nid, n.created, n.title, n.type
  FROM {node} n
  WHERE n.status = 1
  ORDER BY n.created DESC"
;    
  $result = pager_query(db_rewrite_sql($sql), $limit);
  while ($node = db_fetch_object($result))
  {
  $types = node_get_types('names');
  $output[$types[$node->type]][] = array('data' => l($node->title,"node/$node->nid"));
  }
  foreach ($output as $types[$node->type]=> $item) {
  $output = $types[$node->type];
    for($i = 0; $i < $node_limit_by_type; $i++){ /* Фильтруем количество нод, используя значение переменной $node_limit_by_type */
    $output .= theme('item_list',$item[$i]);
    }
  print $output;
  }
  print theme('pager', NULL, $limit);

Немного не в тему ,но как вывести последние комментарии в блок?
Я делал такой сниппет:

$max = 10; // количество комментариев
$query = 'SELECT nid,cid,subject FROM {comments} ORDER BY  timestamp DESC  LIMIT $max';
$result = db_query($query);
$items = array ();
while ($comment = db_fetch_object($result)) {
    $items[] = l($comment->subject, "node/$comment->nid", NULL, NULL, "comment-$comment->cid");
}
if (count($items)) {
        return theme_item_list($items);
}

Но выдает ошибку:

user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '$max' at line 1 query: SELECT nid,cid,subject FROM comments ORDER BY timestamp DESC LIMIT $max in Z:\home\cocktail\www\includes\common.inc(1696) : eval()'d code on line 4.

Чем не нравится ему переменная $max?

Тем, что заключенная в одинарные кавычки, она переменной не считается. И вместо цифрового значения запрос получает строку с именем переменной.

спасибо за ответ - кавычки поменял -Fatal error: Unsupported operand types in Z:\home\example.ru\www\includes\common.inc on line 1593

С функцией l() разберитесь.

разобрался-получилось :

$max = 10; // количество комментариев
$query = "SELECT nid,cid,subject FROM {comments} ORDER BY timestamp DESC LIMIT $max";
$result = db_query($query);
$items = array ();
while ($comment = db_fetch_object($result)) {
$items[] = l($comment->subject, "node/$comment->nid");
}
if (count($items)) {
return theme_item_list($items);
}

Выводятся заголовки комментариев ,а как к ним добавить их дату?

О составлении правильных запросов:

http://api.drupal.ru/api/function/db_query
http://api.drupal.ru/api/function/db_query_range

Примеры вывода комментариев:

http://api.drupal.ru/api/function/comment_get_recent
http://api.drupal.ru/api/function/theme_comment_block

по примеру api.drupal.ru/api/function/theme_comment_block

сделал сниппет :

$max = 10; // количество комментариев
$query = "SELECT nid,cid,subject FROM {comments} ORDER BY  timestamp DESC  LIMIT $max";
$result = db_query($query);
$items = array ();
while ($comment = db_fetch_object($result)) {
    $items[] = l($comment->subject, 'node/'. $comment->nid, array('fragment' => 'comment-'. $comment->cid)) .'<br />'. t('@time ago', array('@time' => format_interval(time() - $comment->timestamp)));
}
if (count($items) ){
        return theme('item_list', $items);
}

Выводит следующее:

ком привет
41 год 9 недель назад
Помогите пожалуйста решить
41 год 9 недель назад
привет
41 год 9 недель назад
здарова
41 год 9 недель назад
привет
41 год 9 недель назад
<)
41 год 9 недель назад

Откуда он берет эти 41 год 9 недель?

Чего тут решать, название функции format_interval() ни о чем разве не говорит? Есть у вас дата в юникс-формате ($comment->timestamp). Обработать ее можно «напрямую» через пэхапэшную date(), или через друпальскую format_date().

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

через date() :
вывожу в виде
date("l dS of F Y h:i:s A",$comment->timestamp)
выдает - Thursday 01st 1970f January 1970 02:00:00 AM причем у всех комментариев

через format_date() -

format_date($comment->timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL)

выдает чт, 01/01/1970 - 02:00 тоже у всех комментариев

юникс-формат времени переводится в обычный формат ,но почему время берется не комментария ,а системное?

Когда я писал ,что у меня выводится во всех случаях 41 год 9 недель назад - это то же явно не юникс время.
1294306665 -вот это пример юникс времени

Сриппет переписал таким образом :

$max = 10; // количество комментариев
$query = "SELECT nid,cid,subject FROM {comments} ORDER BY  timestamp DESC  LIMIT $max";
$result = db_query($query);
$items = array ();
while ($comment = db_fetch_object($result)) {
    $items[] = l($comment->subject, 'node/'. $comment->nid, array('fragment' => 'comment-'. $comment->cid)) .'<br />'. t('@time', array('@time' => format_date( $comment->timestamp)));
}
if (count($items) ){
        return theme('item_list', $items);
}

Под заголовком каждого коммента выводится : чт, 01/01/1970 - 02:00
Почему он не выводит дату комментария?

date()

//день-месяц-год час:минута
date("d-m-Y G:i", $comment->timestamp);

format_date()

Цитата с http://api.drupal.ru/api/function/format_date
$type Формат даты. Может быть 'small', 'medium' или 'large' для предустановленных форматов. Если сюда передать "custom", то можно указать свой формат в параметре $format

format_date($comment->timestamp, 'medium');

так я собственно и ввожу :

format_date($comment->timestamp, 'medium');

Вопрос в том ,почему под каждым комментарием в данном случае выводится : чт, 01/01/1970 - 02:00,
а не дата комментария?

дело было не в функциях форматирования времени-
дело было в неправильной выборке из бд (столбец timestamp отсутствовал ),
поэтому и выдавало все время 1970 год

Таким образом сниппет ,выводящий 10 последних комментариев (заголовок каждого комментария и время назад которое он был написан):

$max = 10; // количество комментариев
$query = "SELECT nid,cid,subject,timestamp FROM {comments} ORDER BY timestamp DESC LIMIT $max";
$result = db_query($query);
$items = array ();
while ($comment = db_fetch_object($result)) {
$items[] = l($comment->subject, 'node/'. $comment->nid, array('fragment' => 'comment-'. $comment->cid)) .'
'. t('@time ago', array('@time' => format_interval(time() - $comment->timestamp)));
}
if (count($items) ){
return theme('item_list', $items);
}

Ту же информацию выводит в блок сам модуль комментариев. Уже «готовой» функцией comment_get_recent(), на которую мну давал вам ссылку выше.

А как вручную через php сниппет вывести эту функцию в блок ?
Я пробывал ее вызывать - выдает "Array" и все.
Мне нужен именно вывод вручную через вставку php кода.

Есть список из титлов нод в виде списка линков на ноды. Можно ли сделать вьюшку для вывода каждой полной ноды по клику на линк заголовка?

Можно, делайте.