Разработка расширений для CMS Joomla

Генерация элементов 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, то эта же строка выведет на экран

    /joomla/templates/beez_20/images/req.png
                

    Обратите внимание, что этот путь мы не задавали, его обнаружил метод 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)
                

    где

    $mail - e-mail;
    $mailto - выводить ли e-mail в виде ссылки <a href="mailto:name@server.com">…</a> или в виде текста;
    $text - текст этой ссылки;
    $email - является ли $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 - список допустимых расширений

    Например, вывод на экран ).

    (рис 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 - исключить пользователей из группы "Зарегистрированные".

    Например, вывод на экран ).

    (рис 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);
                    

    Так как мы передали в функцию ).

    (рис 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,'Риторические вопросы','Вопросы, не требующие ответа')
                

    Зайдите в ).

    (рис 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=editcatcid[]='. $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_myquestionstask=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_myquestionstask=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=editcatcid[]='.$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?
  • Упражнения

    Адаптируйте код из раздела "Практика" для своего варианта (см. список вариантов в дополнительных материалах).

    Страницы:

    Цель лекции: Изучить готовые методы 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, то эта же строка выведет на экран

    /joomla/templates/beez_20/images/req.png
                

    Обратите внимание, что этот путь мы не задавали, его обнаружил метод 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)
                

    где

    $mail - e-mail;
    $mailto - выводить ли e-mail в виде ссылки <a href="mailto:name@server.com">…</a> или в виде текста;
    $text - текст этой ссылки;
    $email - является ли $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 - список допустимых расширений

    Например, вывод на экран ).

    (рис 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 - исключить пользователей из группы "Зарегистрированные".

    Например, вывод на экран ).

    (рис 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);
                    

    Так как мы передали в функцию ).

    (рис 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,'Риторические вопросы','Вопросы, не требующие ответа')
                

    Зайдите в ).

    (рис 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=editcatcid[]='. $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_myquestionstask=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_myquestionstask=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=editcatcid[]='.$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?
  • Упражнения

    Адаптируйте код из раздела "Практика" для своего варианта (см. список вариантов в дополнительных материалах).

    Вернуться к учебному плану