Views. Часть первая - изменение параметров "на лету"
Прислано: Dan
пт, 17/11/2006 - 11:08
Посвящается jerboa7 и Natalie :)
Периодически сталкиваюсь с проблемами использования views, после решения которых
охота поделиться полученным опытом. Но вот времени как обычно не хватает. Попробую
исправиться и рассказать о паре приёмов, которыми пользуюсь довольно часто.
Потребность в написании возникла после диалога с jerboa7 в теме o CCK.
Итак, дано:
На сайте расположены биографии писателей. Биография каждого писателя - на отдельной
странице. Страница содержит: вводную информацию, список произведений этого писателя,
список его статей, список интервью и т.д. и т.п.
Количество писателей может быть достаточно большим.
Задача:
Дабы не плодить огромное количество списков: список произведений, список статей,
список интервью и т.д. для **каждого** писателя, необходимо создать универсальные
списки, которые будут на странице писателя отображать его статьи, произведения и т.д.
Приступим.
- Установим Drupal и модуль views. Для последующих действий нам большего не потребуется.
- Создадим категорию "Писатели". Необходимо отметить типы материала, в которых надо
использовать этот словарь, поставьте галочки на 'page' и 'story'. В категории
создадим термины (писателей): - Пушкин
- Лермонтов
- Кобо Абэ
- Создадим личные страницы писателей (воспользуемся типом page). Названим пусть
будет фамилия писателя, тело статьи пока пустое и не забудьте проставить нужные
термины из категории писателей (для страницы "Пушкин" термин должен быть "Пушкин") - Создадим статьи о писателях, воспользовавшись типом 'story'. Допустим три статьи
на каждого писателя, итого - девять :) Название: "Статья -- Кобо Абэ 1", "Статья
-- Кобо Абэ 2" и т.д. Не забываем в каждой статье проставлять нужные термины. - Строим вид. Я привожу только те параметры, которые я изменял, остальные - по умолчанию.
- Имя(name) - test; Галочка на "Provide Page View" (показывать на странице);
- Тип (View Type) - List view (список).
- Фильтры (filters):
Тип материала (Node: Type) - 'story' (Is Onу of - story)
Один из терминов словаря "Писатели" (Taxonomy: Terms for Писатели) - Кобо Абэ (Is Onу of - Кобо Абэ) - Поля (Fields)
Заголовок (Node: Title) - Изменяем личные страницы писателей. В теле страницы, после вводного тек текста
необходимо вписать нижеследующий код (отметьте фильтр "PHP code"). Комментарии
включать не обязательно.
<?php
// имя вида
$view_name = 'test';
// получаем объект
$view = views_get_view($view_name);
// очищаем запрос
// Это надо прокомментировать. Дело в том, что модуль views составляет
// запрос к БД только один раз - в момент, когда вы сохраняете вид.
// Нам этот вариант не подходит, т.к. параметры вида у нас изменяются,
// соответственно должен изменяться и запрос. У модуля есть проверка на
// пустой запрос - в этом случае он создаётся заново. Именно этот хак
// мы и используем. Для маньяков - оптимизаторов (хотя таковые views и
// не используют, наверное) - можно сохранять запрос после радактирования
// вида и вставлять его здесь, но не думаю что этот способ имеет право на
// жизнь.
$view->query = $view->countquery = "";
// получаем термин, к которому относится данная страница.
// Функция arg(1) возвращает номер материала, то есть если у нас путь к
// статье /node/25, то ф-я возвратит 25
// Последняя цифра в данном выражении (1) - номер словаря, его можно
// узнать на странице редактирования словарей (admin/taxonomy/), наведя
// указатель мыши на категорию (в нашем случае это будет номер 1.
// Внимание!
// функция taxonomy_node_get_terms_by_vocabulary возвращает массив терминов
// в нащем случае одна статья не может принадлежать двум и более терминам,
// но если такое произойдёт, будет взят первый из списка (ф-я array_shift)
$tid = array_shift(taxonomy_node_get_terms_by_vocabulary(arg(1), 1));
// просматриваем все фильтры нашего вида и ищем нужный (один из терминов
// словаря). Это будет фильтр с идентификатором term_node_N.tid, где N -
// номер словаря.
// напоминаю, что $tid->tid содержит номер термина (писателя) данного материала
foreach($view->filter as $num => $item )
if($item['id'] === 'term_node_1.tid')
$view->filter[$num]['value'][0]=$tid->tid;
// отобразить вид
print views_build_view('embed', $view, array(), FALSE, $limit);
?>7. На сегодня всё :) Проверяйте.
- Dan's blog
- Для комментирования войдите или зарегистрируйтесь
А с квтегориями это все будет работать?
- Для комментирования войдите или зарегистрируйтесь
C модулем Category всё по другому, не удивлюсь, если всё это можно сделать стандартными средствами этого модуля. Например там ноду саму можно сделать категорией и привязать к ней другие ноды, чем не решение?
Но использовать его пока не хочу - сырой.
- Для комментирования войдите или зарегистрируйтесь
Я даже фотку на радостях сменила. Теперь я вот такая - со счастливыми глазами. :)
Сейчас буду это всё осуществлять.
Вы просто не представляете, как мне помогли.
- Для комментирования войдите или зарегистрируйтесь
Всегда пожалуйста!
Буду рад если пригодится!
:)
- Для комментирования войдите или зарегистрируйтесь
Да, эта фотография лучше :)
- Для комментирования войдите или зарегистрируйтесь
Простите, а в чем сырость Category?
На drupal.org в "issues" активней мелькает CCK чем Category.
ЗЫ. "issues" - это где делают баг репорты, запрашивают новые фичи, и постят патчи.
- Для комментирования войдите или зарегистрируйтесь
Это потому, что его больше юзают.
Да и на количество багов посмотрите (CCK-Category):
критических: 5 -8
нормальных: 17 - 57
Но дело не в количестве багов дело, я скорее говорю о личных впечатлениях.
При моём последнем знакомстве он был... как бы это сказать... непредсказуем. Одна и таже последовательность действий приводила иногда к разным результатам. Плюс не очень хорошее знание принципов его работы. Вобчем на боевой сайт ставить его пока точно не буду, а баловаться пока нет времени.
Может в ближайшем времени его снова попробую.
- Для комментирования войдите или зарегистрируйтесь
Чего мне стоил весь геморрой, когда при банальном апгрейде модуля вся вложенность категорий перепуталась.
_________________
memyself's
- Для комментирования войдите или зарегистрируйтесь
Спасибо за статью, действительно здорово =). Только вот taxonomy_dhtml не правильно работает с таким словарем, обидно. Может у кого есть идеи как можно сделать хлебные крошки? Ну или просто меню?
- Для комментирования войдите или зарегистрируйтесь
что-то не пойму - как он с i18n работает? - почему-то игнорирует язык и показывает все подряд
- Для комментирования войдите или зарегистрируйтесь
Вот дошли руки в локалке применить решение Dana. Всё получилось.
К сожалению, пока занимаюсь другим сайтом и не могу кинуть ссылку, как это всё работает.
По организации и затратам сил это даже проще, чем я предполагала.
Спасибо ещё раз.
- Для комментирования войдите или зарегистрируйтесь
Образчайся если что :)
- Для комментирования войдите или зарегистрируйтесь
Спасибо, Дан, очено полезное руководство!
Раз уж ты у нас заделался спецом по Views, такой вопрос - как сделать специальный вид нод для какого-то конкретного словаря? Views может переписать дефолтный taxonomy/term, но это будет действовать на все категории, а если мне нужно только на какие-то определенные? Я так понимаю, что это надо делать через аргументы, но как именно?
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.
- Для комментирования войдите или зарегистрируйтесь
Ох уж мне эти аргументы! По их поводу могу сказать одно: "тема аргументов не раскрыта" :(
Я не удивлюсь, если всё описанное мною тут можно сделать с их помошью....
Вообще вторую часть я собирался писать про аргументы. Давай попробуем асилить это вместе?
Мне нужно:
- более подробное описание твоей задачи (с примерами).
- подборка ссылок на drupal.org об аргументах - в англ. я не очень (медленно читаю), но если есть хорошая документация/пример, то - не проблема.
(я не много хочу? :)
- Для комментирования войдите или зарегистрируйтесь
В том-то и дело, что нормальной документации "для чайников" по аргументам нет. Народ что-то творит, а объяснять не может или не хочет :) У меня задача такая: допустим, есть словарь "Новости", в котором ноды показываются в стандартном обратном хронологическом порядке. Соответственно, его мы не трогаем. И есть словарь "Энциклопедия", в котором нужно показать ноды в алфвитном порядке. Как мне сделать вид для этого словаря, чтобы он не затрагивал остальные? Чтобы при заходе на любой термин этого словаря ноды показывались в алфитном порядке. Все это достаточно просто сделать через Category, но увы, cat vies глючит, и мне надоело ждать, пока Джаза разберется с этими и другими багами. Я уже даже заплатить готова, но не знаю, найдутся ли желающие :)
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.
- Для комментирования войдите или зарегистрируйтесь
Ну вобчем так.
Создал вид:
Fields:
Name -- Node: Title
Sortable -- Yes
Default Sort -- Descending
Filters
Field -- Taxonomy: Term
Operator -- Is All Of
Value -- XXXXX: YYYYYYY
Arguments
В "Argument Handling Code" помещаем следующий код:
<?php
$view->query = $view->countquery = "";
foreach(
$view->field as $num => $item )
if($item['id'] == 'node.title')
$view->field[$num]['defaultsort']=arg(2);// второй аргумент: ASC или DESC
foreach($view->filter as $num => $item )
if($item['id'] == 'term_node.tid')
$view->filter[$num]['value'][0]=arg(1); // первый аргумент (номер терма)
?>И делаем URL какой-нить, например term_test
И теперь путь "term_test/1/asc" вывод всех нод, привязанных к терму номер 1 в порядке Ascending (возрастания), а "term_test/1/DESC" - в порядке Descending (убывания).
Можно развить функциональность, например если задан термин номер 7, то порядок сортировки - возрастание, иначе - убывание; код для первого foreach измениться на следующий:
<?php
.....
foreach($view->field as $num => $item )
if($item['id'] == 'node.title')
$view->field[$num]['defaultsort']=((arg(2)==7)?' ASC' : 'DESC');
.....
?>Использование: "term_test/1" или "term_test/7" и т.д.
То что надо?
- Для комментирования войдите или зарегистрируйтесь
Вообще аргументы, как я понял, не для этого делались, но хак, думаю полезный. В принципе отпадает необходимость в коде, который я привёл в самом начале темы, да и удобней стало - не надо заводить отдельную страницу с PHP-кодом.
- Для комментирования войдите или зарегистрируйтесь
Придется, видимо, Natalie платить... :-)
- Для комментирования войдите или зарегистрируйтесь
Дан, спасибо, полезная идея. Это не совсем то, что мне нужно, но все рвно пригодится, я думаю.
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.
- Для комментирования войдите или зарегистрируйтесь
Не, ты скажи как надо - попробую сделать :)
- Для комментирования войдите или зарегистрируйтесь
а можно на страницах views делать фильтры изменяемые пользователем? (например, трекер с выбором нужных терминов и возраста нод)
- Для комментирования войдите или зарегистрируйтесь
Юзай "Exposed Filters"
- Для комментирования войдите или зарегистрируйтесь
Здрасьте, это опять я :)
Нужна модификация первого примера, с nodereference вместо терминов.
Имеется: страница автора (один тип материала) и несколько страниц произведений (другой тип материала), которые ссылаются на автора через nodereference. Нужно, чтобы на странице писателя отображались все произведения, для которых он автор (то бишь, ссылаются на него через nodereference).
Требуется унивесальный view и универсальный код, который можно вставить в шаблон писателя с тем, чтобы это работало для всех сразу :)
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.
- Для комментирования войдите или зарегистрируйтесь
Вроде сама разобралась, там не так сложно было.
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.
- Для комментирования войдите или зарегистрируйтесь
Несложно для "Мастера Views", Natalie :). Может кратенько напишете, что сделали?
"Что там было, как ты спасся?" (с) Высоцкий
Я ставлю строчку "php_value error_reporting 7" в файл .htaccess, а вы? :)
Полный русский перевод Drupal 5.x и еще некоторых модулей.
- Для комментирования войдите или зарегистрируйтесь
Несложно, в смысле программировать не надо, а стащить сниппеты с drupal.org :)
В виде выбрать аргумент нужный nodereference, а в поле для кода вставить
$args[0] = arg(1);
В шаблон вставить
<?php
//Загружаем вид, view_name - уникальное имя вашего вида
$view = views_get_view('view_name');
//Это просто заголовок
print t("<br />");
print t("<h2>Заголовок для view</h2>");
//вставляем вид в страницу
print views_build_view('embed', $view );
?>---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.
- Для комментирования войдите или зарегистрируйтесь
ААА гемор-то какой! Уж лучше я без views сделаю страницу, чем разбираться с аргументами и проч! %)
Например, каталог партнеров по странам в виде ноды типа page:
Текст-текст-текст.......
<h2>Наши партнеры</h2>
<?php
// список ссылок на страны
$country = (int)$_GET['country'];
$contries = taxonomy_get_children(119); // все страны (из таксономии)
foreach ($contries as $c) {
$count = taxonomy_term_count_nodes($c->tid);
if ($count) {
$link = $c->tid == $country ? $c->name : "<a href='" . url("partners", "country=$c->tid") ."'>$c->name</a>";
echo "<li>$link</li>";
}
}
?><?php
// список партнеров в выбранной стране
if ($country) {
print taxonomy_render_nodes(taxonomy_select_nodes(array($country)));
}
?>- Для комментирования войдите или зарегистрируйтесь
views очень полезная штука, без него в друпале сложно, пример как работать с аргументами можно подсмотреть в модуле галереи acidfree
- Для комментирования войдите или зарегистрируйтесь
Если владеешь PHP и знаешь API Drupal'a, многие модули ни к чему. И без ССК вполне можно обойтись.
- Для комментирования войдите или зарегистрируйтесь
так для того и модули и сделаны что-бы не писать все вручную, для того и друпал сделали, но то такое дело - а вот скажите - где взять типа api.drupal.org но что-б там были api от всех модулей а не только от ядра, возможно-ли такое?
- Для комментирования войдите или зарегистрируйтесь
2kiev: да, возможно. ставишь модуль локально и он индексирует все установленные в системе модули. я делал. работает :)
- Для комментирования войдите или зарегистрируйтесь
измучался я с этими видами. Мне надо очень просто: подсчитать сколько в результате нод получается при моем views 'protocols' с аргументом 433 - сколько на drupal.org не копался - так примера и не нашел
сделал наугад вот так:
$view = views_get_view('protocols');
$view_args = array(0 => 433);
views_build_view('embed', $view, $view_args, false);
print $view->num_rows;
но чувствую что это полное ламерство - непонятно как посредине вызванное views_build_view влияет на конечный результат - подскажите - как правильно?
- Для комментирования войдите или зарегистрируйтесь
Привет всем! У меня такая проблема:
Есть тип контента сборник и тип контента композиция.
Некий пользователь создает сборник, а в нем есть возможность для других пользователей вставлять композиции, то есть в сборнике присутствует ссылка "добавить композицию", при переходе по которой открывается страница для создания композиции, причем эта композиция уже автоматически относится к данному сборнику.И кроме того сборник должен содержать список всех относящихся к нему композиций.
Если кто может расписать по пунктам какие действия требуется сделать,пожалуйста ответьте!
- Для комментирования войдите или зарегистрируйтесь
Это подчиненный материал - организуется при помощи views + editview (for views) + viewfield (cck).
- Для комментирования войдите или зарегистрируйтесь
Может не заморачиваться? :)
Есть сборник, пользователь его может редактировать, так?
Если надо запретить редактировать отдельные поля, это можно задать модулем (как называется не помню field permission или как-то так). Внутри сборника есть поле node_reference, с множественным выбором. Вуаля!
Для отображения списка, можно с помощью view создать блок и в разрешениях показа проставить что-то типа node/*/edit (не знаю, сработает ли, но можно и "руками" парсить путь)
- Для комментирования войдите или зарегистрируйтесь
Прости ,Дан, я что то не могу понять до конца твой совет. Напишу как понял:
1) создаем 2 типа нодов а) сборник и б) композиция
2) добавляем ссылку в нод сборник под названием "добавить композицию",которая ведет на http://mysite/node/add/composition ,то есть на страницу создания композиции
3)вопрос в следующем: эта композиция должна автоматически добавиться в список композиций данного сборника и пользователь не должен выбирать сборник к которому должна относится данная композиция,потому что сборники могу иметь одинаковые названия,и пользователь их не сможет отличить. Он просто добавляет в сборник в котором он кликнет на ссылку "добавить композицию".
- Для комментирования войдите или зарегистрируйтесь
nod_reference до конца не понятно как сделать , какие аргументы вписать? Или сам вью списка композиций как то нужно задать? Буду благодарен за помощь.
- Для комментирования войдите или зарегистрируйтесь
Хм, я по другому видел задачу:
- Существует энное количество "композиций". Они являются самостоятельными материалами и ни с чем не связаны.
- Также есть материалы типа "сборник", они являются сборником ссылок на композиции. Поэтому и предложил добавить в этот тип материала поле типа "Node Reference" с множественным выбором.
Опиши пожалуйста задачу подробнее:
- что представляют из себя сборники и композиции.
- как они между собой связаны
- как они будут представлены
- как должно быть реализовано редактирование, добавление, удаление
- Для комментирования войдите или зарегистрируйтесь
Типичный подчиненный материал !
1) В материале "сборник" создать поле editview (выбрать views настроенную для отображения композиций - настраивается передача аргумента nid parent);
2) В материале "сборник" создает computedfield в виде сслылки на создание "композиции" ( node/add/compositions?nid=$nid ) где nid - parent ID;
3) В материале композиция поле computedfield вычиляет при создании материала методом $_GET значение parent ID (PID);
:)
- Для комментирования войдите или зарегистрируйтесь
> Типичный подчиненный материал !....
Клёво! Надо будет попробовать.
Спасибо, Алексей!
- Для комментирования войдите или зарегистрируйтесь
Спасибо, за оценку комментария. А магистр случайно не знает как бы подчиненный материал без открытия новой формы реадктировать, например во viewfiеld ("по месту", "на лету") ? Заранее благодарен.
- Для комментирования войдите или зарегистрируйтесь
Алексей, не скажу - почему-то с первого раза завести связку editview+viewfield не удалось - апач валился с ошибкой. К сожалению нет времени разбираться нет. Если руки дойдут - отпишусь.
- Для комментирования войдите или зарегистрируйтесь
Более простое решение через CCK и аргументы views
http://drupal.org/node/124446
- Для комментирования войдите или зарегистрируйтесь
А можно со скриншотами описать в чем суть идеи и как она реализовывается?
Что-то не совсем понятно и не получается не "плодить списки писателей".
------------------------------------------------------------------------------------------------------------
Вот встречаешь частенько некоторые обучалки (типа этой, хотя совершенно из другой области) и душа радуется - все ясно. И программёру, и начинающему юзеру. Любому!
- Для комментирования войдите или зарегистрируйтесь
Спасибо за статью!
- Для комментирования войдите или зарегистрируйтесь
Для atl - http://drupal.ru/node/5781
- Для комментирования войдите или зарегистрируйтесь
Даниэль, не могли бы вы указать, на каком сайте это реализовано?
- Для комментирования войдите или зарегистрируйтесь
2ii: хоть и запоздалый ответ, но всёж...
Для какого сайта делал не помню, но сейчас это делается легко с помощью аргументов (во время написания статьи они или криво работали или простоя с ними не разобрался).
PS: может спросить у jerboa7?
- Для комментирования войдите или зарегистрируйтесь
попыталась сделать по Вашей инструкции, поставила фильтр "PHP code", в тело скопировала код, отправила, в результате получилась текстовая страничка с цветным тексом, код не исполняется. проверила доступ, все ок.
не подскажете как заставить код исполняться?
- Для комментирования войдите или зарегистрируйтесь
Какой вы используете визуальный редактор?
Нужно этот код вставлять именно в html (для FCKeditor кнопка "источник"), а не в окошко редактора (не относится к bueditor)
- Для комментирования войдите или зарегистрируйтесь

















Комментарии