05. Содержание блока



О чём речь: создание блока в котором будет выводится содержание.
Используемый hook: hook_block.


Теперь, нам надо вывести в блок содержание. В этом примере будет рассмотрен прямой запрос в базу данных.

Наша цель — получить список содержания сохранённого в базе в виде документов и созданного неделю назад. Уточним, что мы хотим получить содержание созданное между полуночью и 11:59pm неделю назад. Когда документ создаётся, то время его создания записывается. Таким образом, мы будем использовать поле базы данных, которое хранит время создания документа.

Во-первых, нам нужно вычислить время (в секундах с начала эпохи, см.: http://www.php.net/manual/en/function.time.php) для полуночи неделю назад и для 11:59pm неделю назад. Этот вопрос не зависит от Друпала, от чего это зависит написано здесь: http://php.net.

<?php
/**
* Generate HTML for the onthisdate block
* @param op the operation from the URL
* @param delta offset
* @returns block HTML
*/
function onthisdate_block($op='list', $delta=0) {

 
// listing of blocks, such as on the admin/block page
 
if ($op == "list") {
   
$block[0]["info"] = t('On This Date');
    return
$block;
  } else if (
$op == 'view') {

   
// our block content
    // Get today's date
   
$today = getdate();

   
// calculate midnight one week ago
   
$start_time = mktime(0, 0, 0,
                        
$today['mon'], ($today['mday'] - 7), $today['year']);

   
// we want items that occur only on the day in question, so 
    // calculate 1 day
   
$end_time = $start_time + 86400;
   
// 60 * 60 * 24 = 86400 seconds in a day
   
...
  }
}
?>

Следующим шагом будет использование SQL-запроса, который вернёт то содержание, которое мы хотим получить из базы. Мы должны выбрать содержание из таблицы node — эта таблица является основной в Друпале для хранения документов. Хорошо, давайте получим все типы содержания в нашем запросе: записи в блогах, сообщения форумов и т.д. Для наших целей это подойдёт, но для своего модуля вы возможно захотите указать в SQL-запросе отбор определённых типов содержания (добавив в запрос обращение к колонке type и выбор в ней типа содержания с помощью WHERE).

Отметьте: заключайте названия таблиц в фигурные скобки: {node}. Это нужно для того, чтобы ваш модуль поддерживал префиксы таблиц базы данных. Вы можете найти более подробное описание этого вопроса в этом документе: Table Prefix (and sharing tables across instances).

Итак, используем db_query(), чтобы получить нужные данные в следующем запросе:

<?php
$result
db_query("SELECT nid, title, created FROM {node} WHERE created >= '%s' AND created <= '%s'", $start_time, $end_time);
?>

Drupal uses database helper functions to perform database queries. This means that, for the most part, you can write your database SQL statement and not worry about the backend connections.

Для того, чтобы оформить каждую ссылку на документ как отдельную запись, мы воспользуемся функцией db_fetch_object():

<?php
 
// content variable that will be returned for display  
 
$block_content = '';
  while (
$links = db_fetch_object($result)) {
   
$block_content .=  l($links->title, 'node/'. $links->nid) .'<br />';
  }

 
// check to see if there was any content before setting up
  //  the block
 
if ($block_content == '') {  
   
/* No content from a week ago.  If we return nothing, the block 
     * doesn't show, which is what we want. */
   
return;
  }

 
// set up the block
 
$block['subject'] = 'On This Date';
 
$block['content'] = $block_content;
  return
$block;
}
?>

Notice the actual URL is enclosed in the l() function. l generates <a href="link"> links, adjusting the URL to the installation's URL configuration of either clean URLs: http://(sitename)/node/2 or not http://(sitename)/?q=node/2.

Также, мы возвращаем массив с элементами subject и content. Это те элементы, которые Друпал ожидает получить от функции выводящей содержание в блок. subject — это название блока, а content — это содержание блока. Название и содержание являются для блока обязательными, это логические элементы, т.е. если у блока нет названия — то непонятно что это за блок, а если нет содержания — то зачем показывать то, в чём ничего нет? Если вы не включите определение этих элементов в свой код, то блок не будет показан правильно.

Также следует заметить, что соединение в коде содержания с форматированием — это плохая практика. Если вы пишите модуль и хотите сделать работу с оформлением содержания которое он выводит более лёгкой для других людей (как минимум — не кодеров), вам не следует включать в код форматирование содержания. Лучший путь — включить в код класс CSS и заключить его в тег <div> и оформить представление ссылок в .css-файле. Это позволит в дальнейшем легче работать с оформлением, чем использование в коде тега <br /> для обозначения строки с ссылкой. Сейчас мы это проигнорируем, но имейте это ввиду.

Итак, соедините всё то о чём мы писали выше и у вас будет такой код:

<?php
function onthisdate_block($op='list', $delta=0) {
 
// listing of blocks, such as on the admin/block page
 
if ($op == "list") {
   
$block[0]["info"] = t("On This Date");
    return
$block;
  } else if (
$op == 'view') {
 
// our block content
    // content variable that will be returned for display
   
$block_content = '';

   
// Get today's date
   
$today = getdate();

   
// calculate midnight one week ago
   
$start_time = mktime(0, 0, 0,$today['mon'],
                               (
$today['mday'] - 7), $today['year']);

   
// we want items that occur only on the day in question, so
    //calculate 1 day
   
$end_time = $start_time + 86400;
   
// 60 * 60 * 24 = 86400 seconds in a day

   
$result db_query("SELECT nid, title, created FROM {node} WHERE created >= '%s' AND created <= '%s'", $start_time, $end_time);
    while (
$links = db_fetch_object($result)) {
     
$block_content .= l($links->title, 'node/'.$links->nid) . '<br />';
    }
   
// check to see if there was any content before setting up the block
   
if ($block_content == '') {
     
// no content from a week ago, return nothing.
     
return;
    }
   
// set up the block
   
$block['subject'] = 'On This Date';
   
$block['content'] = $block_content;
    return
$block;
  }
}
?>

Теперь наш модуль стал рабочим — мы можем его установить, включить и проверить.

Смотрите также

Comments

Post new comment

Image CAPTCHA
Copy the characters (respecting upper/lower case) from the image.