Ромка!eu

  • Отдых
  • Работа
Главная — Блоги — Ромка's blog

Это старая (Drupal 6) версия сайта romka.eu. Она больше не обновляется, комментирование материалов отключено. Обновленная версия сайта доступна по адресу http://romka.eu.

Разработка модуля для Drupal. Часть3. Cron и темизация

Ромка — Вс, 01/03/2010 - 19:52

Регулярные процедуры

Чтобы Drupal периодически выполнял определенные действия, в планировщике задач операционной системы необходимо настроить запуск файла cron.php, который находится в корне каждого Drupal-сайта. При выполнении этого файла будет вызываться хук hook_cron, и в нашем модуле мы напишем его реализацию.

Процедура получения и обработки XML-файла, расположенного на удаленном сервере, довольно проста, поэтому она здесь не приведена. При желании вы можете самостоятельно разобрать логику работы этой функции, изучив исходные коды модуля Currencies. В результате ее работы формируется массив $result, в котором содержится информация о курсах валют и который передается функции темизации.

<?php
function currencies_cron() {
  
currencies_contents();
}
?>

Функцию currencies_contents() см. в листинге 3.

Листинг 3

<?php
function currencies_contents() {
  if(!
$c = cache_get('currencies')) {
    
/* здесь пропущен код, отвечающий за получение
       и обработку XML-файла */
    
$output = theme('currencies_block', $result);
    
$t = variable_get('currencies_list_freq', 3600);
    if(!
$t || !is_numeric($t)) $t = 3600;
    
cache_set("currencies", $output, 'cache', time() + $t);
  } else {
    
$output = $c->data;
  }
  return 
$output;
}
?>

Здесь мы сначала проверяем, нет ли запрашиваемых данных в кэше Drupal, если нет, то происходит соединение с удаленным сервером (его адрес указан через административный интерфейс модуля), получение и обработка XML-файла и формирование массива данных, который передает функции темизации. Функция темизации формирует выходной HTML-код, записываемый в кэш, его время жизни явно указывается исходя из соответствующей настройки, заданной в интерфейсе управления модулем. Drupal автоматически управляет закэшированными данными и при необходимости удаляет устаревшие записи.

Функция currencies_contents() будет использоваться не только при запуске cron-задания, но и при формировании блока с данными, который будет показываться пользователю. Таким образом, практически всегда пользователи будут видеть данные, полученные из кэша Drupal, если же на сайте не работает cron и нет закэшированных данных о курсах валют, то произойдет соединение с сервером ЦБ, формирование и запись в кэш необходимых данных.

Функции темизации

Теперь подробнее остановимся на функциях темизации. Теоретически прямо в коде функции currencies_contents() можно было бы сформировать HTML-код, который в дальнейшем и видел бы посетитель сайта в браузере. Однако такой подход неверен, поскольку при изменении оформления данных пришлось бы менять код модуля, а это влечет за собой две проблемы. Во-первых, модуль могут использовать сторонние разработчики, и им для внесения изменений придется вникнуть в структуру модуля и внести в него изменения, которые могут привести к ошибкам. Во-вторых, часто при разработке крупных проектов версткой и программированием занимаются разные люди. Верстальщик может не иметь представления о том, как работать с языком PHP в целом и модулями Drupal в частности. По этому правильнее вынести все действия, связанные с оформлением данных, в отдельные файлы и функции, для чего и нужны функции темизации.

Функции темизации — это функции, генерирующие HTML-код, который впоследствии показывается пользователю. Особенность таких функций в том, что, во-первых, они не должны реализовывать никакой бизнес-логики, т. е. в их задачи входит только генерирование HTML-кода на основе полученных аргументов. Во-вторых, эти функции могут быть переопределены разработчиком сайта без редактирования кода модуля, путем изменения файла template.php или создания файла-шаблона.

В нашем случае массив данных формируется функцией currencies_contents(), а HTML-код создается функцией theme_currencies_block(), которую нам сейчас предстоит определить и зарегистрировать. Подчеркну, что вызов любой функции темизации осуществляется через вызов функции-обертки с именем theme(), т. е. функция theme_currencies_block($argument) должна вызываться как theme('currencies_block', $argument). Чем вызвана эта необходимость, я объясню чуть позже.

Для регистрации функций темизации, используемых в модуле, мы должны реализовать hook_theme, который возвращает массив имен применяемых функций темизации и принимаемых ими параметров. В нашем модуле будет использоваться одна функция темизации theme_currencies_block(), которая на вход принимает один обязательный аргумент — массив курсов валют, поэтому реализация хука hook_theme будет выглядеть так:

<?php
function currencies_theme() {
  return array(
    
'currencies_block' => array(
      
'arguments' => array('result' => NULL),
    ),
  );
}
?>

