Долгое время не пользовался views, опасаясь его размера. Три дня назад пришлось его поставить для решения определённой задачи, плотно посидел над документацией и примерами - и был впечатлён его гибкостью и мощью. Но осталось несколько вопросов, ответы на которые я пока не нашёл. Надеюсь, гуру views помогут мне советом или готовым рецептом.
1. Есть вьюшка с exposed filter по таксономии, словарь которой имеет два уровня вложенности. Как сделать так, чтобы при выборе термина верхнего уровня страницы с подтерминами тоже попадали в выборку? Например, чтобы при выборе термина "Туполев" показывались также страницы с терминами "Ту-144" и "Ту-95".
2. Есть вьюшка, которая выводит все материалы определённого типа. Как задать exposed filter, чтобы эти материалы можно было отсортировать по алфавиту/времени/рейтингу? По отдельности эти сортировки сделать не проблема, но не могу придумать, как их объеденить для выбора пользователем в виде одного выпадающего списка. Или надо делать несколько вьюшек и переключать их в зависимости от текущего значения в поле?
3. Есть вьюшка, которая выводит список заголовков материалов в три колонки в виде grid. Хочется, чтобы заголовкам, начинающимся на одну букву, предшествовал header с этой самой буквой (примерно как в предметном указателе в конце книжек). Есть ли возможность в views группировать выводимые строки по первой букве, чтобы потом этот вывод можно было темизировать? Может, для этого существуют какие-то готовые рецепты?
Заранее спасибо за помощь!
Комментарии
Есть фильтр с возможностью включить подтермины.
Вот насчет Grid не скажу точно, но обычный список я темизировал легко, подобный функционал решается достаточно просто. Как выяснилось, Views темизируются влегкую
Блин, точно! Вот я слепой... Спасибо, этот вопрос решён!
Не будет ли наглостью с моей стороны попросить вас чуть подробнее рассказать о вашем методе?
Надеюсь, к гриду он тоже окажется применим, так как простой линейный список не очень подходит под мою задачу.
Расскажу, не жалко. Предупреждаю заранее, нужно знание PHP.
Итак, предположим у нас есть View, мы его отсортировали по одному из полей и хотим добавить буквы алфавита перед каждой из них.
Как бы я это делал для простого списка:
1. Смотрим Basic settings -> Theme -> Information
Здесь показано, какие для чего используются шаблоны, для View, каждого поля в отдельности и, то, что мы будем использовать:
Style output: views-view-grid.tpl.php
2. Вот код файла, который по умолчанию показывает список записей:
<?php
// $Id: views-view-grid.tpl.php,v 1.3.4.1 2010/03/12 01:05:46 merlinofchaos Exp $
/**
* file views-view-grid.tpl.php
* Default simple view template to display a rows in a grid.
*
* - $rows contains a nested array of rows. Each row contains an array of
* columns.
*
* ingroup views_templates
*/
?>
<?php if (!empty($title)) : ?>
<h3><?php print $title; ?></h3>
<?php endif; ?>
<table class="views-view-grid">
<tbody>
<?php foreach ($rows as $row_number => $columns): ?>
<?php
$row_class = 'row-' . ($row_number + 1);
if ($row_number == 0) {
$row_class .= ' row-first';
}
if (count($rows) == ($row_number + 1)) {
$row_class .= ' row-last';
}
?>
<tr class="<?php print $row_class; ?>">
<?php foreach ($columns as $column_number => $item): ?>
<td class="<?php print 'col-'. ($column_number + 1); ?>">
<?php print $item; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
?>
3. Копируете этот файл к себе в папку темы, называете его соответственно и видоизменяете.
Э-э-э... Похоже, я не совсем точно сформулировал свой вопрос. В каких темплейтах производится темизация полей - это я сразу нашёл. Мне пока непонятно, как получить доступ к самому массиву значений, чтобы добавить в него элементы "буква-заголовок" (так как определение числа ячеек в гриде зависит от общего числа элементов, то в темплейте их поменять уже не получится).
Думаю, придётся с Views API немного поковырятся, наверняка в нём есть хук, через который можно получить доступ к возвращаемым вьюшкой значениям - и слегка их дополнить.
Тем, кто будет просматривать этот пост: второй вопрос я тоже решил (правда, не совсем так, как изначально задумывал).
Создал дефолтную вьюшку с нужными параметрами, к ней - три отображения-страницы с нужными сортировками и путями, а потом в заголовок дефолтной вьюшки вставил ссылки в виде "Сортировать по дате/алфавиту/рейтингу".
Третий вопрос я все-таки решил, вот тот код, который у меня заработал, публикуется под GPL лицензией.
<?php
/**
* file views-view-grid.tpl.php
* Defines custom view template to display a rows in a grid with first-letters in their own rows.
*
* Based on Views module views-view-grid.tpl.php
* Published under GPL License
*
* G.A.Vinogradov, 2010 <g.a.vinogradov@gmail.com>
*
* - $rows contains a nested array of rows. Each row contains an array of
* columns.
*
* ingroup views_templates
*/
?>
<?php if (!empty($title)) : ?>
<h3><?php print $title; ?></h3>
<?php endif; ?>
<?php // Собираем из отсортированных по колонкам и строкам отрендеренных результатов линейный массив:
$items_display = array();
foreach ($rows as $columns){
foreach ($columns as $column){
$items_display []= $column;
}
} $drawn_letters = array(); $grid = array();
$row_id = 0;
$column_id = 0; // Берем настройки количества столбцов
$columns = $view->display_handler->options['style_options']['columns']; // Основной цикл - будем собирать таблицу заново, поэлементно
foreach ($view->result as $key => $item){
$node_title = $item->node_title;
$first_letter = mb_substr($node_title, 0, 1);
if (!isset($drawn_letters[$first_letter])){
// Строка с первой буквой еще не выводилась, добавим ее
if ($column_id){
$row_id++;
}
$grid[$row_id][0] = $first_letter; // Вот это место можно разбавить темизацией, например "<h2>$first_letter</h2>"
$row_id++;
$column_id = 0;
$drawn_letters[$first_letter] = true;
}
$grid[$row_id][$column_id] = $items_display[$key];
$column_id++;
if ($column_id == $columns){
$row_id++;
$column_id = 0;
}
}
?>
<?php // Теперь выведем новую таблицу?>
<table class="views-view-grid">
<tbody>
<?php foreach ($grid as $row_number => $columns): ?>
<?php
$row_class = 'row-' . ($row_number + 1);
if ($row_number == 0) {
$row_class .= ' row-first';
}
if (count($rows) == ($row_number + 1)) {
$row_class .= ' row-last';
}
?>
<tr class="<?php print $row_class; ?>">
<?php foreach ($columns as $column_number => $item): ?>
<td class="<?php print 'col-'. ($column_number + 1); ?>">
<?php print $item; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
?>
Есть две небольшие проблемки: лишний "?>" в конце файла и неправильная работа в случае, если заголовки выводятся не по горизонтали, а по вертикали (как у меня, например).
Последнее, я думаю, можно решить, предварительно отсортировав массив всех значений. Осталось только придумать, как их потом вывести по вертикали, да так, чтобы "висящих" заглавных букв в конце колонки не оставалось. Со вчерашнего вечера сижу, алгоритм придумываю...
А за файлик - большое спасибо!
Допиливайте, там несложно будет.
Нашёл ещё один элегантный способ, совсем не требующий написания PHP-кода:
http://drupal.org/node/641342#comment-3360558