- •Что в этой книге
- •Настройки против Расширений
- •Как расширить Joomla!
- •Компоненты (Components)
- •Модули (Modules)
- •Плагины (Plug-Ins)
- •Обзор тем
- •Создание пи (Toolbars) и Списков
- •Поддержание стиля и исключение повторений кода используя html функции
- •Доступ к бд и управление записями
- •Безопасность и предпочтительный способ получения переменных запроса
- •Меню управления
- •Управления логикой работы внутри Компонента
- •Конфигурация посредством xml-параметров
- •Упаковка и распространение
- •Наш Проект для примера
- •Приступая к разработке Компонента
- •Структура Компонента Joomla!
- •Запуск Компонента
- •Разделение на иа и ип в Joomla
- •Регистрация Компонента в бд
- •Создание пи
- •Доступные кнопки пи
- •Создание таблицы бд
- •Создание класса Table
- •Создание формы Обзора
- •Обработка данных
- •Создание Списка
- •Редактирование записей
- •Удаление записей
- •Разработка ип
- •Листинг Обзоров
- •Отображение Обзора
- •Генерация дружественных для поисковиков ссылок
- •Создание url сегментов
- •Парсинг url сегментов
- •Добавление комментариев
- •Отображение комментариев
- •Разработка Модуля
- •Регистрация Модуля в бд
- •Создание и настройка базового Модуля
- •Воспользуемся некоторыми помощниками (class Helper)
- •Пробуем различные стили
- •Попробуем смешать
- •Расширяем проект
- •Модель, Вид, Контроллер: Почему?
- •Построение Модели данных
- •Модель Все Обзоры
- •Модель одиночного Обзора
- •Миграция на Виды
- •Переключения посредством Контроллеров (Controllers)
- •Обновление связей и маршрутов
- •Реорганизация кода иа
- •Управление публикацией Обзоров
- •Добавление постраничной навигации
- •Управление Коментариями
- •Дополнительные пи
- •За кулисами: Плагины (Plug-Ins)
- •Запросы к бд
- •Плагин ссылка
- •Плагин справочной информации
- •Поиск Обзоров
- •Параметры
- •Добавление параметров к расширениям
- •Параметры для Модулей
- •Параметры для Плагинов
- •Параметры для Компонентов
- •Упаковываем все вместе
- •Список всех файлов
- •Упаковка Модуля
- •Упаковка Плагина
- •Упаковка Компонента
- •Включение sql-запросов
- •Создание пунктов меню иа
- •Дополнительные сценарии установки
- •Распространение
- •Содержание
Модель одиночного Обзора
В дополнение к Модели всех опубликованных Обзоров создадим Модель для отдельных Обзоров. В папке models, создайте review.php файл с кодом:
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport( 'joomla.application.component.model' );
class ModelReviewsReview extends JModel
{
var $_review = null;
var $_comments = null;
var $_id = null;
function __construct()
{
parent::__construct();
$id = JRequest::getVar('id', 0);
$this->_id = $id;
}
function getReview()
{
if(!$this->_review)
{
$query = "SELECT * FROM #__reviews WHERE
id = '" . $this->_id . "'";
$this->_db->setQuery($query);
$this->_review = $this->_db->loadObject();
if(!$this->_review->published)
{
JError::raiseError( 404, "Invalid ID provided" );
}
}
return $this->_review;
}
function getComments()
{
if(!$this->_comments)
{
$query = "SELECT * FROM #__reviews_comments WHERE
review_id = '" . $this->_id . "'";
$this->_comments = $this->_getList($query, 0, 0);
}
return $this->_comments;
}
}
?>
Как и в предыдущей модели здесь используются те же общие принципы. Мы переопределили конструктор таким образом: сначала вызывается оригинал (исходник), а затем устанавливаем id Обзора для Модуля из запроса [честно говоря я не понял что хотел сказать автор этой фразой: We have overridden the constructor so that we call the original one first, and then set the review id for the module from the request. прим.переводчика]. Кроме того, у нас есть две другие защищенные переменные, в которых хранится информация для Обзора и соответствующих комментариев. Вместо того чтобы загружать список записей, getReview() загружает только одну строку. Обратите внимание, что объект базы данных уже защищенный член класса JModel. Если при выполнении Обзора будет обнаружено, что он не был опубликован, мы получим 404 ошибку. GetComments() работает почти идентично ModelReviewsAll::GetList(), только для таблицы #__reviews_comments
Миграция на Виды
Теперь нам нужно создать некоторый код для отображения информации. Пока что для этого задания нам хорошо служили файлы с расширением .html.php. Однако, архитектура MVC предъявляет довольно жесткие требования: подключается класс HTML вывода и вызывается Вид с помощью которого будут отображаться данные. Благодаря использованию Видов, мы можем использовать эти отображения в любом месте, даже в ИА.
Вместо того, чтобы по разместить весь вывод в один файл, мы создадим отдельную папку для Видов, в которой будут содержаться подпапки для файлов различного назначения. В /components/com_reviews, создайте папку views. На данный момент, наш Компонент имеет функции для отображения одного Обзора и комментария [видимо пропущено: кроме отображения всех Обзоров. прим.переводчика], так что создайте две папки внутри views с названиями all и review. В каждой из этих папок, создайте папки для шаблонов с названием tmpl. Ваша структура каталогов должна выглядеть следующим образом:
Вид All
Каждый Вид может включать в себя несколько шаблонов, но нуждается в объекте Вида для управления этими шаблонами. Чтобы сделать этот объект для всех Видов Обзоров, создайте файл view.html.php внутри
components/com_reviews/views/all с таким кодом:
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport('joomla.application.component.view');
class ReviewViewAll extends JView
{
function display($tpl = null)
{
global $option;
$model = &$this->getModel();
$list = $model->getList();
for($i = 0; $i < count($list); $i++)
{
$row =& $list[$i];
$row->link = JRoute::_('index.php?option=' . $option .
'&id=' . $row->id . '&view=review');
}
$this->assignRef('list', $list);
parent::display($tpl);
}
}
?>
После импорта библиотеки view и объявления ReviewViewAll как расширения JView, мы создаем функцию display(), которая принимает имя шаблона, что мы хотим использовать. Мы получаем Модель назначенную для этого Вида и используем функцию GetList(), чтобы получить наши Обзоры. Прежде чем отображать шаблон, мы проходим через все записи и добавляем правильный SEF URL с помощью JRoute ::_(), для поисковиков. Затем устанавливаем этот список как переменную шаблона и вызываем шаблон. Если имя шаблона не указано, назначается default (по умолчанию). Чтобы создать шаблон по умолчанию, в components/com_reviews/views/all/ создайте default.php с таким кодом:
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); ?>
<table>
<?php foreach($this->list as $l): ?>
<tr><td>
<a href="<?php echo $l->link; ?>"><?php echo $l->name; ?></a>
</td></tr>
<?php endforeach; ?>
</table>
Обратите внимание, что переменная списка добавляется в качестве члена текущего объекта Вида и, следовательно, должны быть доступна через $this
Вид Review
Код для отображения одиночного Обзора похож на код для отображения всех Обзоров. В /com_reviews/views/review создаем view.html.php и добавляем в него следующий код:
<?php
defined( '_JEXEC' ) or die( 'Restricted access' );
jimport('joomla.application.component.view');
class ReviewViewReview extends JView
{
function display($tpl = null)
{
global $option, $mainframe;
$model = &$this->getModel();
$user =& JFactory::getUser();
$review = $model->getReview();
$comments = $model->getComments();
$pathway =& $mainframe->getPathWay();
$backlink = JRoute::_('index.php?option=' .
$option . '&view=all' );
$review->review_date =
JHTML::Date($review->review_date);
if($review->smoking == 1)
{
$review->smoking = "Yes";
}
else
{
$review->smoking = "No";
}
for($i = 0; $i < count($comments); $i++)
{
$row =& $comments[$i];
$row->comment_date =
JHTML::Date($row->comment_date);
}
$pathway->addItem($review->name, '');
$this->assignRef('review', $review);
$this->assignRef('comments', $comments);
$this->assignRef('backlink', $backlink);
$this->assignRef('option', $option);
$this->assignRef('name', $user->name);
parent::display($tpl);
}
}
?>
В дополнение к получению переменных из модели, мы также подключаем объект текущего пользователя и объект $mainframe. Мы используем объект пользователя, чтобы получить имя вошедшего в систему пользователя и присвоить его переменной name. В объекте $review мы форматируем дату и столбец курение (smoking) в привычный для пользователя Вид, мы также форматируем даты для всех комментариев. Из объекта $mainframe, мы получаем путь $pathway и используем имя Обзора для добавления в навигационной цепочке (Breadcrumb). Текст Обзора, строки комментариев, ссылка на список Обзоров, текущее название Компонента и имя вошедшего в систему пользователя - все назначается Виду. Наконец, мы вызываем функцию display() для вывода Обзора
Создание Breadcrumbs (навигационная цепочка - путь по сайту от корня до текущей страницы)
Вы можете изменить путь, который обычно появляется в шаблоне с помощью объекта котрый возвращает $mainframe->getPathWay(). Функция addItem() позволяет добавить навигационную цепочку с названиями пунктов по Вашему выбору. Первым параметром является название пункта, а вторым параметром - URL. Если вы не хотите, чтобы передавалась ссылка, просто передайте пустую строку. Это может быть полезно для иерархических Компонентов, где у вас есть ряд подкатегорий: вы можете создать ссылку на каждую, а затем в конце название текущей записи или категории
Также создана ссылка возврата на главную страницу и назначена Виду. Теперь мы, наконец, выведем выбранный шаблон.
В components/com_reviews/views/review/tmpl создаем default.php с кодом:
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); ?>
<p class="contentheading">
<?php echo $this->review->name; ?>
</p>
<p class="createdate">
<?php echo $this->review->review_date; ?>
</p>
<p>
<?php echo $this->review->quicktake; ?>
</p>
<p>
<strong>Address:</strong> <?php echo $this->review->address; ?>
</p>
<p><strong>Cuisine:</strong>
<?php echo $this->review->cuisine; ?>
</p>
<p><strong>Average dinner price:</strong>
$<?php echo $this->review->avg_dinner_price; ?>
</p>
<p><strong>Credit cards:</strong>
<?php echo $this->review->credit_cards; ?>
</p>
<p><strong>Reservations:</strong>
<?php echo $this->review->reservations; ?>
</p>
<p><strong>Smoking:</strong>
<?php echo $this->review->smoking ?>
</p>
<p>
<?php echo $this->review->review; ?>
</p>
<p><em>Notes:</em>
<?php echo $this->review->notes; ?>
</p>
<a href="<?php echo $this->backlink; ?>"><
return to the reviews
</a>
<?php if(count($this->comments)) : ?>
<br /><br />
<?php foreach($this->comments as $comment): ?>
<p><strong><?php echo $comment->full_name;
?></strong> <em><?php echo $comment->comment_date;
?></em></p>
<p>
<?php echo $comment->comment_text; ?>
</p>
<?php endforeach; ?>
<?php endif; ?>
<br /><br />
<?php echo $this->loadTemplate('form'); ?>
Этот файл в основном состоит из HTML, но мы используем PHP вставки для вывода переменных. Переменные name, review_date, quicktake, address, cuisine, credit_cards, reservations, smoking, review, и notes выводятся обычным echo. Переменная backlink встроена в тег <a>. Перед тем, как отображать комментарии, мы убеждаемся, что у нас есть, по крайней мере, один. Если это так, мы проходим через массив комментариев, отображая full_name, comment_date, и comment_text для каждого комментария. Обратите внимание, что в конце мы вызываем шаблон для вывода формы комментариев. Это позволяет нам сохранить логику Вида: выводить себя отдельно от формы.
Однако мы должны создать этот шаблон. В com_reviews/views/review/tmpl создаем default_form.php и добавляем следующий код:
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); ?>
<form action="index.php" method="post">
<table>
<tr><td><strong>Name:</strong></td> <td><input class="text_area"
type="text" name="full_name" id="full_name" value="<?php echo
$this->name; ?>" /></td></tr>
<tr><td><strong>Comment:</strong></td> <td><textarea
class="text_area" cols="20" rows="4" name="comment_text"
id="comment_text" style="width:500px"></textarea></td></tr>
</table>
<input type="hidden" name="review_id" value="<?php
echo $this->review->id; ?>" />
<input type="hidden" name="task" value="comment" />
<input type="hidden" name="option" value="<?php echo $option; ?>" />
<input type="submit" class="button" id="button" value="Submit" />
</form>