Views. Часть первая - изменение параметров "на лету"

Прислано: Dan

пт, 17/11/2006 - 11:08

Другие статьи по теме:

Посвящается jerboa7 и Natalie :)

Периодически сталкиваюсь с проблемами использования views, после решения которых
охота поделиться полученным опытом. Но вот времени как обычно не хватает. Попробую
исправиться и рассказать о паре приёмов, которыми пользуюсь довольно часто.

Потребность в написании возникла после диалога с jerboa7 в теме o CCK.

Итак, дано:
На сайте расположены биографии писателей. Биография каждого писателя - на отдельной
странице. Страница содержит: вводную информацию, список произведений этого писателя,
список его статей, список интервью и т.д. и т.п.
Количество писателей может быть достаточно большим.
Задача:
Дабы не плодить огромное количество списков: список произведений, список статей,
список интервью и т.д. для **каждого** писателя, необходимо создать универсальные
списки, которые будут на странице писателя отображать его статьи, произведения и т.д.

Приступим.

  1. Установим Drupal и модуль views. Для последующих действий нам большего не потребуется.
  2. Создадим категорию "Писатели". Необходимо отметить типы материала, в которых надо
    использовать этот словарь, поставьте галочки на 'page' и 'story'. В категории
    создадим термины (писателей):
    • Пушкин
    • Лермонтов
    • Кобо Абэ
  3. Создадим личные страницы писателей (воспользуемся типом page). Названим пусть
    будет фамилия писателя, тело статьи пока пустое и не забудьте проставить нужные
    термины из категории писателей (для страницы "Пушкин" термин должен быть "Пушкин")
  4. Создадим статьи о писателях, воспользовавшись типом 'story'. Допустим три статьи
    на каждого писателя, итого - девять :) Название: "Статья -- Кобо Абэ 1", "Статья
    -- Кобо Абэ 2" и т.д. Не забываем в каждой статье проставлять нужные термины.
  5. Строим вид. Я привожу только те параметры, которые я изменял, остальные - по умолчанию.
    • Имя(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. На сегодня всё :) Проверяйте.

Комментарии


Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Применить"
Опубликовано seaji в пт, 17/11/2006 - 14:19.

А с квтегориями это все будет работать?


Опубликовано Dan в пт, 17/11/2006 - 15:17.

C модулем Category всё по другому, не удивлюсь, если всё это можно сделать стандартными средствами этого модуля. Например там ноду саму можно сделать категорией и привязать к ней другие ноды, чем не решение?
Но использовать его пока не хочу - сырой.


Опубликовано jerboa7 в пт, 17/11/2006 - 16:21.

Я даже фотку на радостях сменила. Теперь я вот такая - со счастливыми глазами. :)
Сейчас буду это всё осуществлять.
Вы просто не представляете, как мне помогли.


Опубликовано Dan в пт, 17/11/2006 - 16:28.

Всегда пожалуйста!
Буду рад если пригодится!
:)


Опубликовано Dan в пт, 17/11/2006 - 16:28.

Да, эта фотография лучше :)


Опубликовано seaji в пт, 17/11/2006 - 22:16.

Простите, а в чем сырость Category?
На drupal.org в "issues" активней мелькает CCK чем Category.
ЗЫ. "issues" - это где делают баг репорты, запрашивают новые фичи, и постят патчи.


Опубликовано Dan в пт, 17/11/2006 - 23:07.

Это потому, что его больше юзают.
Да и на количество багов посмотрите (CCK-Category):
критических: 5 -8
нормальных: 17 - 57
Но дело не в количестве багов дело, я скорее говорю о личных впечатлениях.
При моём последнем знакомстве он был... как бы это сказать... непредсказуем. Одна и таже последовательность действий приводила иногда к разным результатам. Плюс не очень хорошее знание принципов его работы. Вобчем на боевой сайт ставить его пока точно не буду, а баловаться пока нет времени.
Может в ближайшем времени его снова попробую.


Опубликовано Flinblo в сб, 18/11/2006 - 19:34.

Чего мне стоил весь геморрой, когда при банальном апгрейде модуля вся вложенность категорий перепуталась.
_________________
memyself's


