Лекция 3: Генерация элементов HTML (класс JHTML)
Цель лекции: Изучить готовые методы Joomla для генерации и отображения элементов XHTML и поведений JavaScript.
Основной метод класса JHTML
Joomla содержит методы для генерации и отображения элементов XHTML и поведений JavaScript. Эти методы вызываются с помощью
mixed _(string $type)
Несмотря на то, что в прототипе метода JHTML::_() указан всего один параметр, на практике их, как правило, бывает больше. Они интерпретируются так: по первому параметру метод _() определяет, какой метод необходимо вызвать, а остальные параметры передаются в этот метод.
Параметр $type может быть трех видов:
- Название метода самого класса JHTML. Например, $type = 'image' приведет к вызову JHTML::image().
- <имя файла>.<имя метода>. Будет вызван метод поддерживающего класса JHTML<Имя файла>.<имя метода>(). В имени поддерживающего класса первая буква <имени файла> станет заглавной. Например, если $type='select.genericlist', то будет вызван метод JHTMLSelect::genericlist().
- <префикс>.<имя файла>.<имя метода> и будет вызван метод <префикс>.<Имя файла>.<имя метода>().
Методы класса JHTML
Класс JHTML содержит восемь методов для вывода элементов XHTML.
Поле для ввода даты и пиктограмма, по щелчку на которой появляется календарь
string calendar(string $value, string $name, string $id, string $format = '%Y-%m-%d', array $attribs = null)
где:
$value | - значение даты; |
$name | - имя текстового поля; |
$id | - id текстового поля; |
$format | - формат даты; |
$attribs | - дополнительные атрибуты, которые должны быть выведены в теге <input>. |
Для примера выведем текущую дату (рис. 3.1):
echo JHTML::_('calendar', date('Y-m-d',time()), 'created', 'created', '%Y-%m-%d', array('size'=>10,'style'=>"class='inputbox'"));
Рис. 3.1. Поле для ввода даты и пиктограмма для вывода календаря
Строка, содержащая дату в заданном формате и часовом поясе
string date(string $input = 'now', string $format = null, mixed $tz = true, bool $gregorian=false)
где:
$input | - строка в формате, подходящем для функции date(); |
$format | - формат, к которому необходимо привести дату; |
$tz | - одна из временных зон, поддерживаемых PHP (их список можно найти на странице http://www.php.net/manual/ru/timezones.php). Кроме того, $tz может иметь логическое значение: при $tz=true временная зона берется из настроек пользователя, при $tz=false - из настроек сервера; |
$gregorian | - при false для форматирования даты будет использоваться локальный календарь. |
Для примера выведем текущую дату:
echo JHTML::_('date',date('Y-m-d',time()), 'Y-m-d h:m', 'Europe/Moscow', false);
Элемент <iframe></iframe>
string iframe(string $url, string $name, array $attribs = null, string $noFrames = '')
где
$url | - относительный URL, будущее значение атрибута src; |
$name | - название будущего элемента <iframe>; |
$attribs | - ассоциативный массив атрибутов будущего тега <iframe>; |
$noFrames | - содержимое будущего тега: текст, который будет показан, если браузер не поддерживает тег <iframe>. |
Пример:
echo JHTML::_('iframe','index.php', 'myelement', array('width'=>500,'height'=>300), 'Ваш браузер не поддерживает плавающие фреймы');
Элемент <img></img>
string image(string $file, string $alt, mixed $attribs = null, bool $relative = false, bool $path_only = false)
где
$file | - абсолютный или относительный URL изображения; |
$alt | - альтернативный текст; |
$attribs | - ассоциативный массив атрибутов будущего тега (может быть задан сразу в виде строки, например: "width="100%" height="100%""); |
$relative | - перебирать ли варианты пути к файлу; |
$path_only | - возвращать ли только путь к изображению или тег <img> со всеми атрибутами. |
Для методов image(), script() и stylesheet() будет выполнена следующая процедура поиска файла. Если $file начинается с "http", то метод просто вернет $file. В противном случае он производит поиск файла, перебирая возможные варианты его названия в зависимости от браузера пользователя. Например, для значения "/pics/pic.png" и браузера Mozilla 5.0 будут перебираться варианты "/pics/pic.png", "/pics/pic_mozilla.png", "/pics/pic_mozilla_5.png", "/pics/pic_mozilla_5_0.png". При $relative=true перебираются также различные варианты пути к файлу в папке текущего шаблона и папке /media. В противном случае метод будет искать файл JPATH_ROOT/<имя файла> для каждого варианта названия файла.
Например, следующий код
echo JHTML::_('image','req.png','Восклицательный знак', array('width'=>25,'height'=>25), true, false);
выведет
<img src="/joomla/templates/beez_20/images/req.png" alt="Восклицательный знак" width="25" height="25"/>
Если последним параметром указать true, то эта же строка выведет на экран
Обратите внимание, что этот путь мы не задавали, его обнаружил метод image().
Элемент <a></a>
string link(string $url, string $text, array $attribs = null)
где:
$text | - текст ссылки; |
$attribs | - ассоциативный массив атрибутов будущего тега. |
Пример:
echo JHTML::_('link','index.php','На главную страницу', array('title'=>'На главную','id'=>'linktomainpage'));
Элемент <script></script>
mixed script(string $file, bool $framework = false, bool $relative = false, bool $path_only = false, bool $detect_browser = true)
где
$file | - путь к файлу; |
$framework | - загружать ли фреймворк Javascript; |
$path_only | - возвращать путь к файлу или добавить все найденные файлы к текущему документу; |
$detect_browser | - определять ли браузер пользователя для включения файлов Javascript для этого браузера. |
При $path_only=false метод не возвращает никакого значения.
Пример:
echo JHTML::_('script', 'media/system/js/calendar.js', false, false, true, false);
Элемент <link rel="stylesheet" style="text/css"/>
mixed stylesheet(string $file, array $attribs = array(), bool $relative = false, bool $path_only = false, bool $detect_browser = true)
Все параметры аналогичны рассмотренным выше.
Пример:
echo JHTML::_('stylesheet', 'media/system/css/system.css', array("title"=>"Название стиля","media"=>"screen, print"), false, true, false);
Всплывающая подсказка
string tooltip(string $tooltip, mixed $title = '', string $image = 'tooltip.png', string $text = '', string $href = '', string $alt = 'Tooltip', string $class = 'hasTip')
где
$tooltip | - текст подсказки; |
$title | - название подсказки или ассоциативный массив с ключами title, image, text, href, alt и соответствующими значениями; |
$image | - изображение, для которого будет выводиться подсказка (если не задано значение $text); |
$text | - текст, для которого будет выводиться подсказка (если не задано значение $image); |
$href | - URL, на который будет произведен переход по щелчку на изображение или текст; |
$alt | - значение атрибута alt тега <img>; |
$class | - название класса элемента <span>, в который будет заключен тег <img>. |
Изображение с подсказкой:
echo JHTML::tooltip('Текст подсказки', 'Заголовок подсказки', 'tooltip.png', '', 'http://www.mysite.ru');
Текст с подсказкой:
echo JHTML::tooltip('Текст подсказки', 'Заголовок подсказки', '', 'Наведите на этот текст курсор мыши, чтобы увидеть подсказку');
Поддерживающие классы
Рассмотрим некоторые методы поддерживающих классов. Полный список этих методов можно найти в документации, однако на текущий момент она не достаточно полная и содержит ошибки, поэтому для детальной справки по какому-либо методу вы можете обратиться напрямую к исходным кодам в папке /libraries/joomla/html/html.
JHTMLBehavior
Методы этого класса загружают код Javascript в заголовок документа. Методы JHTMLBehavior позволяют вывести календарь, дерево элементов, файловый загрузчик и некоторые другие элементы управления. Рассмотрим один из методов, позволяющий вывести всплывающее модальное окно без перезагрузки страницы:
void modal(string $selector = 'a.modal', array $params = array())
где
$selector | - селектор класса; |
$params | - массив параметров, ключи которого могут быть следующими: ajaxOptions, size, shadow, onOpen, onClose, onUpdate, onResize, onShow, onHide. |
В следующем примере выводятся две ссылки. При нажатии на первую из них появляется всплывающее окно с изображением, на вторую - с веб-страницей.
<?php JHTML::_('behavior.modal'); ?> <a href="/media/system/images/notice-info.png" class="modal" rel="{size: {x: 100, y: 100}, handler:'iframe'}" >Щелкните, чтобы увидеть изображение</a><br/> <a href="http://www.mysite.ru" class="modal" rel="{size: {x: 700, y: 500}, handler:'iframe'}" >Щелкните, чтобы открылось окно с веб-страницей</a>
Первое окно выглядит так, как на рис. 3.2.
увеличить изображение
Рис. 3.2. Модальное окно
JHTMLEmail
Содержит один метод для скрытия адреса электронной почты в целях его защиты от спам-ботов:
string cloak(string $mail, bool $mailto=1, string $text='', bool $email=1)
где
- e-mail; | |
$mailto | - выводить ли e-mail в виде ссылки <a href="mailto:name@server.com">…</a> или в виде текста; |
$text | - текст этой ссылки; |
- является ли $text адресом электронной почты. |
Пример:
echo JHtml::_('email.cloak', 'admin@mysite.ru', 1, 'Написать администратору', 0);
JHTMLForm
Содержит один метод, который возвращает код скрытого поля формы для уменьшения риска CSRF-атак:
string token()
Именем получившегося элемента формы станет сгенерированная случайным образом строка, которая используется для проверки того, что запрос был сделан из конкретных формы и сессии.
Для предотвращения CSRF-атак вставляйте в каждую форму своего компонента строку:
<?php echo JHTML::_('form.token');?>
JHTMLGrid
Методы данного класса используются для вывода в таблице в панели управления таких элементов, как чекбокс, пиктограмма для переключения состояния "опубликовано"/"не опубликовано", для отображения заголовка столбца как ссылки для сортировки по этому столбцу и др.
Таблица должна располагаться внутри формы под названием adminForm, обязательно включающей два скрытых поля: boxchecked со значением по умолчанию 0 и task.
Для создания чекбокса используется метод
mixed id(int $rowNum, int $recId, bool $checkedOut=false, string $name='cid')
где
$rowNum | - номер строки в таблице; |
$recId | - id записи; |
$checkedOut | - отмечен ли элемент; |
$name | - имя элемента формы. |
Метод возвращает html-код чекбокса, если элемент не отмечен, и пустую строку в противном случае.
Для создания пиктограммы, по щелчку на которой можно изменять значение поля published с 0 на 1 и обратно, используется
string published(mixed $value, int $i, string $img1 = 'tick.png', string $img0 = 'publish_x.png', string $prefix='')
где
$value | - объект или только значение поля published; |
$i | - номер строки в таблице; |
$img1 | - изображение при published = 1; |
$img0 | - изображение при published = 0; |
$prefix | - префикс, который будет добавлен к названиям по умолчанию задач publish/unpublish. |
Для примера выведем элементы массива $rows как строки таблицы, добавив для каждой записи ячейки с чекбоксом и значком "опубликовано"/"не опубликовано":
$k = 0; for ($i = 0, $n = count($rows); $i < $n; $i ++) { $row = &$rows[$i]; ?> <tr class="<?="row$k"?>"> <td><?=JHTML::_('grid.id', $i, $row->id)?></td> <td><?=$row->name?></td> <td align="center"><?=JHTML::_('grid.published', $row, $i)?></td> </tr> <?php $k = 1 - $k; }
Пример результата приведен на рис. 3.3.
увеличить изображение
Рис. 3.3. Чекбокс и пиктограмма "опубликовано/не опубликовано"Обратите внимание, что методы класса JHTMLGrid лишь отображают какой-либо элемент, но не добавляют код для его обработки. В приведенном выше примере кнопки "опубликовано"/"не опубликовано" отображаются, но не работают. Чтобы это исправить, необходимо зарегистрировать задачи publish и unpublish (если вы не изменили их названия, задав какой-либо префикс) и написать функцию для их обработки, которая будет вызывать метод JTable::publish().
JHTMLImage
Содержит два метода для поиска изображения в фронтенде и бэкенде соответственно. Каждый из них ищет либо изображение из директории images текущего шаблона сайта/панели управления, либо, если файла с заданным именем там нет, изображение из заданной директории.
string site(string $file, string $folder = '/images/system/', int $altFile = null, string $altFolder = '/images/system/', string $alt = null, array $attribs = null, bool $asTag = true) string administrator(string $file, string $folder = '/images/', int $altFile = null, string $altFolder = '/images/', string $alt = null, array $attribs = null, bool $asTag = true)
где
$file | - имя файла; |
$folder | - путь к файлу. Будет использован, если в директории images текущего шаблона не нашлось файла с заданным именем; |
$altFile | - если не задано, то используются значения $file и $folder, при $altFile = -1 метод возвращает пустую строку, при других значениях используются $altFile и $altFolder; |
$altFolder | - другой путь к файлу; |
$alt | - будущее значение атрибута alt; |
$attribs | - ассоциативный массив атрибутов; |
$asTag | - вернуть весь тег <img> с его содержимым или только путь. |
Пример:
echo JHTML::_('image.site', 'notice-info.png', '/media/system/images/');
JHTMLList
Методы класса JHTMLList используются для создания списков некоторых значений.
Список для выбора одного из существующих в Joomla уровней доступа
string accesslevel(object &$row)
где $row - объект, имеющий поле access.
Пример:
$query = 'SELECT id,access FROM #__content WHERE id = 1'; $db = JFactory::getDBO(); $db->setQuery($query); $article = $db->loadObject(); echo JHTML::_('list.accesslevel', $article);
Результат показан на рис. 3.4.
Рис. 3.4. Список для выбора уровня доступа
Список для выбора изображения
array images(string $name, string $active = NULL, string $javascript = NULL, string $directory = NULL, string $extensions = "bmp|gif|jpg|png")
где
$name | - имя поля; |
$active | - выбранный по умолчанию элемент; |
$javascript | - дополнительный код Javascript, который будет выведен внутри тега <select>; |
$directory | - директория, в которой хранятся изображения. Например: components/com_mycomponent/images. Если значение не задано, будет использоваться директория images; |
$extensions | - список допустимых расширений |
Например, вывод на экран JHTML::_('list.images','imglist') приведет к отображению такого списка (рис. 3.5).
Рис. 3.5. Список для выбора изображения
Список незаблокированных пользователей
string users(string $name, string $active, int $nouser = 0, string $javascript = NULL, string $order = 'name', string $reg = 1)
где
$name | - название элемента <select>; |
$active | - выбранный по умолчанию пользователь; |
$nouser | - добавлять ли пункт, означающий отсутствие пользователя; |
$javascript | - дополнительный код Javascript, который будет выведен внутри тега <select>; |
$order | - имя поля для сортировки списка; |
$reg | - исключить пользователей из группы "Зарегистрированные". |
Например, вывод на экран JHTML::_('list.users','usrlist','42', 1, NULL, 'id', $reg = 1) приведет к отображению такого списка (рис. 3.6).
Рис. 3.6. Список для выбора пользователя
Список категорий
string category(string $name, string $extension, string $selected = NULL, string $javascript = NULL, string $order = null, int $size = 1, bool $sel_cat = 1)
где
$name | - название элемента <select>; |
$extension | - расширение, к которому относятся категории; |
$selected | - выбранное по умолчанию значение; |
$javascript | - дополнительный код Javascript, который будет выведен внутри тега <select>; |
$size | - высота списка (значение атрибута size тега <select>); |
$sel_cat | - при null строки "Выберите категорию" в списке не будет. |
Пример:
echo JHTML::_('list.category', 'catlist', 'com_content', 2, 'onclick="someFunc()"', 'id', 1, 1);
Данный код выведет на экран список, представленный на рис. 3.7.
Рис. 3.7. Список для выбора категории
JHTMLMenu
Класс используется для отображения элементов меню и не представляет интереса для использования в расширениях.
JHTMLSelect
Класс JHTMLSelect используется для генерации кода списков.
Выпадающий список
string genericlist(array $data, string $name, mixed $attribs = null, string $optKey = 'value', string $optText = 'text', mixed $selected = null, mixed $idtag = false, bool $translate = false)
где
$data | - массив данных для отображения. Каждый элемент может быть сгенерирован с помощью метода JHTMLSelect.option() или другим образом; |
$name | - имя элемента HTML; |
$attribs | - дополнительные атрибуты тега <select>. Могут быть заданы как массив атрибутов или массив опций с ключами list.attr, id, list.select и др.; |
$optKey | - из какого поля объекта, представляющего собой элемент массива $data, брать значение элементов <option>. При $optkey = null будут использованы ключи массива; |
$optText | - из какого поля объекта, представляющего собой элемент массива $data, брать текст элементов <option>. Тег <option> формируется так: <option value="$optkey">$optText</option>; |
$selected | - значение выбранного по умолчанию элемента; |
$idtag | - id тега <select>; |
$translate | - пропускать ли текст через функцию JText::_(). |
Пример:
$query = 'SELECT id,title FROM #__content'; $db = JFactory::getDBO(); $db->setQuery($query); $content = $db->loadObjectList(); echo JHTML::_('select.genericlist', $content, 'genlist', 'size='.count($content), 'id', 'title', 2);
Так как мы передали в функцию genericlist() $selected=2, то в сгенерированном списке по умолчанию выделен элемент с id, равным 2 (рис. 3.8).
Рис. 3.8. Список для выбора материала
Объект, представляющий элемент <option> выпадающего списка
object option(string $value, string $text = '', mixed $optKey = 'value', string $optText = 'text', bool $disable = false)
где
$value | - значение элемента <option>; |
$text | - текст элемента; |
$optKey | - если это строка, то имя того поля возвращаемого объекта, в котором будет храниться значение элемента <option>. Если массив, то это параметры. Возможные ключи массива: attr, disable, label, option.attr, option.disable, option.key, option.label, option.text; |
$optText | - имя того поля возвращаемого объекта, в котором будет храниться текст элемента <option>; |
$disable | - добавлять ли к тегу атрибут disable. |
Рассмотрим пример:
$query = 'SELECT id,title FROM #__content'; $db = JFactory::getDBO(); $db->setQuery($query); $content = $db->loadObjectList(); foreach ($content as $c) $data[] = JHTML::_('select.option', $c->id, $c->title, 'my_value', 'my_text'); echo JHTML::_('select.genericlist', $data, 'genlist', 'size='.count($data), 'my_value', 'my_text', 2);
В данном примере для каждого материала сайта с помощью метода JHTMLSelect.option() создается объект, представляющий элемент <option>:
JObject Object ([_errors:protected]=>Array () [my_value]=>1 [my_text]=>Материал #1 [disable]=>)
Таким образом, значения $optKey и $optText, переданные в функцию option(), стали названиями полей получившегося объекта, а значения $c->id и $c->title - значениями этих полей. Теперь в функцию JHTMLSelect.genericlist() необходимо передать те же названия полей, что и в option(). Если не передать их, то функция genericlist() будет по умолчанию искать в объектах массива $data поля $value и $text, которых там нет.
Результат работы данного примера будет выглядеть так же, как и результат предыдущего.
Список целых чисел
string integerlist(int $start, int $end, int $inc, string $name, mixed $attribs = null, mixed $selected = null, string $format = '')
где
$start | - первое число последовательности; |
$end | - последнее число последовательности; |
$inc | - шаг; |
$name | - имя тега; |
$attribs | - массив атрибутов тега; |
$selected | - значение выбранного по умолчанию элемента; |
$format | - формат вывода числа для функции printf(). |
Пример:
echo JHTML::_('select.integerlist', 1, 10, 1, 'intlist', 'size=10', 3, '%02d');
Этот код выведет список, представленный на рис. 3.9.
Рис. 3.9. Список для выбора числа
Группа переключателей
string radiolist(array $data, string $name, mixed $attribs = null, mixed $optKey = 'value', string $optText = 'text', string $selected = null, bool $idtag = false, bool $translate = false)
где
$data | - массив объектов; |
$name | - имя, общее для всех переключателей; |
$attribs | - дополнительные атрибуты тега <input> (могут быть заданы сразу в виде строки); |
$optKey | - из какого поля объекта, представляющего собой элемент массива $data, брать значения элементов <input>; |
$optText | - из какого поля объекта, представляющего собой элемент массива $data, брать текст элементов <input>; |
$selected | - значение выбранного по умолчанию элемента; |
$idtag | - префикс id сгенерированных тегов. Для каждого тега <input> id станет равным $idtag<key>, где <key> - значение поля под названием $optKey в соответствующем объекте из массива $data. Если $idtag не задан, то вместо него будет использовано значение $name. В Joomla 1.7 в этой функции имеется ошибка: если объекты массива $data содержат поле с названием id, то к каждому элементу <input> добавляется второй id со значением, взятым из этого поля; |
$translate | - пропускать ли текст через функцию JText::_(). |
Пример:
$query = 'SELECT id,title FROM #__content'; $db = JFactory::getDBO(); $db->setQuery($query); $content = $db->loadObjectList(); echo JHTML::_('select.radiolist', $content, 'radlist', 'class="inputbox"', 'id', 'title', 2, 'radlist', false);
Результат показан на рис. 3.10.
Рис. 3.10. Группа переключателей
Практика
Обработка категорий
В единственном вопросе, который хранится в нашей базе, в поле id_cat стоит значение 1. Оно должно означать id категории. Добавим таблицу и код для работы с категориями.
Создание таблицы для категорий
Выполните следующий SQL-запрос, чтобы создать таблицу для хранения категорий:
CREATE TABLE `jos_myquestions_categories` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, `name` VARCHAR(255) NOT NULL, `desc` TEXT NOT NULL DEFAULT '' )
Добавьте записи в эту таблицу:
INSERT INTO `jos_myquestions_categories` VALUES (NULL,'Без категории',''), (NULL,'Риторические вопросы','Вопросы, не требующие ответа')
Зайдите в phpMyAdmin и убедитесь, что таблица jos_myquestions_categories содержит две записи (рис. 3.11).
Рис. 3.11. Таблица базы данных, хранящая данные о категорияхТаким образом, сейчас все вопросы, для которых в поле id_cat стоит значение 1, относятся к категории "Без категории".
Создание класса таблицы
Создайте файл /administrator/components/com_myquestions/tables/category.php:
<?php defined('_JEXEC') or die('Restricted access'); class TableCategory extends JTable { var $id = null; var $name = null; var $desc = null; function __construct($db) { parent::__construct('#__myquestions_categories', 'id', $db); } } ?>
Вывод списка категорий
Добавьте в файл admin.myquestions.php функцию showCategories():
function showCategories($option) { $db = JFactory::getDbo(); $query = "SELECT * FROM #__myquestions_categories"; $db->setQuery($query); $rows = $db->loadObjectList(); if ($db->getErrorNum()) { echo $db->stderr(); return false; } HTML_questions::showCategories($option, $rows); }
Эта функция аналогична функции showQuestions(), рассмотренной ранее.
В файл admin.myquestions.html.php в класс HTML_questions добавьте еще одну функцию:
function showCategories($option, &$rows) { ?> <form action="index.php" method="post" name="adminForm"> <table class="adminlist"> <thead> <tr> <th width="20"> <input type="checkbox" name="toggle" value="" onclick="checkAll(<?php echo count($rows);?>);"/> </th> <th class="title" width="30%"><?php echo JText::_('COM_MYQUESTIONS_CATEGORY_NAME');?></th> <th><?php echo JText::_('COM_MYQUESTIONS_CATEGORY_DESC');?></th> </tr> </thead> <?php jimport('joomla.filter.output'); $k = 0; for ($i = 0, $n = count($rows); $i < $n; $i ++) { $row = &$rows[$i]; $checked = JHTML::_('grid.id', $i, $row->id); $link = JFilterOutput::ampReplace('index.php?option=' .$option . '&task=editcat&cid[]='. $row->id); ?> <tr class="<?php echo "row$k";?>"> <td><?=$checked?></td> <td><?='<a href="'.$link.'">'.$row->name.'</a>'?></td> <td><?=$row->desc?></td> </tr> <?php $k = 1 - $k; } ?> </table> <input type="hidden" name="option" value="<?php echo $option;?>"/> <input type="hidden" name="task" value=""/> <input type= "hidden" name="boxchecked" value="0"/> </form> <?php }
Данная функция также аналогична одноименной функции для отображения списка вопросов.
Добавьте в переключатель switch в файле admin.myquestions.php обработку новой задачи:
case 'showcat': showCategories($option); break;
Добавьте в файл /administrator/language/ru-RU/ru-RU.com_myquestions.ini код:
COM_MYQUESTIONS_CATEGORY_NAME="Название категории" COM_MYQUESTIONS_CATEGORY_DESC="Описание категории"
Перейдя по ссылке http://localhost/joomla/administrator/index.php?option=com_myquestions&task=showcat, вы уже можете увидеть список категорий.
Однако пока над списком будет отображаться старая панель инструментов, которую мы создали для списка вопросов. Поэтому необходимо также создать новые панели инструментов для работы с категориями. Откройте файл toolbar.myquestions.php и добавьте в переключатель switch следующий код:
case 'showcat': TOOLBAR_myquestions_categories::_DEFAULT(); break;
Как видите, мы добавили обработку задачи showcat - отображение списка категорий. Соответственно, вызывается функция _DEFAULT() класса TOOLBAR_myquestions_categories. Напишем код этого класса. Добавьте в файл toolbar.myquestions.html.php код:
class TOOLBAR_myquestions_categories { function _DEFAULT() { JToolBarHelper::title(JText::_('COM_MYQUESTIONS_TOOLBAR_TITLE_CATEGORIES'), 'generic.png'); JToolBarHelper::addNew('addcat'); JToolBarHelper::editList('editcat'); JToolBarHelper::deleteList (JText::_('COM_MYQUESTIONS_TOOLBAR_REMOVE_CATEGORIES_CONFIRMATION'), 'removecat'); } }
Таким образом, панель инструментов для списка категорий будет содержать три кнопки: "Создать", "Изменить" и "Удалить".
Добавьте в файл /administrator/language/ru-RU/ru-RU.com_myquestions.ini код:
COM_MYQUESTIONS_TOOLBAR_TITLE_CATEGORIES="Управление категориями вопросов" COM_MYQUESTIONS_TOOLBAR_REMOVE_CATEGORIES_CONFIRMATION="Вы действительно хотите удалить эти категории?"
Теперь по ссылке http://localhost/joomla/administrator/index.php?option=com_myquestions&task=showcat видим список категорий (рис. 3.12).
увеличить изображение
Рис. 3.12. Список категорий в бэкенде
Создание, редактирование и удаление категорий
При нажатии на кнопки "Создать" или "Изменить", расположенные над списком категорий, должна отображаться другая панель инструментов. Для этого добавьте в класс TOOLBAR_myquestions_categories функцию _NEW():
class TOOLBAR_myquestions_categories { function _NEW() { JToolBarHelper::title(JText::_('COM_MYQUESTIONS_TOOLBAR_TITLE_CATEGORIES'), 'generic.png'); JToolBarHelper::save('savecat'); JToolBarHelper::apply('applycat'); JToolBarHelper::cancel('showcat'); } function _DEFAULT() { JToolBarHelper::title(JText::_('COM_MYQUESTIONS_TOOLBAR_TITLE_CATEGORIES'), 'generic.png'); JToolBarHelper::addNew('addcat'); JToolBarHelper::editList('editcat'); JToolBarHelper::deleteList(JText::_('COM_MYQUESTIONS_TOOLBAR_REMOVE_CONFIRMATION'), 'removecat'); } }
Запишем в файле toolbar.myquestions.php, что при обработке задач addcat и editcat должна отображаться панель инструментов _NEW. Измените код этого файла так:
<?php defined('_JEXEC') or die('Restricted access'); require_once(JApplicationHelper::getPath('toolbar_html')); switch($task) { case 'reply': TOOLBAR_myquestions::_REPLY(); break; default: TOOLBAR_myquestions::_DEFAULT(); break; case 'showcat': TOOLBAR_myquestions_categories::_DEFAULT(); break; case 'addcat': case 'editcat': TOOLBAR_myquestions_categories::_NEW(); break; } ?>
Теперь добавим обработку всех перечисленных в файле toolbar.myquestions.html.php задач. Откройте файл admin.myquestions.php и добавьте в переключатель switch код:
case 'addcat': case 'editcat': editCategory($option); break; case 'savecat': case 'applycat': saveCategory($option, $task); break; case 'removecat': removeCategories($option); break;
Добавьте перечисленные функции в файл admin.myquestions.php:
function editCategory($option) { $row = JTable::getInstance('Category','Table'); $cid = JRequest::getVar('cid', array(0), '', 'array'); $id = $cid[0]; $row->load($id); HTML_questions::editCategory($row, $option); } function saveCategory($option, $task) { $row = JTable::getInstance('category', 'Table'); if (!$row->bind(JRequest::get('post'))) { echo "<script> alert('".$row->getError()."'); window.history.go(-1); </script>\n"; exit(); } $row->desc = JRequest::getVar('desc', '', 'post', 'string', JREQUEST_ALLOWRAW); if (!$row->store()) { echo "<script> alert('".$row->getError()."'); window.history.go(-1); </script>\n"; exit(); } global $app; if ($task == 'savecat') $app->redirect('index.php?option='.$option.'&task=showcat', JText::_('COM_MYQUESTIONS_CATEGORY_SAVED')); else if ($task == 'applycat') $app- >redirect('index.php?option='.$option.'&task=editcat&cid[]='.$row- >id, JText::_('COM_MYQUESTIONS_CATEGORY_SAVED')); } function removeCategories($option) { global $app; $cid = JRequest::getVar('cid', array(), '', 'array'); $db = JFactory::getDbo(); if(count($cid)) { $cids = implode(',', $cid); $query = "DELETE FROM #__myquestions_categories WHERE id IN ($cids)"; $db->setQuery($query); if (!$db->query()) { echo "<script> alert('".$db->getErrorMsg()."'); window.history.go(-1); </script>\n"; } } $app->redirect('index.php?option=' . $option . '&task=showcat', JText::_('COM_MYQUESTIONS_CATEGORY_DELETED')); }
Листинг .
Добавьте в файл admin.myquestions.html.php в класс HTML_questions метод editCategory() для отображения формы редактирования категории:
function editCategory ($row, $option) { $editor = JFactory::getEditor(); ?> <form action = "index.php" method="post" name="adminForm" id="adminForm"> <fieldset class="adminform"> <table class="admintable" width=100%> <tr> <td width="100" class="key"> <?php echo JText::_('COM_MYQUESTIONS_CATEGORY_NAME');?>: </td> <td> <input class="text_area" type="text" name="name" id="name" size="50" maxlength="255" value="<?php echo $row->name;?>"/> </td> </tr> <tr> <td width="100" class="key"> <?php echo JText::_('COM_MYQUESTIONS_CATEGORY_DESC');?>: </td> <td> <?php echo $editor->display('desc', $row->desc,'100%', '250', '40', '10');?> </td> </tr> </table> </fieldset> <input type="hidden" name="id" value="<?php echo $row->id;?>"/> <input type="hidden" name="option" value="<?php echo $option;?>"/> <input type="hidden" name="task" value=""/> </form> <?php }
Наконец, добавьте в файл /administrator/language/ru-RU/ru-RU.com_myquestions.ini код:
COM_MYQUESTIONS_CATEGORY_SAVED="Категория сохранена" COM_MYQUESTIONS_CATEGORY_DELETED="Категории успешно удалены"
Убедитесь, что все кнопки обеих панелей инструментов работают корректно.
Присвоение вопросу какой-либо категории
Добавим в форму ответа на вопрос выпадающий список для выбора категории.
Откройте файл admin.myquestions.php и измените код функции replyToQuestion() следующим образом:
function replyToQuestion($option) { $row = JTable::getInstance('Question','Table'); $cid = JRequest::getVar('cid', array(0), '', 'array'); $id = $cid[0]; $row->load($id); $db = JFactory::getDBO(); $query = 'SELECT name AS text, id AS value FROM #__myquestions_categories'; $db->setQuery($query); $categories = $db->loadObjectList(); $list_cat = JHTML::_('select.genericlist', $categories, 'id_cat', ' class="inputbox" ', 'value', 'text', $row->id_cat); HTML_questions::replyToQuestion($row, $option, $list_cat); }
В файле admin.myquestions.html.php измените прототип функции HTML_questions::replyToQuestion() так:
function replyToQuestion ($row, $option, $list_cat)
Наконец, в коде этой функции измените фрагмент, в котором раньше выводилось текстовое поле с id категории, так:
<tr> <td width="100" class="key"> <?php echo JText::_('COM_MYQUESTIONS_CATEGORY');?>: </td> <td> <?=$list_cat?> </td> </tr>
Перейдите к странице ответа на вопрос и убедитесь, что отображается выпадающий список для выбора категории (рис. 3.13).
Рис. 3.13. Выбор категории вопроса в бэкенде
Ключевые термины
JHTML | - класс для вывода элементов XHTML. |
JHTMLBehavior | - поддерживающий класс, который позволяет вывести календарь, дерево элементов, файловый загрузчик и некоторые другие элементы управления. |
JHTMLEmail | - поддерживающий класс, содержащий метод для скрытия адреса электронной почты в целях его защиты от спам-ботов. |
JHTMLForm | - поддерживающий класс, содержащий метод, который возвращает код скрытого поля формы для уменьшения риска CSRF-атак. |
JHTMLGrid | - поддерживающий класс, позволяющий вывести в таблице в панели управления такие элементы, как чекбокс, пиктограмма для переключения состояния "опубликовано"/"не опубликовано", отобразить заголовок столбца как ссылки для сортировки по этому столбцу и др. |
JHTMLImage | - поддерживающий класс, содержащий методы для поиска изображения в фронтенде и бэкенде. |
JHTMLList | - поддерживающий класс для создания списков некоторых конкретных значений. |
JHTMLSelect | - поддерживающий класс для генерации кода списков. |
Основной метод класса JHTML | - метод JHTML::_(), который вызывает метод, определяющийся его первым параметром, и передает ему свои остальные параметры. |
Поддерживающие классы | - классы для вывода элементов XHTML и поведений Javascript. |
Краткие итоги
Joomla содержит методы для генерации и отображения элементов XHTML и поведений JavaScript. Эти методы вызываются с помощью метода JHTML::_(). По первому параметру данный метод определяет, какой метод необходимо вызвать, а остальные параметры передаются в этот метод. Таким образом могут быть вызваны как методы самого класса JHTML, так и методы поддерживающих классов.
Методы класса JHTML позволяют вывести следующие элементы: календарь, форматированную дату, элементы <iframe>, <img>, <a>, <script>, <link> и всплывающую подсказку.
Поддерживающие классы используются следующим образом:
- JHTMLBehavior позволяет вывести календарь, дерево элементов, файловый загрузчик и некоторые другие элементы управления.
- JHTMLEmail содержит метод для скрытия адреса электронной почты в целях его защиты от спам-ботов.
- JHTMLForm содержит метод, который возвращает код скрытого поля формы для уменьшения риска CSRF-атак.
- JHTMLGrid позволяет вывести в таблице в панели управления такие элементы, как чекбокс, пиктограмма для переключения состояния "опубликовано"/"не опубликовано", отобразить заголовок столбца как ссылки для сортировки по этому столбцу и др.
- JHTMLImage содержит два метода для поиска изображения в фронтенде и бэкенде соответственно.
- JHTMLList используется для создания списков некоторых конкретных значений.
- JHTMLSelect используется для генерации кода списков.
Вопросы
- Каким образом работает метод JHTML::_()?
- Какие элементы могут быть отображены с помощью класса JHTML?
- Для чего используется класс JHTMLBehavior?
- Для чего используется класс JHTMLEmail?
- Для чего используется класс JHTMLForm?
- Код каких элементов генерируют методы класса JHTMLGrid?
- В чем преимущество использования класса JHTMLImage?
- Для чего используются классы JHTMLList и JHTMLSelect?