Разработка модуля на примере создания блока

Прислано: i_byte

вс, 28/02/2010 - 17:53

Судя по форуму, количество людей работающих с Drupal не так уж и мало, а количество и объем русскоязычных статей о разработке модулей под Drupal оставляют желать лучшего. Поэтому решил один раз сесть, разобраться, написать русскоязычную документацию по написанию шаблона для модуля типа блок, дабы каждый раз не вгрызаться в дебри англоязычного текста.
Приведенный ниже материал является вольной интерпретацией документации с drupal.org. Попытался не обойти стороной и локализацию модуля. Подразумевается, что используется переведенный на русский "движок" Drupal. В конце теории будет приведен код простого модуля для отображения самых активных пользователей сайта на основе подсчета количества оставленных комментариев.
Любые конструктивные замечания и советы приветствуются.
Итак

Разработка модулей для Drupal 6.x на примере блока

В каталоге modules создаем каталог латиницей по имени модуля (без пробелов)
Создаем файл латиницей имямодуля.info
В файле необходимо заполнить как минимум следующие данные

; $Id$
name = Module name
description = A description of what your module does.
core = 6.x

где
; $Id$ - тег для подстановки системой контроля версий (CVS) номера версии, даты создания и автора данного файла; используется при публикации модуля на drupal.org и контроля версий

name - отображаемое имя модуля
description - коротко, в одну строку описание модуля; используется для указания администратору сайта назначения модуля; максимум 255 символов
core - определяет под какую версию написан данный модуль; не дает подключить модуль к несоответствующей версии сайта

Также допустимы следующие необязательные параметры

dependencies - описание модулей от которых зависит данный модуль; синтаксис следующей

dependencies[] = taxonomy
dependencies[] = comment

package - если данный параметр присутствует, то на странице admin/build/modules модуль будет сгруппирован с другими модулями такой же категорией. Если данный параметр не указан, то модуль будет в категории 'Other' (Другое). Данный параметр помогает поместить модуль в категорию с теми пакетами, с которыми предполагает использование, что облегчает администрирование модулей. Если не уверены, не заполняйте данный параметр.
Пример категорий:

  • Audio
  • Bot
  • CCK
  • Chat
  • E-Commerce
  • Event
  • Feed Parser
  • Organic groups
  • Station
  • Video
  • Views
  • Voting (if it uses/requires VotingAPI)

Создаем файл латиницей имямодуля.module
Не забываем, что весь код внутри должен быть заключен между тегами <?php ?>
Специфические функции имеют предопределенные имена и пишутся после знака подчеркивания и имени модуля. Предположим, модуль называется firstmodule . Тогда функции будут называться firstmodule_имяфункции.
Первая функция - необязательная.
hook_help() - функция для предоставления дополнительной информации о модуле.
Заготовка для функции будет следующая.

