Алфавитная линейка на русском методами Views

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

Аватар пользователя seaji seaji 15 сентября 2007 в 14:05

Итак задача:

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

Во views существует возможность выбора в качестве аргумента - заголовка с фильтрацией по одной букве, но...
Работает все это только с англицкими названиями.

Решил я эту проблему транслитерацией заголовка и помещением его в специальное спрятанное поле (Computed Field).
Решение получилось немного мудреным. Если кто может предложить оптимизацию - Welcome !

Требуемые модули:

Решение:

Тип материала "фильм"

Для своего типа материала "фильм" создал новое поле.
Имя : 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
Заголовок: (это то, что будет над результатом, сюда рисуем саму линейку)

<style>
.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: (это то, что выводится если нет результата, сюда опять же линейку и какой нибудь текст)

<style>
.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

Комментарии

Аватар пользователя magway magway 15 сентября 2007 в 15:23

Хм. Может я немного не так понял, но у меня подобная задача решается без дополнительного кода. Пример: http://bestofbeauty.ru/base. Ссылки русского алфавита формируются вот так:

<a href="/base/%D0%90">А</a>
<a href="/base/%D0%91">Б</a>

Views нормально принимает такой аргумент.

Аватар пользователя magway magway 15 сентября 2007 в 17:04

Получил я это примерно так:
<?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";
}
?>

Аватар пользователя aga aga 15 сентября 2007 в 18:28

Спасибо, интересно!
Кстати, некоторые фильмы начитаются не с буквы, а с цифры, например "300 спартанцев". Так неплохо было бы добавить дополнительную категорию для подобных названий.

Аватар пользователя Гость Гость (не проверено) 19 сентября 2007 в 22:57

Может кто знает решение такой задачки:
Если фильмы нужно выводить не отдельно по буквам, а в общей ленте, НО чтобы вьюс давал не просто упорядоченный по алфавиту список фильмов. Нужен также и вывод заглавных букв.

А
Американский пирог. Комедия
Американский пирог-2. Комедия
Б
Батальоны просят огня. Боевик
...
В
...
Я
???

Аватар пользователя seaji seaji 20 сентября 2007 в 14:00

Тут видимо нужно создать страницу и в ней вызывать вид 33 раза (для каждой буквы).
Я так понял, что список должен быть на одной странице?

Аватар пользователя Гость Гость (не проверено) 20 сентября 2007 в 15:31

А есть красивые решения?
Поиски под друпал.орг и танцы с бубном над видами пока ничего не дали.

Аватар пользователя yo-ki yo-ki 10 ноября 2007 в 0:03

В общем, у меня не получается разобраться в работе модуля (что в принципе не удивительно пхп незнаю)
Я хочу сделать кнопку 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;
?>
В общем, функций я незнаю, сделал логически Lol
заменяю чтото видимо два раза одно и тоже из $letter_eng в $letter_eng , но должно работать ведь?

Аватар пользователя seaji seaji 10 ноября 2007 в 15:34

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

Лучше делайте как писал magway
Создаете вид.
Как аргумент делаете Node:Title
В опшинсах выставляете 1 (значит один символ)
Ссылки делаете так:

<a href="/base/%D0%90">А</a>
<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";
}
?>
Вот с цифрами не знаю.
Выводить каждую отдельной ссылкой - это можно, а вот объединить ...

Аватар пользователя zuk0 zuk0 27 ноября 2007 в 18:33

Вопрос автору..

А можно ли заставить это работать без использования модуля Pathauto ? Что и где для этого нужно изменить? Функциональность того что здесь есть меня полностью устраивает... только вот заставить это работать никак не получается. У меня, например, не установлен Pathauto, а в статье ни слова нет про его настройки.. Модуль то я установил (для чего понадобилось поставить еще некий Token... ) В результате имею ошибки от Pathauto, кашу в голове, и не решенную задачу с алфавитом ))

Как решается задача у magway'a вобще не понял.. без какого дополнительного кода? и как собственно решается? )

Буду признателен за любую помощь )

P.S. Все заработало как разобрался с Pathauto. Спасибо автору! )

Аватар пользователя magway magway 27 ноября 2007 в 20:23

Чего ж непонятного? Smile В view добавлется аргумент Node:Title, в Option ставится 1 (показывает количество букв в аргументе). В любое место страницы добавляется код со ссылками (я его расположил в Page header). Код примерно такой:

<div id="base-rusalpha">
<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

Аватар пользователя player player 20 февраля 2008 в 16:06

Скоро мне это понадобится. Хотелось бы узнать. Нет ли чего нибудь новенького по этому вопросу? Может появилось новое решение?

Аватар пользователя player player 1 марта 2008 в 20:29

У меня немного другая ситуация, но похожа. Есть словарь "Авторы" с терминами (их фамилии), соответственно каждый написал несколько книг, но это нам не надо =). Нужен список авторов в алфавитном порядке (алфавитной линейке). Пишем 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()
?>

Но!

  • Мне не нравится вывод алфавита. Хотелось бы сделать как в Node list. Там вообще все буквы всех алфавитов выводятся. Может можно грамотнее как нить?
  • Как грамотно можно ссылки на странице делать? чтоб не через $_GET передавать. Как правильно?

Да и вообще повалидатьте код если не сложно.

Аватар пользователя lazio lazio 8 августа 2008 в 3:05

Подскажите пожалуйста новичку, как таким образом, или похожим образом сделать линейку только на английские буквы?
спс

Аватар пользователя elmigo elmigo 20 октября 2008 в 9:50

еще достаточно красивый вариант моего производства, а как я уже потом посмотрел таких солюшенов предостаточно, но конкретно такого полного не встречал иначе бы часов 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(1)) $args[1] = 1;
if (!arg(2)) $args[2] = 1;

т.е. код который задаст значения по умолчанию для определенных ранее аргументов

5. в заголовок и empty text вида пишем следующий код генерации урлов:

<?php
$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 ?

Аватар пользователя deni_m deni_m 19 марта 2009 в 15:13

Извините за оффтоп, а не могли бы более подробно рассказать, как сделать такой анонс как на Вашей страничке http://rodinakino.ru/films(картинка, заголовок фильма, краткое описание)?

Много чего по теме перечитал, но толкового описания процесса и не нашел...