Опубликовано palych063 в вт, 21/11/2006 - 06:06.

Спасибо за статью, действительно здорово =). Только вот taxonomy_dhtml не правильно работает с таким словарем, обидно. Может у кого есть идеи как можно сделать хлебные крошки? Ну или просто меню?


Опубликовано kiev1 в вт, 21/11/2006 - 21:38.

что-то не пойму - как он с i18n работает? - почему-то игнорирует язык и показывает все подряд


Опубликовано jerboa7 в чт, 23/11/2006 - 12:10.

Вот дошли руки в локалке применить решение Dana. Всё получилось.
К сожалению, пока занимаюсь другим сайтом и не могу кинуть ссылку, как это всё работает.
По организации и затратам сил это даже проще, чем я предполагала.
Спасибо ещё раз.


Опубликовано Dan в чт, 23/11/2006 - 19:31.

Образчайся если что :)


Опубликовано Natalie в пт, 19/01/2007 - 02:31.

Спасибо, Дан, очено полезное руководство!

Раз уж ты у нас заделался спецом по Views, такой вопрос - как сделать специальный вид нод для какого-то конкретного словаря? Views может переписать дефолтный taxonomy/term, но это будет действовать на все категории, а если мне нужно только на какие-то определенные? Я так понимаю, что это надо делать через аргументы, но как именно?

---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.


Опубликовано Dan в пт, 19/01/2007 - 14:56.

Ох уж мне эти аргументы! По их поводу могу сказать одно: "тема аргументов не раскрыта" :(
Я не удивлюсь, если всё описанное мною тут можно сделать с их помошью....

Вообще вторую часть я собирался писать про аргументы. Давай попробуем асилить это вместе?
Мне нужно:
- более подробное описание твоей задачи (с примерами).
- подборка ссылок на drupal.org об аргументах - в англ. я не очень (медленно читаю), но если есть хорошая документация/пример, то - не проблема.

(я не много хочу? :)


Опубликовано Natalie в пт, 19/01/2007 - 22:20.

В том-то и дело, что нормальной документации "для чайников" по аргументам нет. Народ что-то творит, а объяснять не может или не хочет :) У меня задача такая: допустим, есть словарь "Новости", в котором ноды показываются в стандартном обратном хронологическом порядке. Соответственно, его мы не трогаем. И есть словарь "Энциклопедия", в котором нужно показать ноды в алфвитном порядке. Как мне сделать вид для этого словаря, чтобы он не затрагивал остальные? Чтобы при заходе на любой термин этого словаря ноды показывались в алфитном порядке. Все это достаточно просто сделать через Category, но увы, cat vies глючит, и мне надоело ждать, пока Джаза разберется с этими и другими багами. Я уже даже заплатить готова, но не знаю, найдутся ли желающие :)
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.


Опубликовано Dan в пн, 22/01/2007 - 20:48.

Ну вобчем так.
Создал вид:
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" и т.д.

То что надо?


Опубликовано Dan в пн, 22/01/2007 - 20:51.

Вообще аргументы, как я понял, не для этого делались, но хак, думаю полезный. В принципе отпадает необходимость в коде, который я привёл в самом начале темы, да и удобней стало - не надо заводить отдельную страницу с PHP-кодом.


Опубликовано vadbars@drupal.org в пн, 22/01/2007 - 21:06.

Придется, видимо, Natalie платить... :-)


Опубликовано Natalie в пн, 29/01/2007 - 19:12.

Дан, спасибо, полезная идея. Это не совсем то, что мне нужно, но все рвно пригодится, я думаю.
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.


Опубликовано Dan в вт, 30/01/2007 - 02:02.

Не, ты скажи как надо - попробую сделать :)


Опубликовано korj в ср, 31/01/2007 - 23:14.

а можно на страницах views делать фильтры изменяемые пользователем? (например, трекер с выбором нужных терминов и возраста нод)


Опубликовано Dan в чт, 01/02/2007 - 05:03.

Юзай "Exposed Filters"


Опубликовано Natalie в сб, 24/02/2007 - 21:59.