<?php/**
* Отображение помощи и информации о модуле
* @param path адрес по которому будет отображаться помощь
* @param arg массив содержащий текущий адрес как если бы он был возвращен из arg() функции
* @return возвращаем помощь как текст
*/
function firstmodule_help($path$arg) {
  
$output '';  //определение переменной в которой будем возвращать текст
  
switch ($path) {
    case 
"admin/help#firstmodule":
      
$output '<p>'.  t("Здесь текст помощи") .'</p>';
      break;
  }
  return 
$output;
// function firstmodule_help
?>

Примечание: хотя в приведенном примере и дальше я буду использовать кириллицу в выводимом тексте, делать это в реальном коде я не советую. Используйте латиницу и английский язык. Почему? Ответ содержится в части, рассказывающей о локализации.

Следующая функция определяет какие права доступа (разрешения) доступны для модуля и обозначается hook_perm()
Данная функция не определят сами права доступа и не предоставляет их - только описывает доступные права. Как только hook_perm () определена, администратору становятся доступны разрешения для тех или иных ролей на странице Управление/Управление пользователями/Разрешения
Пример данной функции

<?php/**
* Доступные разрешения для модуля
* @return array массив доступных разрешений для модуля
*/
function firstmodule_perm() {
  return array(
'access firstmodule content');
// function firstmodule_perm()
?>

Чтобы избежать пересечение прав между различными модулями, название разрешений должны быть уникальны. Считается хорошим тоном включать в название имя вашего модуля, например

return array('access firstmodule', 'create firstmodule', 'administer firstmodule');

В данном примере 'administer firstmodule' описывает разрешения для настройки модуля.

Определение кода обработчика для блока

<?php/**
* Шаблон для hook_block
* @param строка $op одна из "list", "view", "save" и "configure"
* @param целое $delta код для идентификации блока
* @param массив $edit только для "save" операции
**/
function firstmodule_block($op 'list'$delta 0$edit = array()) {  

  
// код модуля

// function firstmodule_block
?>

где
$op - hook_block() вызывается для выполнения 4 различных операций: "list", "view", "save", и "configure". Через переменную $op сообщается какую из операций запрашивают.

$delta - в модуле можно использовать больше одного блока для операции. Именно для определения того или иного блока и существует переменная $delta которая обычно является целым числом. Примером мультиблочного модуля может служить модуль ядра user который имеет блок для авторизации, блок отображения новых пользователей и блок отображения пользователей on-line.
Модуль управления блоками вызовет функцию hook_block() с $op='list' когда будет строить список блоков на странице управления блоками.

<?php/**
* Шаблон для hook_block
* @param строка $op одна из "list", "view", "save" и "configure"
* @param целое $delta код для идентификации блока
* @param массив $edit только для "save" операции
**/
function firstmodule_block($op 'list'$delta 0$edit = array()) {
if (
$op == "list") {
    
// Для построения списка модулей с именем данного модуля, для admin/block страницы
    
$block = array();
    
$block[0]["info"] = t('Название модуля');
    return 
$block;
  } 
// function firstmodule_block
?>

где
$block - переменная, используемая, чтобы хранить необходимые данные, прежде, чем возвратить их.
$block[0] - $block - переменная типа массив, и каждый элемент в массиве представляет один блок. "0" индекс массива - то самое значение $delta, которое можно будет использоваться в других операциях (если бы были определены множественные блоки, то использовались бы элементы массива $block [0], $block [1], $block [2], и т.д.; также необходимо было бы проверять значение $delta, которое передают в функцию для других операций).
$block[0]["info"] - массив ассоциативный и использует именованные элементы для определения тех или иных значений. В данном случае определяется то, как будет отображаться блок на странице администрирования.

Теперь пришла пора наполнить блок содержанием

Для этого вводим в код функции hook_block следующие строки

<?php
 
else if ($op == 'view') {

    
// Код для генерации наполнения блока
  
$query "SELECT nid, title, created FROM {node} WHERE created >= '%d' AND created <= '%d'";

  
$query_result =  db_query($query$start_time$end_time);
   
}
?>

В данном примере используется доступ к базе drupal. Для получения результата применяется функция $query_result с передачей параметров, которые подставляются вместо "тегов" %d в SQL-запросе, запрос является текстовой строкой заключенной в переменную $query. Данный запрос является "безопасным" запросом. Имя таблицы, в данном случае node, необходимо заключать в фигурные скобки {}. Заключение в скобки требуется для поддержки механизма префикса таблиц. Префиксы используются для мультисайтинга или повышения безопасности сайта, так как произвольный префикс изменяет имя таблицы и затрудняет использование SQL-инъекций. Также желательно использовать функцию db_rewrite_sql() которая позволяет определить имеет ли пользователь права на выполнение данного запроса?
Функция db_rewrite_sql() определяется как (оригинал смотрите в database.inc)

<?php
function db_rewrite_sql($query$primary_table 'n'$primary_field 'nid',  $args = array())
?>

где
$query - параметр для перезаписи
$primary_table - Имя или псевдоним таблицы которая имеет первичное поле для данного запроса
Типичные имена таблиц: {blocks}, {comments}, {forum}, {node}, {menu}, {term_data} or {vocabulary}. Однако, более распространено использование псевдонимов: b, c, f, n, m, t или v.
$primary_field - Имя первичного поля
$args - Массив дополнительных аргументов
возвращается - Оригинальный запрос с JOIN и WHERE с подставленными параметрами; nid перезаписан если необходимо

Таким образом, стратегия использования SQL-запроса к базе drupal следующая:

$query = db_rewrite_sql($query);
$query_result =  db_query($query);

Для получения данных из результата запроса обычно используют db_fetch_object(), т.е.

$data = db_fetch_object($query_result);

Пример кода ниже:

<?php// переменная для возвращения данных которые будут отображены на экране    
  
$block_content '';  
  while (
$links db_fetch_object($query_result)) { 
    
$block_content .=  l($links->title'node/'$links->nid) .'<br />';
  }
?>

Здесь функция l() создает ссылку правильного Drupal-пути, например с использованием чистых ссылок http://(sitename)/node/2 или с подстановкой переменной http://(sitename)/?q=node/2 (путь любой страницы будет "node/#", где # идентификационный номер страницы).

В завершение необходимо вернуть данные Drupal'у для вывода их на экран. Выполнить это можно соответственно нижеприведенному шаблону:

<?php  // проверяем, есть ли наполнение данными
  
if ($block_content == '') {   
     
// данные отсутствуют
     
$block['subject'] = 'Название блока';
     
$block['content'] = 'Извините, данные отсутствуют';
     return 
$block;
  }

  
// заполняем данными
  
$block = array();
  
$block['subject'] = 'Название блока';  
  
$block['content'] = $block_content;
  return 
$block;?>

Можно использовать следующий код, чтобы не выводить блок, если данных для наполнения нету:

<?phpif ($block_content == '') {   
    
/* Данных нет.  Блок отображаться не будет     */
    
return;
  }
?>

При выводе данных необходимо помнить о том, что применение функции t() дает возможности перевода на другие языки, а применение классов CSS дает возможности управлять отображением содержимого блока при его эксплуатации, что особенно актуально если блок будет передаваться другим людям. Еще лучше - использовать "themeable" вывод данных.

Далее все стандартно: записываем папку с модулем в директорию modules/, затем включаем модуль на странице admin/build/modules Управление/Конструкция сайта/Модули. Если нет синтаксических ошибок, то после сохранения конфигурации вновь отобразится страница сайта. Конфигурация видимости модуля осуществляется на странице /admin/build/block Управление/Конструкция сайта/Блоки. В случае ошибки удаляем директорию с модулем.

Создание кода для управления модулем

Используя Drupal Forms API создадим функцию для определения системных параметров модуля.

<?phpfunction firstmodule_admin() {
  
$form = array();

  
$form['firstmodule_variablename'] = array(
    
'#type' => 'textfield',
    
'#title' => t('Название параметра'),
    
'#default_value' => variable_get('firstmodule_variablename'3),
    
'#size' => 2,
    
'#maxlength' => 2,
    
'#description' => t("Описание параметра."),
    
'#required' => TRUE,
  );

  return 
system_settings_form($form);
}
?>

Вообще то, имя после префикса firstmodule_ может быть произвольным, однако всегда нужно помнить про удобочитаемость кода.
В коде:
$form - массив элементов формы согласно Drupal Forms API. Каждый элемент массива соответствует элементу формы. В данном примере это текстовое поле на два символа с максимальным количеством символов - 2, а также названием и кратким описанием.
system_settings_form() - функция на основе данных формы создаст требуемые кнопки и т.д., позаботится о сохранении значений введенных параметров. Drupal сохранит значение параметра в базе, однако, параметры должны иметь уникальное имя, для этого и существует префикс firstmodule_ .
variable_get() - получает значение параметра, число 3 в данном случае является значением по умолчанию если параметр не был установлен ранее.
Важно чтобы название элемента в определении формы и название параметра при вызове variable_get() совпадали, так как Drupal использует название элемента в массиве $form при сохранении данных формы.
'#default_value' - если значение не установлено или нажать кнопку "Установки по умолчанию", то будет принято данное значение.
'#required' => TRUE - говорит о том, что данный параметр является обязательным для заполнения.
Функция t() отвечает за корректное отображение текста какой бы язык интерфейса не был установлен для сайта.
Теперь можно модифицировать функцию hook_block() так, чтобы использовать значение параметра при запросе к базе:

<?php
$limitnum 
variable_get("firstmodule_count"3);
$query "SELECT nid, title, created FROM {node} WHERE created >= %d AND created <= %d";
$query_result db_query_range($query$start_time$end_time0$limitnum);
?>

В данном примере db_query_range() подставляет значения для LIMIT в запрос, в данном случае от 0 до $limitnum. Таким образом будут выбраны не все данные, а только в нужном диапазоне, например первые 3 в данном случае.
После определения функции для параметров необходимо определить функцию для добавления соответствующих пунктов меню в интерфейс Drupal. Эту задачу выполняет hook_menu(). Пример:

<?php
function firstmodule_menu() {

  
$items = array();

  
$items['admin/settings/firstmodule'] = array(
    
'title' => 'Заголовок пункта меню',
    
'description' => 'Описание пункта настроек',
    
'page callback' => 'drupal_get_form',
    
'page arguments' => array('firstmodule_admin'),
    
'access arguments' => array('access administration pages'),
    
'type' => MENU_NORMAL_ITEM,
   );

  return 
$items;
}
?>

Важно чтобы справа от 'page arguments' было указано имя функции, в которой описана форма для параметров модуля. В нашем случае это firstmodule_admin.
Для того, чтобы пункт меню появился в интерфейсе необходимо очистить кеш данных. Для этого переходим на страницу admin/settings/performance Управление/Настройка сайта/Производительность и нажимаем кнопку "Очистить кеш данных".
Основные необходимые функции определены, все вроде бы работает хорошо. Однако, как себя поведет модуль в случае, если вместо ожидаемого числового значения в вышеприведенном примере будет введен символ? К тому же проверка вводимых значений является хорошей практикой программирования. Для отслеживания вводимых данных можно использовать функцию с суффиксом _validate. В нашем случае функция будет выглядеть следующим образом:

<?php
function firstmodule_admin_validate($form, &$form_state) {
  
$variablename $form_state['values']['firstmodule_variablename'];
  if (!
is_numeric($variablename)) {
    
form_set_error('firstmodule_variablename't('Вы должны ввести целое число.'));
  }
  else if (
$variablename <= 0) {
    
form_set_error('firstmodule_variablename't('Значение должно быть положительным.'));
  }
}
?>

Теперь код обладает всеми чертами полноценного модуля, однако, все же чего-то не хватает. А именно, что очень актуально для не англоязычных проектов, поддержки различных языков.

Поддержка локализации

Основное правило: Drupal полагает, что модули и темы написаны на английском
. Для написания моделей и тем, предназначенных для других языков, используется механизм локализации.
Пожалуй, самый простой способ - это заключать выводимые данные в функцию t(). Если перейти на страницу admin/build/translate Управления/Конструкция сайта/Перевод интерфейса и ввести в строке поиска часть текста, заключенного в коде модуля в функцию t(), то строка будет найдена и появится возможность задать вручную перевод для требуемого языка. Данный метод прост, но возлагает весь перевод на администратора сайта.
Также можно использовать подстановки, например:

<?php
return t('@username, welcome to my website', array('@username' => $account->name));
?>

В приведенном примере @username будет заменено на значение переменной $account->name. Для подстановок можно использовать три спецсимвола: @, % и !
В случае @ вывод будет использовать check_plain() перед выводом.

Рассмотрим способ поставки локализации вместе с самим модулем. Для этого можно использовать модуль для создания шаблона трансляции на основе англоязычного модуля. Загрузить сей чудесный модуль можно по адресу http://drupal.org/project/potx
После установки модуля переходим на страницу admin/build/translate/extract Управление/Конструкция сайта/Перевод интерфейса (вкладка "Извлечь")
Раскрываем список модулей и выбираем свой модуль (что означает, что на тестовый Drupal необходимо установить модуль с английским языком). Выбираем способ извлечения: независимый от языка шаблон или ориентированный на конкретный язык. Если был предварительно произведен перевод средствами самого Drupal, то можно выгрузить в шаблон переведенный текст. После нажатия "Извлечь" получаем шаблон с расширением pot.
Для создания файлов переводов po можно использовать специальный редактор Poedit, скачать который можно по адресу http://www.poedit.net/download.php
Запускаем Poedit и выбираем Файл/Создать каталог из POT-файла, выбираем pot файл. В появившемся окне заполняем необходимые поля. Затем указываем как будет называться файл локализации, например ru.po
Перевод осуществляется путем выбора строки в верхней части программы и введения переведенного текста в нижней части.
В директории модуля создаем директорию с именем translations и записываем туда po-файл. Теперь когда модуль будет активироваться на странице управления моделями то при совпадении языка интерфейса и po-файла будет произведен импорт перевода.

Ниже, как и обещал, практический пример: модуль для отображения в блоке энного (настраивается) количества самых активных посетителей исходя из количества комментариев. Заранее приношу извинения за английский текст, встречающийся в коде - с английским у меня не очень...
Модуль назван actcomm. Первый код для файла actcomm.info

; $Id$
name = Active commentators
description = Top active commentators
core = 6.x

Затем код для actcomm.module

<?php

//функция помощи
function actcomm_help($path$arg) {
  
$output '';  //отпределяем переменную для возврата из функции
  
switch ($path) {
    case 
"admin/help#actcomm":
      
$output '<p>'.  t("Top active commentators order by count comments desc") .'</p>';
    break;
  }
  return 
$output;
// function actcomm_help

//функция определяет какие разрешения будут достурны ролям
function firstmodule_perm() {
  return array(
'access actcomm content');
// actcomm_perm()

//функция вывода блока
function actcomm_block($op='list'$delta=0) {

    switch (
$op) {
      case 
'list':
        
// Что будет отображаться на странице управления блоками admin/block 
        
$block = array();
        
$block[0]["info"] = t('Top active commentators');
        return 
$block;
      break; 
      case 
'view':

        
// Создание данных блока

        // переменная для контента
        
$block_content '';
        
//переменная actcomm_topcount будет отвечать за количество отображаемых позиций, по умолчанию 3
    
$limitnum variable_get("actcomm_topcount"3);
        
//поскольку комментарии хранятся в отдельной таблице вместе с именами авторов, то запрос простой
        //получаем имя и количество комментариев
    
$query "SELECT name, count(*) as ccom FROM {comments} group by name order by ccom desc";
        
//определяем доступность запроса пользователю
        
$query db_rewrite_sql($query"comments");
        
//подставляем границы для LIMIT и получаем результат
    
$query_result db_query_range($query0$limitnum);
        
$block_content.= "<table border=0 width=80%>";
        while (
$row db_fetch_object($query_result)) {
              
$block_content.= "<tr><td width=50%>".$row->name."</td><td>".$row->ccom."</td></tr>";
        }
        
$block_content.= "</table>";
        
// проверяем наличие данных
        
if ($block_content == '') {   
               
// контента нет - выводим сообщение
               
$block['subject'] = t('Top active commentators');
               
$block['content'] = t('Comments not found');
               return 
$block;
        }
        
//или можем не выводить блок вовсе
        /*if ($block_content == '') {   
               // контента нет - блок не выводится
               return;
        } */
        // заполняем данными
        
$block['subject'] = t('Top active commentators');
        
$block['content'] = $block_content;
        return 
$block;
      break;
      }
}  
// end actcomm_block

//определяем форму для управления параметрами модуля
function actcomm_admin() {
  
$form = array();

  
$form['actcomm_topcount'] = array(
    
'#type' => 'textfield',
    
'#title' => t('Amount of top'),
    
'#default_value' => variable_get('actcomm_topcount'3),
    
'#size' => 2,
    
'#maxlength' => 2,
    
'#description' => t("Amount top of views commentators."),
    
'#required' => TRUE,
  );

  return 
system_settings_form($form);
}

//встраиваем меню в интерфейс Drupal
function actcomm_menu() {

  
$items = array();
  
//важно чтобы справа от 'page arguments' было имя функции actcomm_admin
  
$items['admin/settings/actcomm'] = array(
    
'title' => 'Top commentators module settings',
    
'description' => 'Description of your Top commentators settings page',
    
'page callback' => 'drupal_get_form',
    
'page arguments' => array('actcomm_admin'),
    
'access arguments' => array('access administration pages'),
    
'type' => MENU_NORMAL_ITEM,
   );

  return 
$items;
}

//проверяем введенные данные 
function actcomm_admin_validate($form, &$form_state) {
  
$topcount $form_state['values']['actcomm_topcount'];
  if (!
is_numeric($topcount)) {
    
form_set_error('actcomm_topcountp't('You must enter an integer for the maximum number of top commentators.'));
  }
  else if (
$topcount <= 0) {
    
form_set_error('actcomm_topcount't('Maximum number of top commentators must be positive.'));
  }
}

?>

Вот, собственно, пока и все.

Комментарии


Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Применить"
Опубликовано glu2006 в вс, 28/02/2010 - 20:41.

Дополню с позволения автора, код который строит html лучше вынести в отдельную theme функцию, вдруг меня не устроит тот вывод, который предлагаете Вы, для построения таблиц существует функция theme_table (используйте готовое).

для определения theme функции своего модуля пишем следующее:

<?php
function mymodule_theme() {
 return array(
   
'mymodule_function' => array(
     
'arguments' => array('form' => NULL),
     
'file' => 'mymodule.admin.inc',
   ),
   
'profile_info' => array('arguments' => array('uid' => 0)),
  );
}

function 
theme_mymodule_function($form) {
 
// Какой-то код
  
return $output
}

function 
theme_profile_info() {
  
//аналогично
}
?>


Опубликовано VladSavitsky в вс, 28/02/2010 - 21:21.

Да уж - основательная статья. Спасибо.


Опубликовано i_byte в вс, 28/02/2010 - 21:36.

"glu2006" написал(а):

код который строит html лучше вынести в отдельную theme функцию

Спасибо!
Да, писать модуль для использования сторонними относительно разработчика людьми, конечно лучше так, как Вы привели.


Опубликовано Eugeny в пн, 01/03/2010 - 01:11.

Спасибо за статью! Очень полезно.


Опубликовано Sinkora в сб, 15/05/2010 - 15:42.

ТС, конечно, молодец, что не поленился написать.

Я посмотрел бегло и заметил, например, такой фрагмент:

$block_content.= "<table border=0 width=80%>";

Это, честно говоря, жесть, в нашем веке прописывать такие html атрибуты как border и width :), да еще и значения их не брать в кавычки...

Насчет создания блоков. Я бы еще добавил актуальность их кеширования с помощью cache_set, cache_get, что нужно делать почти всегда.

Судя по количеству комментов, могу сделать вывод, что статья неплохая, но, к сожалению, не популярная на этом сайте. Причины этого:

1. Большая часть людей пользуется вьюсами, сниппетами и php-фильтром в админке сайта, и не понимает, что это плохой подход.
2. Знающие люди создают блоки в своих модулях примерно так, как описано в этом топике, и для них эта статья ничего нового не несет.


Опубликовано glu2006 в сб, 15/05/2010 - 20:38.

Sinkora написал(а):

1. Большая часть людей пользуется вьюсами, сниппетами и php-фильтром в админке сайта, и не понимает, что это плохой подход.

И чем же плох подход использования вьюсов, сниппетов?


Опубликовано Sinkora в сб, 15/05/2010 - 23:47.

"glu2006" написал(а):

И чем же плох подход использования вьюсов, сниппетов?

Вы и сами знаете все плюсы и минусы.


Опубликовано glu2006 в пн, 17/05/2010 - 08:59.

И все же? :)
Я к примеру всегда пользуюсь вьюсами, сниппетами реже, но все зависит от ситуации и самое главное никогда не считал это плохим подходом. Поэтому и спросил у Вас чем это плохо с Вашей точки зрения.


Опубликовано Sinkora в пн, 17/05/2010 - 09:30.

"glu2006" написал(а):

Поэтому и спросил у Вас чем это плохо с Вашей точки зрения.

Если брать сниппеты, то они используют PHP-фильтр, так? А он требует использование функции eval, которую не рекомендуют часто использовать сами разработчики Zend Engine (eval() is evil). Т.е. имеем накладные расходы ресурсов. Также код сниппетов хранится в БД, что вызывает лишние запросы, когда нужно проанализировать код. А в третьих, скрипты удобнее отлаживать в файлах, а не в админке. Может я еще не все причины перечислил... (сказывается ночь без сна...)


Опубликовано glu2006 в вт, 18/05/2010 - 04:52.

Sinkora написал(а):

Если брать сниппеты, то они используют PHP-фильтр, так? А он требует использование функции eval, которую не рекомендуют часто использовать сами разработчики Zend Engine (eval() is evil). Т.е. имеем накладные расходы ресурсов. Также код сниппетов хранится в БД, что вызывает лишние запросы, когда нужно проанализировать код. А в третьих, скрипты удобнее отлаживать в файлах, а не в админке. Может я еще не все причины перечислил... (сказывается ночь без сна...)

Ну если касаться сниппетов, то я к примеру ограничиваюсь (опять же все зависит от задач) вызовом в блоке единственной функции к примеру print theme('что-то', параметры) а саму функцию описываю в своем модуле проекта, поэтому править что-то в админке у меня нет необходимости, с моей точки зрения минус сниппета в блоке - это заказчик, вот ему надо объяснять что в этом вот блоке ничего трогать не надо.
Конечно идеологически наверное правильнее писать свой hook_block на каждый чих, но очень часто возникает необходимость и в самих сниппетах к примеру:
Вам нужен блок который будет в зависимости от роли пользователя показывать то или иное содержание т.е.: аноним - счетчик liveinternet, зарегистрированный - счетчик mail.ru, модератор - счетчик rambler.ru Вы лично будете писать модуль, напишете в блоке <?php global $user и т.д... , или создадите три блока с разными счетчиками с правами показа по ролям??>


Опубликовано Sinkora в вт, 18/05/2010 - 07:25.

"glu2006" написал(а):

Вам нужен блок который будет в зависимости от роли пользователя показывать то или иное содержание т.е.: аноним - счетчик liveinternet, зарегистрированный - счетчик mail.ru, модератор - счетчик rambler.ru Вы лично будете писать модуль, напишете в блоке <?php global $user и т.д... , или создадите три блока с разными счетчиками с правами показа по ролям??>

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

Но в принципе, по-моему, самый оптимальный способ - это создать свой модуль my_module_block, где через один hook_block реализовывать все блоки сайта.

Хотя если все делать идеологически правильно, то на это уходит больше времени. Тут, как мне кажется, главное найти компромисс: если работа не стоит лишних усилий - найти более быстрое решение. А если труд окупается - стремиться к идеалу...


Опубликовано krock в вт, 07/09/2010 - 01:08.

Хороший пример, спасибо!
Но такое ощущение, что немного сбита система наименований. Например, складывается впечатление, что actcomm_admin() - это тоже какой-то хук. А на самом деле?


Опубликовано aksernar в пн, 03/01/2011 - 11:27.

блин у меня после подключения отключается отображение модуля Administration menu ! что за хрень? да и блок не отображается в странице блоков?!


Новое на сайте