Итак задача:
Есть база данных фильмов.
Нужно иметь возможность располагать эти фильмы по разным страницам группируя по начальной букве названия.
Во views существует возможность выбора в качестве аргумента - заголовка с фильтрацией по одной букве, но...
Работает все это только с англицкими названиями.
Решил я эту проблему транслитерацией заголовка и помещением его в специальное спрятанное поле (Computed Field).
Решение получилось немного мудреным. Если кто может предложить оптимизацию - Welcome !
Требуемые модули:
- CCK
- Computed Field
- Views
- Pathauto (для транслитерации)
Решение:
Тип материала "фильм"
Для своего типа материала "фильм" создал новое поле.
Имя : title_en
Field type: Computed
Обязательно
Computed Code
<?php
$title_ru = trim(&$node->title); // на всякий случай обрезаем пробелы
$letter_ru = substr ($title_ru, 0, 2); // вырезаем первую русскую букву
$translations = array();
$path = drupal_get_path('module', 'pathauto'); // транслитерация
if (is_file($path. '/i18n-ascii.txt')) {
$translations = parse_ini_file($path. '/i18n-ascii.txt');
}
$output = strtr($letter_ru, $translations);
$node_field[0]['value'] = $output;
?>
обратите внимание, что в поле Computed Code вводится php код без <?php ?>
Display this field - снимаем галочку.
Store using the database settings below - ставим галочку.
Data Type - text
Data Length - 4
Sortable - ставим галочку.
Сохраняем поле.
Теперь нужно либо пересохранить существующие фильмы, либо создавать новые.
Все они пойдут с этим новым полем. В старых материалах нового поля нет.
Создание "вида" (views)
Создаем вид со следующими параметрами:
Имя: film_pager
Описание: Фильмы по алфавиту
Страница
Provide Page View - ставим галочку
адрес: films
View Type: - Teaser List
Заголовок: Все фильмы по алфавиту (заголовок страницы)
Nodes per Page: 20
Заголовок: (это то, что будет над результатом, сюда рисуем саму линейку)
.film_alf_pager { margin: 0.5em; }
</style>
<div style="line-height:150%; text-align: center;"><p>
<?php
print l ("А", "films/a", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Б", "films/b", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("В", "films/v", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Г", "films/g", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Д", "films/d", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Е", "films/e", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ж", "films/zh", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("З", "films/z", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("И", "films/i", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("К", "films/k", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Л", "films/l", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("М", "films/m", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Н", "films/n", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("О", "films/o", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("П", "films/p", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Р", "films/r", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("С", "films/s", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Т", "films/t", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("У", "films/u", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ф", "films/f", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Х", "films/kh", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ц", "films/ts", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ч", "films/ch", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ш", "films/sh", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Щ", "films/shch", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ы", "films/y", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Э", "films/e", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ю", "films/yu", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Я", "films/ya", $attributes = array('class'=>'film_alf_pager')).' ';
?>
</p></div>
Формат ввода: PHP
Empty Text: (это то, что выводится если нет результата, сюда опять же линейку и какой нибудь текст)
.film_alf_pager { margin: 0.5em; }
</style>
<div style="line-height:150%; text-align: center;"><p>
<?php
print l ("А", "films/a", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Б", "films/b", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("В", "films/v", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Г", "films/g", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Д", "films/d", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Е", "films/e", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ж", "films/zh", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("З", "films/z", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("И", "films/i", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("К", "films/k", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Л", "films/l", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("М", "films/m", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Н", "films/n", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("О", "films/o", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("П", "films/p", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Р", "films/r", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("С", "films/s", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Т", "films/t", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("У", "films/u", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ф", "films/f", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Х", "films/kh", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ц", "films/ts", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ч", "films/ch", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ш", "films/sh", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Щ", "films/shch", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ы", "films/y", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Э", "films/e", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Ю", "films/yu", $attributes = array('class'=>'film_alf_pager')).' ';
print l ("Я", "films/ya", $attributes = array('class'=>'film_alf_pager')).' ';
?>
</p></div>
<?php if ($_GET[q]!="films") : // если есть буква но нет фильмов
?>
<p><big><b>На эту букву нет фильмов.</b></big></p>
<?php else : // если нет буквы встраиваю другой "вид" с последними фильмами
?>
<h3>Последние поступления:</h3>
<?php
print theme_view ('last_films', $limit=4, $use_pager=FALSE, $type= 'embed', $view_args=array());
?>
<?php endif; ?>
Формат опять же PHP
Аргументы:
Computed: title_en (field_title_en); по умолчанию - Use Empty Text
Фильтры:
Node: Published - да; Node: Type - фильм
Sort Criteria:
Node: Title - по возрастанию (Ascending)
Все, сохраняем вид. Переходим на страницу films и наслаждаемся.
Пример работы этой схемы здесь:
http://rodinakino.ru/films
Комментарии
спасибо !
Хм. Может я немного не так понял, но у меня подобная задача решается без дополнительного кода. Пример: http://bestofbeauty.ru/base. Ссылки русского алфавита формируются вот так:
<a href="/base/%D0%91">Б</a>
Views нормально принимает такой аргумент.
непонятно откуда А - %D0%90
ведь А это %C0
???
%C0 - это "А" в CP1251;
%D0%90 - это "А" в UTF-8.
Получил я это примерно так:
<?php
header("Content-type: text/plain");
for($i=192;$i<192+32;$i++){ // 192 - код буквы 'А' в CP1251 (вендовая кодировка)
$c = chr($i);
$c = iconv("CP1251","UTF-8",$c);
print urlencode($c)."\n";
}
?>
Спасибо, интересно!
Кстати, некоторые фильмы начитаются не с буквы, а с цифры, например "300 спартанцев". Так неплохо было бы добавить дополнительную категорию для подобных названий.
Может кто знает решение такой задачки:
Если фильмы нужно выводить не отдельно по буквам, а в общей ленте, НО чтобы вьюс давал не просто упорядоченный по алфавиту список фильмов. Нужен также и вывод заглавных букв.
А
Американский пирог. Комедия
Американский пирог-2. Комедия
Б
Батальоны просят огня. Боевик
...
В
...
Я
???
Тут видимо нужно создать страницу и в ней вызывать вид 33 раза (для каждой буквы).
Я так понял, что список должен быть на одной странице?
Как то не очень кузяво...
А есть красивые решения?
Поиски под друпал.орг и танцы с бубном над видами пока ничего не дали.
А я когда-то для этих нужд модуль написал. Мож кому интересно будет. Пример работы тут
А как работает модуль? расскажите пожайлуста.
В общем, у меня не получается разобраться в работе модуля (что в принципе не удивительно пхп незнаю)
Я хочу сделать кнопку 0-9 и выводить все фильмы названия которых начинаются с чисел.
Пробывал, по разному но не выходит.
Вообще не могу понять как это работает =/ Где указывается какие именно Computed Field выводить?
Тоесть, ссылка типа вид\символ , работает только с символами а-я =/
Не работают: "мой_сайт.ру/вид/3" (числа) - и "мой_сайт.ру/вид/w" (английские названия)
"мой_сайт.ру/вид/Я+Щ" как складывать? )
Кто может помочь?
Проблема в том что мне надо научится выводить ещё английскую линейку =/
Пробывал примерно так:
Добавлял второе computed поле engl
<?php
$title_eng = trim(&$node->title);
$letter_eng = substr ($title_eng, 0, 2);
$output = strtr($letter_eng, $letter_eng);
$node_field[0]['value'] = $output;
?>
В общем, функций я незнаю, сделал логически
заменяю чтото видимо два раза одно и тоже из $letter_eng в $letter_eng , но должно работать ведь?
В моем решении с компьютед филдом и русские и английские названия складываются вместе в соответствии с транслитерацией.
Отделить английскую линейку не получится.
Лучше делайте как писал magway
Создаете вид.
Как аргумент делаете Node:Title
В опшинсах выставляете 1 (значит один символ)
Ссылки делаете так:
<a href="/base/%D0%91">Б</a>
получить их можно так:
<?php
header("Content-type: text/plain");
for($i=192;$i<192+32;$i++){ // 192 - код буквы 'А' в CP1251 (вендовая кодировка)
$c = chr($i);
$c = iconv("CP1251","UTF-8",$c);
print urlencode($c)."\n";
}
?>
Вот с цифрами не знаю.
Выводить каждую отдельной ссылкой - это можно, а вот объединить ...
Вопрос автору..
А можно ли заставить это работать без использования модуля Pathauto ? Что и где для этого нужно изменить? Функциональность того что здесь есть меня полностью устраивает... только вот заставить это работать никак не получается. У меня, например, не установлен Pathauto, а в статье ни слова нет про его настройки.. Модуль то я установил (для чего понадобилось поставить еще некий Token... ) В результате имею ошибки от Pathauto, кашу в голове, и не решенную задачу с алфавитом ))
Как решается задача у magway'a вобще не понял.. без какого дополнительного кода? и как собственно решается? )
Буду признателен за любую помощь )
P.S. Все заработало как разобрался с Pathauto. Спасибо автору! )
Чего ж непонятного? В view добавлется аргумент Node:Title, в Option ставится 1 (показывает количество букв в аргументе). В любое место страницы добавляется код со ссылками (я его расположил в Page header). Код примерно такой:
<a href="/base/%D0%90">А</a>
<a href="/base/%D0%91">Б</a>
<a href="/base/%D0%92">В</a>
<a href="/base/%D0%93">Г</a>
<a href="/base/%D0%94">Д</a>
<a href="/base/%D0%95">Е</a>
<a href="/base/%D0%96">Ж</a>
<a href="/base/%D0%97">З</a>
<a href="/base/%D0%98">И</a>
<a href="/base/%D0%99">Й</a>
<a href="/base/%D0%9A">К</a>
<a href="/base/%D0%9B">Л</a>
<a href="/base/%D0%9C">М</a>
<a href="/base/%D0%9D">Н</a>
<a href="/base/%D0%9E">О</a>
<a href="/base/%D0%9F">П</a>
<a href="/base/%D0%A0">Р</a>
<a href="/base/%D0%A1">С</a>
<a href="/base/%D0%A2">Т</a>
<a href="/base/%D0%A3">У</a>
<a href="/base/%D0%A4">Ф</a>
<a href="/base/%D0%A5">Х</a>
<a href="/base/%D0%A6">Ц</a>
<a href="/base/%D0%A7">Ч</a>
<a href="/base/%D0%A8">Ш</a>
<a href="/base/%D0%A9">Щ</a>
<a href="/base/%D0%AA">Ъ</a>
<a href="/base/%D0%AB">Ы</a>
<a href="/base/%D0%AC">Ь</a>
<a href="/base/%D0%AD">Э</a>
<a href="/base/%D0%AE">Ю</a>
<a href="/base/%D0%AF">Я</a>
</div>
,где /base - адрес страницы с view
Скоро мне это понадобится. Хотелось бы узнать. Нет ли чего нибудь новенького по этому вопросу? Может появилось новое решение?
См. на пост выше.
Вот с цифрами пока непонятки.
А что насчет модуля Node list. Чем он неподходит?
У меня немного другая ситуация, но похожа. Есть словарь "Авторы" с терминами (их фамилии), соответственно каждый написал несколько книг, но это нам не надо =). Нужен список авторов в алфавитном порядке (алфавитной линейке). Пишем bookl.module
=). Это под 6-ку.
<?php
// $Id$
function booklist_perm() {
return array('access booklist', 'create booklist', 'administer booklist');
} // function booklist_perm()
function booklist_print() {
$page_content = '
'.urldecode($_GET['letter']).'
';
$page_content .= '| ';
//db_query("DELETE FROM {cache};");//чистим кэш
//выводим алфавит.
for($i=192; $i<192+32; $i++){ // 192 - код буквы 'А' в CP1251 (вендовая кодировка)
$c = chr($i);
$c = iconv("CP1251","UTF-8",$c);
$page_content .= "".$c." | ";
}
$page_content .= "
";
//запрос из БД выбирающий только те имена которые начинаются с нужной буквы
$query = "SELECT tid, name FROM {term_data} WHERE vid = '%d' AND name LIKE ('%s')";
$queryResult = db_query($query, 1, urldecode($_GET['letter']).'%%');
while ($temp = db_fetch_object($queryResult)) {
$page_content .= l($temp->name,"taxonomy/term/".$temp->tid)."
";
}
return $page_content ;
}// function booklist_print()
function booklist_menu() {
$items = array();
// $items['адрес страницы']
$items['bookl'] = array(
'title' => t('Booklist'),
'page callback' => 'booklist_print',
'access arguments' => array('access booklist'),
'type' => MENU_CALLBACK
);
return $items;
} // function booklist_menu()
?>
Но!
Да и вообще повалидатьте код если не сложно.
Патч views_alpha_pager для русских букв
жесть, я и не знал, что так можно замучить модуль ))
Подскажите пожалуйста новичку, как таким образом, или похожим образом сделать линейку только на английские буквы?
спс
Не очень понятна Ваша задача.
Неужели Вам не подходит ни одно, приведенное выше, решение?
еще достаточно красивый вариант моего производства, а как я уже потом посмотрел таких солюшенов предостаточно, но конкретно такого полного не встречал иначе бы часов 5 точно съэкономил
1. создаем категорию "алфавит" с терминами (т.е. с буквами и цифрами) по которым собственно будем раскидывать ноды (фильмы).
2. создаем вид c именем alpha представляющий страницу и определяем выводимые видом поля нод (Fields)
3. определяем аргументы (Arguments): словарь (Taxonomy: Vocabulary ID) и термин (Taxonomy: Term ID) со значениями по умолчанию отображать все. (тормозил по страшному, но въехал не сразу, что аргументы это и есть забираемые видом из урла значения, т.е значения передаваемы в вид через урл в том порядке в каком мы их задали), т.е. урл у нас будет вида /?q=alpha/n/m где n - id словаря, m - id термина
4. в поле "Argument Handling Code" пришем следующее, обязательно без "<?php" and "?>"
if (!arg(2)) $args[2] = 1;
т.е. код который задаст значения по умолчанию для определенных ранее аргументов
5. в заголовок и empty text вида пишем следующий код генерации урлов:
$rs = db_query('SELECT * FROM {term_data} t WHERE t.vid='.arg(1));
while ($term = db_fetch_object($rs))
{
$t = arg(2)==$term->tid ? "[$term->name]" : $term->name;
print(sprintf("<a href='?q=alpha/1/%d'>%s</a> ", $term->tid, $t));
}
?>
и... и все.
P.s. генератор ссылок описан для режима выключенных "чистых ссылок", в ином случаем надо поправить шаблон урла.
P.s.s. на сколько красивый вариант решать вам ибо друпал денсингом занимают часов 12 от силы.
P.s.s.s. вот вопрос в догонку, а как оставить алфавитную линейку на странице такого вида http://rodinakino.ru/films/vall-i ?
Извините за оффтоп, а не могли бы более подробно рассказать, как сделать такой анонс как на Вашей страничке http://rodinakino.ru/films(картинка, заголовок фильма, краткое описание)?
Много чего по теме перечитал, но толкового описания процесса и не нашел...
Это азы
Темизация вида ноды в файле шаблона node_ваш_тип.tpl.php