Без такой регистрации вызов theme('currencies_block', $argument) будет невозможен. Сама функция темизации будет такой:
<?php
function theme_currencies_block($result) {
  
$output = "";
  foreach(
$result as $k => $v) {
    if(
$v["diff"] > 0) {
      
$color = "#5aaf43";
      
$v["diff"] = "+" . $v["diff"];
    }
    else if(
$v["diff"] < 0) $color = "#f00";
    else if(
$v["diff"] == 0) $color = "#00f";
    
$output .= "-" . $v["nominal"] . " " . $v["name"] . " = "
      
. $v["value"] . " (<span style=\"color: " . $color . "\">"
      
. $v["diff"] . "</span>)
"
;
  }
  
$output .= "";
  return 
$output;
}
?>

Еще раз обратите внимание на то, что в функции currencies_theme в качестве имени функции темизации указывается название currencies_block, а реализация ее имеет имя theme_currencies_block(). Нужно это, чтобы в дальнейшем разработчики сайтов, использующие наш модуль, могли переопределить эту функцию, т. е. изменить формируемый ею HTML-код. Для этого им в папке со своей темой в файле template.php достаточно будет создать функцию с именем, совпадающим с именем функции темизации, но в котором слово theme заменено на название используемой темы оформления, т. е. создать функцию название_темы_оформления_currencies_block(). Ядро Drupal, когда встретит в коде модуля вызов вида theme('currencies_block', $result), сначала попробует найти функцию темизации в файле template.php используемой в данный момент темы оформления, и только если там ее не найдет, использует функцию theme_currencies_block().

В случае больших шаблонов удобнее вынести функцию темизации из файла template.php в отдельный файл. Для этого в массиве, возвращаемом реализацией хука hook_theme, нужно добавить элемент с ключом template и именем, соответствующим имени файла-шаблона, а в каталоге с модулем разместить файл-шаблон с указанным ранее именем и расширением .tpl.php. В итоге hook_theme() примет вид:

<?php
function currencies_theme() {
  return array(
    
'currencies_block' => array(
      
'arguments' => array('result' => NULL),
      
'template' => 'cur-block',
    ),
  );
}
?>

а в папке с модулем нужно разместить файл с именем cur-block.tpl.php и таким содержимым:

<?php
  
foreach($result as $k => $v) {
    if(
$v["diff"] > 0) {
      
$color = "#5aaf43";
      
$v["diff"] = "+" . $v["diff"];
    }
    else if(
$v["diff"] < 0) $color = "#f00";
    else 
$color = "#00f";
    print 
"-" . $v["nominal"] . " " . $v["name"] . " = " .
      
$v["value"] . " (<span style=\"color: " . $color . "\">" .
      
$v["diff"] . "</span>)
"
;
  }
?>

Теперь, чтобы переопределить вывод данных, формируемых модулем Currencies, разработчику достаточно скопировать файл cur-block.tpl.php из папки с модулем в папку с используемой темой оформления и внести в него необходимые изменения.

Интерфейс пользователя

Сейчас наш модуль имеет интерфейс администратора, умеет автоматически соединяться с удаленным сервером, получать необходимую информацию, формировать из нее HTML-код и сохранять его в кэше. Осталась самая простая для программиста и наиболее значимая для посетителя сайта часть — вывод данных на экран.

Для решения этой задачи мы могли бы через созданную ранее функцию currencies_menu() зарегистрировать еще один путь и в качестве параметра page callback указать функцию currencies_contents(), которая получила бы необходимые данные (из кэша или от удаленного сервера) и вывела бы их на экран через функцию темизации. Но мы хотим, чтобы курсы валют выводились не отдельной страницей, а в блоке (оформленный особым образом элемент, содержащий данные) на любой заданной администратором сайта странице. Для этого необходимо создать реализацию хука hook_block() (см. листинг 4).

Листинг 4

<?php
function currencies_block($op = 'list', $delta = 0,
    
$edit = array()) {
  switch (
$op) {
    case 
'list':
    
$blocks[0] = array(
      
'info' => t('Currencies block'),
    );
    return 
$blocks;
    case 
'view':
    switch (
$delta) {
      case 
0:
      
$block['subject'] = t('Currencies block');
      
$block['content'] = currencies_contents();
      break;
    }
    return 
$block;
  }
}
?>

Параметр $op (сокращение от operation), содержит информацию о том, какая операция над блоком в данный момент выполняется. Значение list сообщает модулю, что информация о нем выводится в списке модулей, здесь мы должны передать ядру Drupal один обязательный параметр — заголовок модуля и ряд необязательных параметров, информацию о которых можно найти в документации.