Здрасьте, это опять я :)
Нужна модификация первого примера, с nodereference вместо терминов.
Имеется: страница автора (один тип материала) и несколько страниц произведений (другой тип материала), которые ссылаются на автора через nodereference. Нужно, чтобы на странице писателя отображались все произведения, для которых он автор (то бишь, ссылаются на него через nodereference).
Требуется унивесальный view и универсальный код, который можно вставить в шаблон писателя с тем, чтобы это работало для всех сразу :)
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.


Опубликовано Natalie в вс, 25/02/2007 - 16:09.

Вроде сама разобралась, там не так сложно было.
---
---
All content management systems suck, Drupal just happens to suck less. -- Boris Mann at DrupalCON Amsterdam, August 2005.


Опубликовано vadbars@drupal.org в вс, 25/02/2007 - 16:15.

Несложно для "Мастера Views", Natalie :). Может кратенько напишете, что сделали?
"Что там было, как ты спасся?" (с) Высоцкий


Я ставлю строчку "php_value error_reporting 7" в файл .htaccess, а вы? :) Полный русский перевод Drupal 5.x и еще некоторых модулей.


Опубликовано Natalie в вс, 25/02/2007 - 16:34.

Несложно, в смысле программировать не надо, а стащить сниппеты с 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.


Опубликовано edhel в пн, 23/04/2007 - 08:37.

ААА гемор-то какой! Уж лучше я без 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)));
}
?>


Опубликовано kiev1 в пн, 23/04/2007 - 08:39.

views очень полезная штука, без него в друпале сложно, пример как работать с аргументами можно подсмотреть в модуле галереи acidfree


Опубликовано Dan в пн, 23/04/2007 - 12:36.

Если владеешь PHP и знаешь API Drupal'a, многие модули ни к чему. И без ССК вполне можно обойтись.


Опубликовано kiev1 в пн, 23/04/2007 - 15:30.

так для того и модули и сделаны что-бы не писать все вручную, для того и друпал сделали, но то такое дело - а вот скажите - где взять типа api.drupal.org но что-б там были api от всех модулей а не только от ядра, возможно-ли такое?


Опубликовано Dan в пн, 23/04/2007 - 15:42.

2kiev: да, возможно. ставишь модуль локально и он индексирует все установленные в системе модули. я делал. работает :)


Опубликовано kiev1 в пн, 14/05/2007 - 04:15.

измучался я с этими видами. Мне надо очень просто: подсчитать сколько в результате нод получается при моем 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 влияет на конечный результат - подскажите - как правильно?


Опубликовано gorr в вт, 22/05/2007 - 14:55.

Привет всем! У меня такая проблема:
Есть тип контента сборник и тип контента композиция.
Некий пользователь создает сборник, а в нем есть возможность для других пользователей вставлять композиции, то есть в сборнике присутствует ссылка "добавить композицию", при переходе по которой открывается страница для создания композиции, причем эта композиция уже автоматически относится к данному сборнику.И кроме того сборник должен содержать список всех относящихся к нему композиций.
Если кто может расписать по пунктам какие действия требуется сделать,пожалуйста ответьте!


Опубликовано sas@drupal.org в вт, 22/05/2007 - 15:12.

Это подчиненный материал - организуется при помощи views + editview (for views) + viewfield (cck).


Опубликовано Dan в вт, 22/05/2007 - 15:24.

Может не заморачиваться? :)

Есть сборник, пользователь его может редактировать, так?
Если надо запретить редактировать отдельные поля, это можно задать модулем (как называется не помню field permission или как-то так). Внутри сборника есть поле node_reference, с множественным выбором. Вуаля!

