СОдержимое блока
Существует два типа модулей: модуль-блок и модуль-нод. Модуль-блок отображает чаще (но не всегда) небольшое количество информации. Отображение производится в левой или правой части страницы. Модуль-нод генерирует содержимое страницы полностью (примеры: дневник, форум, страница книги).
Создадим содержимое блока для начала, затем рассмотрим создание содержимого нода (т.е. содержимое всей страницы). Модуль может генерировать содержимое как блока, так и всей страницы (пример: модуль дневника). Хук для модуля-блока называется block; напишем нашу следующую функцию:
<?php
/**
* СОздаёт HTML-содержимое для блока onthisdate
* param op Операция для url
* param delta Смещение
* returns Html-содержимое блока
*/
function onthisdate_block($op='list', $delta=0) {
} // end function onthisdate_block
?>
Функция block принимает два параметра: "операция" и "смещение" (дельта). Пока нас интересует только параметр "операция". Особо стоит позаботиться об анализе ситуации, в которой наш блок отображается в списке на странице блоков. Во всех других ситуациях будем отображать содержимое блока.
Когда наш модуль будет отображаться на странице списка блоков, значение параметра $op будет равным 'list'.
<?php
/**
* СОздаёт HTML-содержимое для блока onthisdate
* param op Операция для url
* param delta Смещение
* returns Html-содержимое блока
*/
function onthisdate_block($op='list', $delta=0) {
// Вывод списка блоков (как на странице "администрировать/блоки")
if ($op == "list") {
$block[0]["info"] = t('On This Date');
return $block;
} else {
// Содержимое нашего блока
}
} // end onthisdate_block
?>
Генерация содержимого блока
Теперь нам нужно сгенерировать содержимое блока для модуля 'onthisdate'. Здесь же продемонстрируем основной принцип работы с базой данных.
Наша цель - получить список материалов (содержащихся в виде нодов в базе данных), созданных неделю назад. Более конкретно, нам нужны материалы, созданные между полуночью и 23:59 дня неделю назад. Время создания нода содержится в базе данных. Мы будем использовать это поле для поиска нужных нам материалов.
Сперва вычислим время (в секундах, считая с начала эпохи unix. Смотри http://www.php.net/manual/en/function.time.php для справки о формате времени) с полуночи до 23:59 неделю назад. Эта часть кода не имеет отношения к drupal. См. веб сайт php (
php.net) для дополнительной справки.
<?php
/**
* СОздаёт HTML-содержимое для блока onthisdate
* param op Операция для url
* param delta Смещение
* returns Html-содержимое блока
*/
function onthisdate_block($op='list', $delta=0) {
// Вывод списка блоков (как на странице "администрировать/блоки")
if ($op == "list") {
$block[0]["info"] = t('On This Date');
return $block;
} else {
// Содержимое блока
// Получаем текущую дату
$today = getdate();
// Вычисляем полночь дня неделю назад
$start_time = mktime(0, 0, 0,
$today['mon'], ($today['mday'] - 7), $today['year']);
// Нас интересуют материалы, созданные в рамках одного дня
// вычисляем один день в секундах
$end_time = $start_time + 86400;
// 60 * 60 * 24 = 86400 секунд в дне
...
}
}
?>
Следующий шаг - SQL запрос, с помощью которого получим желаемое содержимое из базы данных. Мы будем производить выборку из таблицы нодов; она является основной таблицей для хранения содержимого сайта на drupal. Мы получим все типы содержимого нашим запросом: записи в дневниках, сообщения форума и т.д. Для обучающего примера это вполне подходит. Для реальных модулей вам нужно будет формировать SQL запрос для выборки определённых типов содержимого (путём добавления столбца 'type' и проверки его значения в части WHERE).
Замечание: имя таблицы заключается в фигурные скобки: {node}. Это необходимо для поддержки префиксов в именах таблиц. Вы можете найти дополнительную информацию, прочитав страницу префиксы таблиц в руководстве drupal.
<?php
$query = "SELECT nid, title, created FROM " .
"{node} WHERE created >= '" . $start_time .
"' AND created <= '". $end_time . "'";
?>
Drupal использует механизм, упрощающий работу с базой данных, при запросах к б.д. Это значит, вы можете выполнять SQL запросы в большинстве случаев, незаботясь о соединении с базой данных.
Мы будем использовать функцию db_query() для извлечения записей (другими словами - строк таблицы), удовлетворяющих критериям нашего запроса; для просмотра содержимого каждой из полученных записей будем использовать функцию db_fetch_object():
<?php
// Получаем ссылки на материалы
$queryResult = db_query($query);
// Переменная content будет возвращена функцией для дальнейшего отображения
$block_content = '''';
while ($links = db_fetch_object($queryResult)) {
$block_content .= '<a href="' . url('node/' . $links->nid) . '">' .
$links->title . '</a><br />';
}
// Проверяем, есть ли содержимое перед заполнением
// блока
if ($block_content == '''') {
/* Нет материалов, созданных неделю назад. Если не возвращаем никакого значения,
* ничего не будет отображено, что нам и нужно. */
return;
}
// Заполнение блока
$block['subject'] = 'On This Date';
$block['content'] = $block_content;
return $block;
}
?>
Замечание: реальные url адреса должны обрабатываться функцией l(). l возвращает <a href="link"> ссылку в соответствии с настройками сайта: в чистой форме (clean URLS) или в обычной форме http://(sitename)/?q=node/2.
Мы возвращаем массив, содержащий два элемента: 'subject' (тема) и 'content' (содержимое). Это как раз то, что ожидает drupal от функции генерации содержимого блока. Если любой из двух элементов не будет задан, блок будет отображён неверно.
Также мы предостерегаем вас от плохой практики: объединения содержимого с разметкой. Если вы пишете модуль не только для себя, вы, возможно, захотите предоставить простой способ разметки содержимого в том числе и для не программистов. Простой способ сделать это - включить атрибут класса в вашу ссылку или заключить html код в тег <div> с указанием css класса, предназначенного для модуля. Также необязательно включать <br /> в конце ссылки. Пока можете не обращать на это внимания, но имейте ввиду этот момент, если будете писать модули для общего использования.
Объединяя всё выше сказанное, наша функция выглядит так:
<?php
function onthisdate_block($op='list', $delta=0) {
// Вывод списка блоков (как на странице "администрировать/блоки")
if ($op == "list") {
$block[0]["info"] = t('On This Date');
return $block;
} else {
// Содержимое блока
// Получаем текущую дату
$today = getdate();
// Вычисляем полночь дня неделю назад
$start_time = mktime(0, 0, 0,
$today['mon'], ($today['mday'] - 7), $today['year']);
// Нас интересуют материалы, созданные в рамках одного дня
// вычисляем один день в секундах
$end_time = $start_time + 86400;
// 60 * 60 * 24 = 86400 секунд в дне
$query = "SELECT nid, title, created FROM " .
"{node} WHERE created >= '" . $start_time .
"' AND created <= '". $end_time . "'";
// Получаем ссылки на материалы
$queryResult = db_query($query);
// Переменная content будет возвращена функцией для дальнейшего отображения
$block_content = '''';
while ($links = db_fetch_object($queryResult)) {
$block_content .= '<a href="' . url('node/' . $links->nid) . '">' .
$links->title . '</a><br />';
}
// Проверяем, есть ли содержимое перед заполнением
// блока
if ($block_content == '''') {
/* Нет материалов, созданных неделю назад. Если не возвращаем никакого значения,
* ничего не будет отображено, что нам и нужно. */
return;
}
// Заполнение блока
$block['subject'] = 'On This Date';
$block['content'] = $block_content;
return $block;
}
}
?>
Установка, включение и тестирование модуля
Теперь вы можете установить модуль и он будет работать. Сделайте это и посмотрите, что в нём можно улучшить.
Для установки модуля скопируйте файл onthisdate.module в директорию modules установленной копии drupal. Файл модуля должен находиться в директории modules или любой её поддиректории и должен иметь расширение .module.
ВОйдите на сайт с правами администратора и перейдите на страницу администрирования модулей. Там будет список модулей по алфавиту. В меню администрировать >> модули (или по адресу http://.../admin/modules или
http://.../?q=admin/modules), пользуясь прокруткой, найдите модуль onthisdate. Там же увидите его описание.
Включите модуль, установив флажок, и сохраните настройки.
Так как наш модуль - модуль-блок, его нужно включить также и в разделе "блоки" меню администрирования. и указать размещение блока на странице.
Модули-ноды могут требовать или не требовать дальнейшей настройки в зависимости от модуля. Модуль может иметь настройки, управляющие его функциональностью и/или отображением. Настройки мы обсудим позже. ПОка же перейдите на страницу администрировать >> блоки и включите модуль 'On This Date' с помощью флажка "включён", также укажите размещение блока (справа или слева), если используете тему оформления, ограничивающую размещение блока. Затем сохраните настройки блоков.
Перейдите на другую страницу. Некоторые темы отображают блок после того, как страница формирует содержимое. В таком случае вы не увидите работы блока, пока не перейдёте на другую страницу.
Если на сайте есть материалы, созданные неделю назад, модуль отобразит ссылки на эти материалы. Если материалов нет, создайте их. Это можно сделать, создав запись в дневнике, тему форума или страницу книги и в поле "опубликовано" указав дату на неделю назад от текущей.
Если материалов, наоборот, было много, вы увидите много ссылок.
Комментарии
А где же обещанное "затем рассмотрим создание содержимого нода (т.е. содержимое всей страницы)" ?
Согласен с мишкой. Хотелось бы увидеть, как создать нод.
Со времени создания топика сменилась версия движка и в значительной мере API - руководство надо переписывать заново.
--
Axel,
Darcs-репозиторий разработок для Drupal
Долго мучался пытаясь завести этот пример на Drupal 4.7.3 получил только
Parse error: parse error, unexpected $end in D:\nas01\www\html\drupal\modules\onthisdate.module on line 54
Здравствуйте. Пробовала этот модуль, но почемуто не работает: страница admin/modules белая, как чистый лист. Проверяла и синтаксис и пунктуацию, ничего не увидела. Подскажите, пожалуйста, где искать ошибку.
Еще созрел вопрос. Объясните, пожалуйста, какая в PHP разница между одинарной кавычкой и двойной, а то было немало ошибок. Какую в каком случае ставить.
Двойная кавычка интерпретирует внутри переменные и спецсимволы (\n,\t и т.д.), то есть
$test = "123";
print("$test");
выведет 123, а
$test = "123";
print('$test');
выведет $test
===============
бросьте пример, возмите за основу работающий модуль с нужной функциональностью и издевайтесь над ним