После победы на выборах в Сенат Штата Нью-Йорк, впервые за почти 50 лет, Демократическая партия обратились к Advomatic с просьбой быстро развернуть новый сайт на Drupal. Были многочисленные проблемы, которые предстояло преодолеть, и их требования заставляли выйти за грани возможного в некоторых областях, таких, как разграничение прав доступа и общий порядок действий (workflow). В конце концов, этот сайт, является свидетельством того, что может быть достигнуто командой разработчиков, путем целенаправленной разработки и экспериментирования, используя мощность и гибкость Drupal и его сообщества.
Ранее, каждый сенатор контролировал свою собственную маленькую вотчину в сети (часть одного сайта), используя проприетарный, написанный на ASP сайт, со слабыми связями между частями. Сенат хотел продолжить эту практику, т.е. сенаторы по-прежнему должны были контролировать свои собственные подсайты, однако их содержимое должно было проще разделяться между сайтами, и чтобы была возможность размещать выбранные статьи отдельных сенаторов в основном разделе сайта.
Очевидно, это требовало мультисайтового решения, и это должно было быть решено в первую очередь, так как от этого решения зависела дальнейшая разработка.
Мы просмотрели несколько предлагаемых решений и модулей, позволяющих развернуть такой сайт, и в итоге решили реализовать собственный метод, похожий на тот, что мы применили для Air America Radio, по причине уникальных требований. Это решение состояло в создании типа материала "Сенатор" ("Senator"), на который могут ссылаться все другие типы материалов, и эта ссылка будет использоваться для группировки. Например, раздел сайта, посвященный сенатору Малькому А. Смиту (Malcom A. Smith) группирует все его материалы, со специальным заголовком, специализированным навигационным меню, блогом и т.д.

Дизайн, созданный нашими дорогими Амандой Люкер и Джеком Хаазом (Amanda Luker and Jack Haas), аппелировал к двум основным темам, в зависимости от принадлежности к партии. Мы просто добавили выпадающее поле с вариантами "Синий" и "Красный", первоначально с целью включения этой информации в глобальную переменную $custom_theme по мере необходимости. В конце концов мы решили просто печатать это значение в css-классе для тега body, так как было проще переключать оформление с помощью CSS, чем использовать две разные темы. Мы использовали Cufon для замены изображений на сайте.
Сделать навигационное меню было гораздо труднее. Они хотели, чтобы каждый сенатор имел свое собственное меню, при этом, оно изначально должно было содержать некоторые пункты, что не должно мешать сенатору изменять меню так, как ему заблагорассудится. Мы быстро отклонили стандартное меню в качестве варианта, поскольку мы не хотели открывать ящик Пандоры - предоставление полного доступа к системе меню недовольными офисными редакторами. Даже если бы мы предоставили доступ только на определенное меню, то это не решило бы задачу автоматически создавать подходящее меню из шаблона, которое будет использовать 95% сенаторов.
В конце концов, мы решили использовать поле Link для меню, которое будет напечатано путем переопределения $vars['primary_links'] в phptemplate_preprocess_page(). Тогда мы просто проверяем путь, чтобы увидеть, находимся ли мы на странице, ссылающейся на сенатора, и в этом случае делаем переопределение. Мы также реализовали токен для этого, так что мы можем заполнить меню такими полезным путями по умолчанию, как, например, [senator]/blog и [senator]/gallery.
Так как было много других случаев, для которых нам необходимо было знать, загружается ли специфическая страница, ссылающаяся на сенатора, мы положили все отслеженные аргументы в статическую переменную во время выполнения hook_init(), так что мы легко смогли бы обнаружить этот случай: вызов nyss_senator() возвращает либо FALSE, либо ссылающуюся на сенатора ноду.
После создания основных типов контента, с необходимыми полями, ссылающимися на ноду с сенатором, пришло время для наполнения нашего сайта. Первоначальный продавец предоставил нам диск с резервной копией, в которой было примерно 12000 единиц контента. Мы написали скрипт быстрой миграции, чтобы отобразить исходные данные на наши новые типы контента. В прошлом, мы сделали это просто через командную строку. Сегодня же, я бы предпочел погрузиться в пакетные операции Drupal 6, которые предлагают ловкий интерфейс, так, я бы только однажды положил скрипты в специальный администраторский обратный вызов, и мог бы наблюдать друплифицированную панель хода работ в то время, когда я ем попкорн.
Первоначальные данные были в базе данных Microsoft Access, что принесло ряд проблем при миграции. Во-первых, первоначальный дамп базы данных был поврежден, поэтому при миграции около трех четвертей всего контента вернулось со странными символами. После изучения ситуации, почему апострофы превращаются в символ a€™ (помимо всего прочего), мы узнали, что данные были повреждены, когда первоначальный продавец делал бекап базы данных. Как правило, функция PHP iconv() смогла бы преобразовать из кодировки Latin-1 в требуемую UTF-8. Однако, данные были повреждены сами по себе, что означало, что нам был необходим новый бекап. Несколько часов спустя мы получили новую резервную копию, которая и была надлежащим образом перекодирована.
Были и другие проблемы, связанные с исходными данными: не было уникальных полей в строках базы данных для картинок и PDF-файлов, они хранились встроенно, (что означало, что мы должны были изменить эти данные "на лету", в соответствии с нашей новой консолидированной папкой /files, а также преобразовать их в подходящие файловые объекты для последующего хранения в поле filefield). Потом была проблема редактирования 300 страниц Конституции Штата, как единой ноды.
Эти трудности были легко преодолимы, и в скором времени мы получили работающий сайт. Интересно, что в исходной проприетарной CMS не было ничего близкого к функции Drupal check_plain(), а это означало, что в прошлом некоторые продвинутые редакторы сенаторов пришли к таким фантазиям, как отображение заголовка страницы в виде JavaScript-бегущей строки...
Имея 12000 документов, размещенных в разделах более чем для 60 сенаторов, не все из которых хорошо работали друг с другом, мы должны были решить следующую задачу: распределение ролей и уровней доступа для редакторов на сайте. Это не решалось в лоб: все они должны были иметь возможность редактировать содержимое своих сенаторов, но не других сенаторов. Кроме того, если у одного сенатора было несколько редакторов, они должны были иметь возможность изменять работы друг друга, и нам также пришлось учитывать то, что некоторые редакторы работали на разных сенаторов.
Для этого мы использовали hook_node_access_records и hook_node_grants, чтобы обрабатывать доступ. Мы создали область доступа для возможных id сенатора в поле field_senator в документе, и отобразили ее на офисных редакторов, прикрепленных к сенатору. Они, в свою очередь, были прикреплены с помощью поля типа user_reference (предоставляется модулем CCK), с выбором из списка пользователей с ролью "Офисный редактор" (список пользователей был сделан модулем Views). Наконец, мы подправили вызов функции меню для node/[nid]/edit для проверки прав доступа, чтобы не показывать людям без соответсвующих прав вкладку на редактирование, ведущую вникуда.