Значение view аргумента $op означает, что пользователь просматривает страницу, на которой должен быть отображен наш блок, и модуль обязан вернуть его содержимое. Для этого функция должна сформировать и выдать ассоциативный массив, элемент с ключом content которого будет использован в качестве содержимого блока, а необязательный элемент с ключом subject — заголовка.

Каждый модуль может создавать несколько блоков, параметр $delta хука hook_block содержит индекс обрабатываемого в текущий момент блока.

Все, разработка модуля завершена! Теперь администратор сайта, после инсталляции модуля Currencies, может активировать созданный им блок, для этого необходимо перейти в меню Administer — Blocks (admin/build/block), перетащить мышкой строку с описанием блока в нужный регион (область страницы, которая может содержать один или несколько блоков) и сохранить изменения. В свойствах модуля доступны стандартные для Drupal средства управления блоком: список страниц, на которых блок должен показываться (или наоборот список страниц, на которых блок не должен показываться), список ролей пользователей, которые имеют доступ к содержимому блока, и другие.

Ссылки на другие части этой статьи:

  • Часть 1. Основы модульной системы Друпала
  • Часть 2. Разработка простейшего модуля
  • Часть 3. Введение в темизацию Друпала (для программистов, а не дизайнеров)

Содержание всех статей: http://romka.eu/blog/my-drupal-articles

  • cron
  • Drupal
  • модуль
  • статья
  • темизация
  • Ромка's blog

Вы храните в кэше

xandeadx (не проверено) → Пнд, 01/04/2010 - 15:46

Вы храните в кэше сгенерированный html, а не логичнее ли хранить там результат обработки xml файла (данные которые отдаются функции theme_currencies_block), а содержимое блока заполнять таким образом:

$block['content'] = theme('currencies_block', currencies_contents());

ведь html блоков и так кэшируется друпалом

hook_theme pattern

Anonymous (не проверено) → Пнд, 07/12/2010 - 18:09

У меня вопрос:
Как работать с шаблонами (pattern) в хуке hook_theme?
Мне нужно сделать целевые сраницы, т.е. чтоб по разным адресам появлялись формы регистрации, с разной темизацией. Задача усложняется тем что при создании шаблона " имя_шаблона.tpl.php", должна чоздаваться функция темизации и тепеэлка должна подхватываться Друпалом...
я сделал следующее:

в модуле:

<?php

function my_module_theme($existing, $type, $theme, $path) {
  return array(
    
'user_register' => array(
      
'arguments' => array('form' => NULL),
      
'pattern'   => 'user_register__',
    ),  
  );
}

function 
internetdevels_form_alter(&$form, &$form_state, $form_id) {
  if (
$form_id == 'user_register') {
    if (
is_file(drupal_get_path('theme','fly4smile') . '/user-register--' . arg(2) . '.tpl.php')) {
      
$form['#theme'] = arg(2);
    }
  }
}
?>

в tpl.php:

<?php return theme(array('user_register__' . $theme, 'user_register'), $form);?>


Но работать эта конструкция не хочет...В чем может быть проблема?

Темизация

sv2109 (не проверено) → Вс, 08/08/2010 - 17:17

Отличная статья! Спасибо огромное!
Единственное замечание - вы создаете шаблон, с которым поидее должен работать дизайнер, но этого:


<?php
  
foreach($result as $k => $v) {
    if(
$v["diff"] > 0) {
      
$color = "#5aaf43";
      
$v["diff"] = "+" . $v["diff"];
    }
    else if(
$v["diff"] < 0) $color = "#f00";
    else 
$color = "#00f";
    print 
"-" . $v["nominal"] . " " . $v["name"] . " = " .
      
$v["value"] . " (<span style=\"color: " . $color . "\">" .
      
$v["diff"] . "</span>)
"
;
  }
?>

ниодин дизайнер не поймет! Он или не станет разбираться с этим кодом и завтра по любой мелочи дергать вас, чтобы поменять напр. "#5aaf43" на "#5aafff" ИЛИ будет сам это менять в результете где-то пропустит кавычку или кому и в результате опять будет дергать вас, потому что сайт не грузится..

Выход:
вместо <?php"<span style=\"color: " . $color . "\">"?>
использовать <?php"<span class=\"" . $class . "\">"?>
Тогда любой дизайнер сможет изменить цвет (а также размер, шрифт, положение итп) простой правкой css кода

Обо мне

Всем привет!
Меня зовут
Роман Архаров, я профессиональный веб-разработчик, программирую на языках PHP, Python и Action-Script, в работе использую фреймворки Drupal и Django. В этом блоге я размещаю заметки и статьи, связанные с моей работой, отдыхом и другими интересными мне темами.