Для отображения списка, можно с помощью view создать блок и в разрешениях показа проставить что-то типа node/*/edit (не знаю, сработает ли, но можно и "руками" парсить путь)


Опубликовано gorr в вт, 22/05/2007 - 16:38.

Прости ,Дан, я что то не могу понять до конца твой совет. Напишу как понял:
1) создаем 2 типа нодов а) сборник и б) композиция
2) добавляем ссылку в нод сборник под названием "добавить композицию",которая ведет на http://mysite/node/add/composition ,то есть на страницу создания композиции
3)вопрос в следующем: эта композиция должна автоматически добавиться в список композиций данного сборника и пользователь не должен выбирать сборник к которому должна относится данная композиция,потому что сборники могу иметь одинаковые названия,и пользователь их не сможет отличить. Он просто добавляет в сборник в котором он кликнет на ссылку "добавить композицию".


Опубликовано gorr в вт, 22/05/2007 - 16:54.

nod_reference до конца не понятно как сделать , какие аргументы вписать? Или сам вью списка композиций как то нужно задать? Буду благодарен за помощь.


Опубликовано Dan в ср, 23/05/2007 - 06:21.

Хм, я по другому видел задачу:
- Существует энное количество "композиций". Они являются самостоятельными материалами и ни с чем не связаны.
- Также есть материалы типа "сборник", они являются сборником ссылок на композиции. Поэтому и предложил добавить в этот тип материала поле типа "Node Reference" с множественным выбором.

Опиши пожалуйста задачу подробнее:
- что представляют из себя сборники и композиции.
- как они между собой связаны
- как они будут представлены
- как должно быть реализовано редактирование, добавление, удаление


Опубликовано sas@drupal.org в ср, 23/05/2007 - 07:05.

Типичный подчиненный материал !
1) В материале "сборник" создать поле editview (выбрать views настроенную для отображения композиций - настраивается передача аргумента nid parent);
2) В материале "сборник" создает computedfield в виде сслылки на создание "композиции" ( node/add/compositions?nid=$nid ) где nid - parent ID;
3) В материале композиция поле computedfield вычиляет при создании материала методом $_GET значение parent ID (PID);
:)


Опубликовано Dan в ср, 23/05/2007 - 11:41.

> Типичный подчиненный материал !....
Клёво! Надо будет попробовать.
Спасибо, Алексей!


Опубликовано sas@drupal.org в ср, 23/05/2007 - 11:51.

Спасибо, за оценку комментария. А магистр случайно не знает как бы подчиненный материал без открытия новой формы реадктировать, например во viewfiеld ("по месту", "на лету") ? Заранее благодарен.


Опубликовано Dan в ср, 23/05/2007 - 13:42.

Алексей, не скажу - почему-то с первого раза завести связку editview+viewfield не удалось - апач валился с ошибкой. К сожалению нет времени разбираться нет. Если руки дойдут - отпишусь.


Опубликовано Dimm в чт, 24/05/2007 - 18:38.

Более простое решение через CCK и аргументы views
http://drupal.org/node/124446


Опубликовано Atl в сб, 26/05/2007 - 21:35.

А можно со скриншотами описать в чем суть идеи и как она реализовывается?

Что-то не совсем понятно и не получается не "плодить списки писателей".
------------------------------------------------------------------------------------------------------------
Вот встречаешь частенько некоторые обучалки (типа этой, хотя совершенно из другой области) и душа радуется - все ясно. И программёру, и начинающему юзеру. Любому!


Опубликовано Kostaz в пн, 25/06/2007 - 09:58.

Спасибо за статью!


Опубликовано sas@drupal.org в вт, 26/06/2007 - 09:07.

Для atl - http://drupal.ru/node/5781


Опубликовано ii в пн, 22/10/2007 - 04:32.

Даниэль, не могли бы вы указать, на каком сайте это реализовано?


Опубликовано Dan в сб, 03/11/2007 - 22:00.

2ii: хоть и запоздалый ответ, но всёж...

Для какого сайта делал не помню, но сейчас это делается легко с помощью аргументов (во время написания статьи они или криво работали или простоя с ними не разобрался).

PS: может спросить у jerboa7?


Опубликовано achadidi в ср, 26/12/2007 - 22:32.

попыталась сделать по Вашей инструкции, поставила фильтр "PHP code", в тело скопировала код, отправила, в результате получилась текстовая страничка с цветным тексом, код не исполняется. проверила доступ, все ок.
не подскажете как заставить код исполняться?


Опубликовано SaBoNim в ср, 26/12/2007 - 23:51.

Какой вы используете визуальный редактор?
Нужно этот код вставлять именно в html (для FCKeditor кнопка "источник"), а не в окошко редактора (не относится к bueditor)


Ссылки партнёров