Мы интенсивно использовали модуль Flag на сайте. Это не только размещение материалов в карусельке на главной странице (которая была создана с помощью jQuery Cycle) и для других блоков на главной странице, но и похожие карусельки и закладки на страницах сенаторов, галереях, и других местах на сайте.
Конечно, это предоставило свой набор проблем для нашей уникальной структуры уровней доступа, например, сенатор не должен быть в состоянии ставить флаги на материалы другого сенатора. Чтобы обойти эту проблему, мы изменили ссылки на флаги, чтобы они не появлялись, если редактор не имеет возможности для редактирования конкретного документа.
Представления (модуль Views), конечно, наполняют сайт нашими материалами. После создания и доводки блоков и страниц с представлениями, мы экспортировали их все для лучшей производительности. Не было никаких серьезных проблем на этом этапе, за исключением нескольких запросов, которые не возможно было создать через стандартный пользовательский интерфейс (UI). В этих немногих случаях, мы использовали hook_views_query_alter. Кроме того, поскольку многие из представлений требуют аргумента (который ссылается на сенатора), а у нас был свой токен для указания пути к сенатору, который не обязательно совпадал с названием, мы были вынуждены написать наш собственный обработчик аргумента для представлений, который мы привязывали в PHP-блок проверки аргумента, случае необходимости.
Поскольку требовался сайт любой сложности, нам необходимо было внедрить ряд пользовательских блоков. Мы усовершенствовали систему на нескольких сайтах, о которых мы здесь продолжим, что позволило увеличить гибкость системы пользовательских блоков Drupal, с целью легко контролировать появление блоков с помощью кода, а не только встраивая в административную форму такие вещи, как видимость блока на определенной странице. В основном, при создании нового блока, мы определяли его видимость как 2 (то есть, видимость блока на страницах контролируется PHP-кодом), и задавали в нем вызов своей функции, с параметром $delta. Тогда, если в будущем мы примем решение переместить один или несколько блоков на другую страницу, мы можем изменить настройки в функции, вместо того, чтобы конфигурировать каждый блок в отдельности. Для дальнейшего облегчения конфигурации, а также для того, чтобы воспользоваться Drupal только в момент загрузки файлов, мы создавали соответствующие функции темы автоматически, как только добавлялся новый пользовательский $delta, загружая, если требуется, новый файл theme_custom_block_$delta.tpl.php.
Есть много мелочей, что потребовались для создания этого сайта, о которых я хотел бы рассказать вам, и их там было значительно больше, чем я могу рассказать без превращения данного обучающего примера в длинный роман. Я даже не коснулся Комитетов (Committees), Законодательства (Legislation), или проекта Открытые Данные (Open Data).
Команда разработки Advomatic была великолепна! Я помогал Джонатану ДеЛейглу (Jonathan DeLaigle), Аманде Люкер (Amanda Luker), Джеку Хаазу (Jack Haas), и Марко Карбоне (Marco Carbone). Смотрящими за проектом были Фред Гултц (Fred Gooltz) и Дилан Клеар (Dylan Clear). Отдельный привет EchoDitto, который нес ответственность за ранее управление проектом и за первые наброски проекта/спецификации. Также, Крейг Лейнофф (Craig Leinoff) первым из офиса Сената прибежал к нам, чтобы помочь разработать сайт и получить его готовым к запуску.
Я рад видеть все большее восхваление добродетелей Open Source от нашего правительства, и горжусь тем, что мы помогли снабдить Сенат Штата Нью-Йорк надежным Drupal-сайтом.
Аарон Винборн является разработчиком из Advomatic. Кроме разработки, Advomatic также предлагает широкий спектр других Drupal-услуг, включая обслуживание и кластерный хостинг. Помимо оказания помощи в производстве таких сайтов, как Сенат Штата Нью-Йорк, Воздух Америки, а также Mozilla, Аарон также вносит большой вклад в сообщество Drupal, включая такие модули, как Embedded Media Field (встроенное поле для медиа) и Views SlideShow (слайдшоу на основе модуля Views). Он написал книгу "Drupal Multimedia", опубликованную издательством Packt Publishing, и играет ведущую роль в проекте Google Summer of Code, чтобы помочь выпустить модуль Media. Вы можете почитать его дневники на сайтах Advomatic и AaronWinborn.com.
Источник: Статья The New York State Senate, английский язык.
Комментарии
Отправить комментарий