Похожие заметки

  • Несколько статей о Друпале
  • Темизация Drupal. Часть 2. Анатомия темы оформления Drupal
  • Темизация Drupal. Часть 1
  • Swftools и модуль Pdf2SWfField для Друпала
  • Разработка модуля для Drupal. Часть2

Популярные заметки

  • Авторизация на Drupal-сайте с помощью аккаунта ВКонтакте
  • Перетаскивание строк таблицы. Table drag and drop — плагин для jQuery
  • Темизация Drupal. Часть 3. Основы Drupal Forms API и темизация форм
  • Темизация Drupal. Часть 4. Темизация Views
  • AJAX. Обмен данными между клиентом и сервером, закачка на сервер файлов без перезагрузки страницы при помощи библиотеки jQuery.
  • Кеширование на Drupal-сайте. Сравнение встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Varnish
  • Тестирование модуля "Inner poll"
  • Несколько панорам из путешествия по Перу и Боливии
  • Arduino + bluetooth, небольшая проблема
  • Пример разработки плагина для модуля CCK

Подписка


Последние комментарии

  • drupal-admin → Кеширование на Drupal-сайте. Сравнение эффективности встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Var → Отличная статья
  • Меховщиков Руслана → Проверка имени пользователя на наличие букв из разных алфавитов → Re: Читал про это уже на
  • Вероника → Куба. Лето 2008. Часть 3 → По поводу "приветливых жителей" Тринидада
  • Sfero → Статья в PC Magazine/RE. Drupal: разработка модуля → Немного о контенте
  • RemaGe → Статья в PC Magazine/RE. Drupal: разработка модуля → -)
  • Ромка → Статья в PC Magazine/RE. Drupal: разработка модуля → Да, будет сборка, та которую
  • RemaGe → Статья в PC Magazine/RE. Drupal: разработка модуля → -)
  • anatinge → Поездка в Киев → спасибо :)
  • Ромка → Поездка в Киев → Да, в общем-то, ничего
  • GogA → Поездка в Киев → Заинтриговал, что там за

Новые заметки

  • Кеширование на Drupal-сайте. Сравнение встроенного в Drupal кеша, статического файлового кеша (модуль Boost) и Varnish
  • Любопытное поведение модуля syslog в шестом Друпале (баг?)
  • Arduino + bluetooth, небольшая проблема
  • Гугл 1 марта прекратил поддержку сервиса Google Friend Connect
  • Проба пера в HTML5 + canvas. Эффект ластика
  • Шесть рукопожатий
  • Доклад на DrupalConfMoscow 2011
  • Статусы разных сущностей в Друпале 6
  • Футер, прибитый к низу страницы
  • Путешествие по Перу и Боливии. Часть 2

Тэги

Drupal jquery Куба Лето 2007 Лето 2008 Отдых Работа Штуки-дрюки лето модуль статья цитата
еще тэги

Навигация

  • Exchange rate
  • Переход по внешней ссылке
  • Последние сообщения
  • Фотогалереи

Курсы валют

  • 100 Казахстанских тенге — 21,3687 (-0.43)
  • 10 Украинских гривен — 27,2852 (-13.04)
  • 1 Китайский юань — 10,2706 (-40.98)
  • 100 Японских иен — 53,5332 (+12.67)
  • 1 Доллар США — 65,6210 (+33)
  • 1 Евро — 69,8076 (+29.42)
  • 10000 Белорусских рублей — 36,3310 (-2.51)
  • 1 Турецкая лира — 22,9540 (+4.99)

10 случайных заметок

  • Небольшой отчет о прошедшем первом Российском семинаре по CMS Drupal
  • Перетаскивание строк таблицы. Table drag and drop — плагин для jQuery
  • Кнопки Home, End и Page Up, Page Down в Mac OS
  • Получение заголовков (HTTP-headers) страницы при помощи Java-script
  • Cinnamon Chasers - Luv Deluxe (Music Video)
  • Вспомнил детство
  • Validation — восхитительный короткометражный фильм
  • Зима 2010. Поездка в Тайланд, Индонезию и Сингапур. Часть 1 — Пхукет и Джакарта
  • Начинающий автор
  • Несколько смешных картинок

Случайные фото

Я на
Радуга над футбольным полем в Лужниках
Море
Замок Акерхус вечером
Крым
Дорожка
А это уже полуостров Крым, на пути в Керчь.
Опять я
Недалеко от Красной поляны
Оригинальная дорожная разметка в Гаване
Арка
Тринидад. Лошадка держит домик
Пеликан
Взгляд в будущее
В Сингапурском зоопарке. Леопардовая (бенгальская) кошка.
Вид на Осло из замка Акерхус
  • Отдых
  • Работа

При использовании материалов с сайта, пожалуйста, ставьте ссылку на источник. E-mail для связи: mne@romka.eu.