Друзья, при разработке очередного сайта на Drupal у меня вновь возник вопрос. Прошу помощи, ибо сам уже с неделю думаю над задачей — и вижу приемлемое решение только в том, чтобы отказаться от CCK и написать свой модуль.
Итак, ДАНО:
Есть сайт с афишами фильмов. Афиша — это тип контента, созданный при помощи CCK. У него сейчас такие поля:
Название (стандартное поле title)
Описание (стандартное поле body)
Постер (картинка фильма, Imagefield + ImageCache)
Дата показа (дата, делается модулем Date)
Кинотеатр (Ссылка на ноду, Nodereference)
Жанр (обычное текстовое поле с множественным выбором)
Режиссёр (простое текстовое поле)
В ролях (простое текстовое поле)
Рецензия (простое текстовое поле)
Выпущено (простое текстовое поле)
Сценарий (простое текстовое поле)
Итак, в текущем режиме всё работает идеально: Узнаётся в каком кинотеатре будет идти тот или иной фильм, узнаётся дата-время премьеры и последнего показа фильма, ну и затем заполняется афиша. Несложно? Несложно. Вот пример заполненной афишы:
Однако, что получается. В базе данных забито множество кинотеатров. И замечательный мультик «Валл-И» показывается если не во всех, то во множестве кинотеатров. И для того, чтобы оповестить пользователей об этом, нужно создать подобную авфишу ДЛЯ КАЖДОГО КИНОТЕАТРА И ДЛЯ КАЖДОЙ ДАТЫ. Т.е., если у меня в базе данных кроме кинотеатра «Руслан», есть ещё кинотеатр «Космос», то мне нужно создать афишу со следующим содержанием:
Жирным показаны те поля, которые отличаются от аналогичных полей предыдущей афишы.
Разумеется, это неэффективно — у меня получается множество практически одинаковых афиш, и на странице просмотра последних афиш у меня будет длинный список с одной и той же картинкой, одинаковым текстом и т.д. Раумеется, помимо раздражения пользователей, можно ещё и бан поисковых систем получить.
Итак, сформулируем задачу:
Нужно реализовать следующую афишу:
Здесь, строка «Кинотеатр / Дата: Руслан / 10.07.2008 18:21 - 23.07.2008 10:00» расшифровывается так: Кинотеатр / дата премьеры в этом кинотеатре / дата последнего показа этого фильма в этом кинотеатре.
ЗАДАЧА:
То есть, при создании афиши, нужно иметь возможность задать СЦЕПЛЕННЫЕ ПОЛЯ — в данном случае, забить поле Кинотеатр и сразу же для этого поля задать дату. Если у меня есть ешё кинотеатры, в которых пройдёт этот же фильм, то я должен опять — выбрать Кинотеатр и сразу же заполнить поле Даты для этого кинотеатра.
РЕШЕНИЕ №1
В CCK есть хорошая возможность: можно каждому полю приписать «множественность», и забив одно значение, можно забить ещё столько, сколько нужно. (Это делается при настройке поля, во вкладке «Общие настройки», Параметр «Количество значений»: установить в «Неограничено») Однако это работает для ОДНОГО ПОЛЯ. Я же хочу, чтобы подобная возможность работала для группы полей (в данном случае, опять же, речь идёт о Кинотеатре и Дате). Т.е. заполнив одну пару полей, я хочу, чтобы были показана другая пара полей.
Можно, конечно, сделать для каждого из сцепленных полей (Кинотеатр и Дата) установить Количество значений в «Неограниченно», и вводить их по очереди. Ввёл 3 Кинотеатра, потом принялся за даты: ввёл три даты премьер, ввёл три даты последнего показа. Затем, при выводе материалов, нужно будет смотреть какие даты к какому кинотеатру относятся, сопоставляя порядковые номера массивов. Первый кинотеатр — первая дата премьеры — первая дата последнего показа и т.д.
Однако минусы этого подхода очевидны:
- это неудобно визуально,
- пользователь легко может ошибиться при сопоставлении какому кинотеатру — какая дата,
- невозможно задать «жёсткий режим»: например, нельзя задавать три даты премьеры, если задан только один кинотеатр и т.д. - проверку этого известными мне способами с помощью CCK сделать невозможно.
Но есть и другой способ..
РЕШЕНИЕ №2
Разбить данную связь много-ко-многим на две 1-ко-многим. Разбиваем сущность «Афиша» на две сущности: «Фильм» и собственно «Афиша».
Вот такими полями будут обладать эти сущности:
В сущности «Афиша», у нас поля Фильм и Кинотеатр, выделенные жирным курсивом, будут ссылками на ноды (Nodereference — поле).
Таким образом, мне, чтобы ввести афишу, придётся сначала забить фильм, а затем уже создать афишу фильма. И создавать отдельную афишу фильма на каждый день и на каждый кинотеатр.
Однако в этом случае у меня остаётся неразрешённым вопрос: а как мне выводить афишу в таком виде:
С помощью модуля Views я не знаю, как это сделать.
Вот если писать свой модуль, и работать напрямую с базой данных, то любое из вышеописанных решений делается элементарно — я знаю как это делать, и это делается всё очень просто, а вот если делать с помощью CCK — то у меня тут затруднения, не знаю как.
В общем, дорогое друзья, прошу помощи. Может есть какие-то другие решения?
Комментарии
А что мешает юзать словари со свободным заполнением? Создаем ноду (фильм), а дальше указываем в словаре КИНОТЕАТРЫ название этих кинотеатров. Ну и для остального также, я не думаю, что там много новых жанров наизобретали И заполнять проще и быстрее будет.
Далее по дате какие соображения... Дать доступ юзерам редактировать эту ноду, но с ограничением по полю (есть cck-модуль). Типа cck_date_ruslan для представителей Руслана, cck_date_kosmos для Космоса. Текст ноды или в отдельное cck поле выносить, или редактрование темизировать так, чтоб народ не смог текст перебодяжить.
автор, по поводу CCK:
используйте связи многие ко многим через node reference и вложенные виды views field
этим viws field можно передавать аргументы, в основном это NID, но можно и другие, например время и так далее...
Можно сделать макет сложной страницы через panels, они поддерживают передачу аргументов
всё что вам нужно - это написать схему данных на бумажке, установить связи и воспользоваться указанными модулями.
Я уже давно практикую вывод сложных материалов с помощью связией главных и дочерних нод. Аргументы передаются через views или panels/
KCEOH, спасибо за ответ, но Вы написали его, наверное, ещё до того, как я закончил редактировать сообщение и вставлять картинки.
У меня несколько другой вопрос...
За совет разграничить доступ по полям спасибо, однако в вашей схеме получается, что я должен ввести столько полей вроде cck_date_ruslan, сколько у меня кинотеатров, а это не самая лучшая идея
что-то вот в голове вертится решение, да никак не сформулируется что-то...
вот решение:
[тип ноды фильм]<-------->[прокат в киноеатре]<-------->[кинотеатр]
вы выводите ноду [прокат в кинотеатре], захватывая материал про фильм и сами кинотеатры
kyky, спасибо за наводку.
Сразу же поискал на оф. сайте модуль views field, но нашёл только это: Views Tabs, Views Static Field
Нашёл модуль Viewfield, может вы про него мне говорили? Вроде по описанию подходит: When the node is displayed, the view is run and the content is inserted into the body of the node...
Буду копать, спасибо!
Да, kyky, ещё раз спасибо! Кажется это то что надо. Я просто не знал про модуль Viewfield.
Наверное у меня ещё остались вопросы по разграничению доступа к полям, нодам и апгрейде на 6-ку, только сейчас я не могу их сформулировать...
kyky, а как сделать так, чтобы при создании документа типа [прокат в киноеатре] , как Вы предложили, у представителей кинотеатра "Космос" (это определённая роль пользователей) отображался только кинотеатр "Космос" в списке кинотеатров, а не все кинотеатры из базы данных?
andyceo
Сделать автором ноды Космоса данного пользователя, а список кинотеатров выводить через Views с фильтром "текущий пользователь"
jason32, спасибо!
Но я извиняюсь, а можно ли как-то посложнее задать фильтр? например, автор документа + админ + модераторы.
Дело в том, что у меня там довольно сложная система ролей на сайте - есть верховный админ, есть модераторы афиш (ибо один я всё не осиляю). Можно ли в фильтрах Views'а делать выборки в зависимости от ролей пользователя? (Наверное я очень плохо знаю Views... извиняюсь если вопросы нубские...)
Подскажите, пожалуйста! Или ткните меня носом в мануал,я вкурю! Заранее спасибо...
на своем сайте я делал уже две версии афиши с помощью view и сск.
в данный момент рабочий вариант такой:
есть ноды типа фильм (набор полей примерно как тут http://www.drupal.ru/files/images/db_entry_film_tn.gif
есть ноды типа афиша (время) и там из полей только: название, node reference на тип фильм, в поле описание руками пишется, в каком кинотеатре какие сеансы, ну и cck_date. и все. вывод этого всего осуществляется через views типа лист, и уже в шаблоне из поля с node_reference nid получается нода с описанием фильма.
У этого способа огромный плюс, в том, что можно задавать афишу на каждый день, ведь известно, что сеансы день ото дня могут меняться.
из такого явного недостатка - в данной конфигурации невозможно сделать выборку по кинотеатру, но в теории это решается путем добавления словаря, в котором термины будут означать названия кинотеатров. этот словарь привязать к материалу типа афиша-время и таким образом при заполнении этой ноды надо будет лишь галочкой отметитиь нужные термины (которые будут означать что этот кинотеатр показывает фильм). в таком случае сделать выборку по кинотеатру - проще простого.
В предудущей версии афиши я пользовался таксономией и имел лишь один тип материалов (описание). На каждый кинотеатр я создавал свой словарь и привязывал его к описанию фильма. Терминами в словаре было время начала сеанса. В принципе, если скомбинировать этот подход с текущим вариантом, то получится совсем хорошо, но! Почему я отказался от варианта с таксономией? Таксономия, да еще с выборкой терминов по куче словарей - это все ужасно медленно, просто ужасно медленно было. Ну по крайней мере в моей конфигурации: у меня на страниче должно было грузиться порядке 20-30 фильмов.
Надеюсь, чем-то помог.
Спасибо всем ответившим! Извиняюсь, что отвечаю так поздно.
К сожалению, модуль Viewfield не подошёл, т.к. у него нельзя задать динамические аргументы к Views. Скажем, у меня создан Вид, в него в качестве аргумента передаётся ID ноды, вид выдаёт документы. Так вот, когда я создаю тип материала, использующий данный вид, я не могу указать в качестве аргумента ID текущей ноды, например. Только константу какую-то.
Нашёл решение в виде вставки вида вручную из шаблона: Inserting Views. Также изучаю эту тему: How can I make an embedded view take an argument from a URL?
Перевёл статью Inserting Views на русский язык.