02. Использование Zend_Layout и помощников видов.
В этой статье оптимизируем работу со скриптами видов используя, специально для этого предназначенные, компоненты фрэймворка. В 90% случаев, для каждой страницы, у нас одинаковые шапка и подвал. Чтобы не прописывать в каждом файле require('header.phtml'), require('footer.phtml'), будем использовать компонент Zend_Layout, к тому же это даст нам возможность использовать несколько полезнейших помощников видов по назначению.
Начнем с того, что создадим макет сайта. В папку с видами нужно добавить файл layout.phtml
app/views/layout.phtml
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru" dir="ltr">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>Демо-сайт</title>
</head>
<body>
<div id="header">
<h1>Демо-сайт</h1>
<p><em>Только для примера</em></p>
</div>
<div id="menu">
<a href="<?php echo HOST.BASEURL;?>/">Главная</a>
<a href="/index/about" title="Главная">О сайте</a>
</div><br /><br />
<div id="content">
<!-- вывод скрипта вида -->
<?php echo $this->layout()->content; ?>
</div><br /><br />
<div id="footer">
<p class="textRight"> © 2009 2Developers.Net</p>
</div>
</body>
</html>
Для того, что бы посмотреть как это работает изменим скрипт вида для действия index, оставив в нем только одну строку:
app/views/index/index.phtml
<?php echo $this->message; ?>
и для наглядности примера, добавим еще одно действие в index-контроллер, в результате, чего он будет иметь следующий вид:
app/controllers/IndexController.php
require_once 'Divo/Controller.php';
class IndexController extends Divo_Controller
{
public function divoInit() //__construct()
{ }
public function indexAction()
{
$this->view->assign("message", "Текст главной страницы");
}
public function aboutAction()
{ }
}
еще придется добавить скрипт вида для aboutAction с примерно таким текстом:
app/views/index/about.phtml
<p>Страница с текстом о сайте и может быть контактной формой.</p>
Теперь что бы заработало нужно прописать 2 строки в контроллере:
require_once 'Zend/Layout.php';
Zend_Layout::startMvc();
Но что бы не писать это в каждом действии, следует добавить один метод запускающий layout в базовый контроллер (Divo_Controller) и вызывать его при каждом обращении к скрипту:
lib/Divo/Controller.php
/** Базовый Класс между Zend_Controller_Action и нашими контроллерами действий.
Содержит базовые методы которые необходимо использовать в более чем одном контроллере */
require_once 'Zend/Controller/Action.php';
class Divo_Controller extends Zend_Controller_Action
{
public function init()
{
// Если каталог www расположен не в корне сервера (см. 11 строка www/index.php)
if (BASEURL !== "") {
$this->getRequest()->setBaseUrl(BASEURL.'/');
}
/** Настройки вида */
// Указываем где искать скрипты вида
$this->view->setScriptPath(APPPATH.'/views/');
// Запустить layout
$this->_divoStartLayout();
$this->divoInit();
}
/** Используется вместо конструктора в дочерних контроллерах */
public function divoInit()
{ }
// Метод запускающий layout
private function _divoStartLayout()
{
require_once 'Zend/Layout.php';
$options = array(
'contentKey' => 'content', // Есть еще опции см. в мануале
);
Zend_Layout::startMvc($options);
}
}
теперь можно пробовать.
Помощники видов (View Helpers).
В составе Zend Framework, поставляются несколько незаменимых помощников видов, которые нам пригодятся для полноценной работы с Zend_Layout - это HeadMeta Helper, HeadScript Helper, HeadStyle Helper и HeadTitle Helper.
Что бы увидеть их в работе, изменим наш макет:
app/views/layout.phtml (часть)
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<?php echo $this->headMeta() ?>
<?php echo $this->headTitle('Демо-сайт'); ?>
<link rel="stylesheet" type="text/css" href="/css/style.css" />
<?php echo $this->headStyle(); ?>
<?php echo $this->headScript(); ?>
</head>
HeadMeta Helper
Предназначен для добавления мета-тегов в заголовок html документа, из скриптов вида. Для того что бы добавить на главную мета-тэги keywords и description напишем следующие строки в скрипте вида indexAction:
app/views/index/index.phtml
$this->headMeta()->appendName('keywords', 'демо, тест, ZF, фрэймворк, PHP');
$this->headMeta()->appendName('description', 'Демо-сайт. Разработано с использованием Zend Framework');
$this->headMeta()->appendName('copyright', '© 2009 2Developers.Net');
Теперь вы можете увидеть что в заголовке главной страницы появилась следующая информация для поисковых машин, на том месте где в Layout.phtml (строка 6) мы вызывали HeadMeta-хелпер.
<meta name="keywords" content="демо, тест, ZF, фрэймворк, PHP" />
<meta name="description" content="Демо-сайт. Разработано с использованием Zend Framework" />
<meta name="copyright" content="2Developers.Net 2009" />
Еще существует способ добавлять мета-тэги с информацией для браузера:
пример:
$this->headMeta()->appendHttpEquiv('Refresh', '3; URL=http://zf-demo.2developers.net');
результат:
<meta http-equiv="Refresh" content="3; URL=http://zf-demo.2developers.net" />
HeadScript Helper
Предоставляет два полезнейших метода, незаменимых при работе с Zend_Layout, которые позволяют подключать файлы .js в заголовок страницы, вызывая хелпер из скриптов вида:
пример:
$this->headScript()->appendFile('/js/example.js');
результат:
<script type="text/javascript" src="/js/example.js"></script>
И самое интересное, отображать javaScript-код (написанный в скрипте вида), в заголовке страницы во время выполнения:
<?php $this->headScript()->captureStart() ?>
bkLib.onDomLoaded(
function()
{
nicEditors.allTextAreas({fullPanel : true})
});
<?php $this->headScript()->captureEnd(); ?>
вывод:
<script type="text/javascript">
//<!--
bkLib.onDomLoaded(
function()
{
nicEditors.allTextAreas({fullPanel : true})
});
//-->
</script>
Весь вывод, после вызова метода captureStart() и до вызова captureEnd(), будет подставлен на место, где вызывается данный помощник в Layout.phtml (строка 13).
HeadStyle
Работает, точно по такому же принцпу как и HeadScript-хэлпер, только служит для вывода и подключения каскадных таблиц стилей.
пример:
$this->headStyle()->appendStyle('/css/example.css');результат:
<link rel="stylesheet" type="text/css" href="/css/example.css" />пример (из ZF-мануала):
<?php $this->headStyle()->captureStart() ?>
body {
background-color: <?= $this->bgColor ?>;
}
<?php $this->headStyle()->captureEnd() ?>
HeadTitle Helper
Дает возможность указать заголовок страницы в любое время, для этого в скрипт вида следует добавить:
$this->headTitle('Главная страница');
в том случае, если в Layout был передан заголовок по умолчанию
<?php echo $this->headTitle('Демо-сайт'); ?> // Демо-сайт (по умолчанию)
то хэлпер будет добавлять указанные заголовки в начало:
app/views/index/index.phtml
$this->headTitle('Главная страница ');
результат:
<title>Главная страница Демо-сайт</title>Чтобы части составного заголовка не смешивались, установим разделитель строк для хэлпера HeadTitle методом setSeparator() в базовом контроллере
lib/Divo/Controller.php (часть)
public function init()
{
// Если каталог www расположен не в корне сервера (см. 11 строка www/index.php)
if (BASEURL !== "") {
$this->getRequest()->setBaseUrl(BASEURL.'/');
}
/** Настройки вида */
// Указываем где искать скрипты вида
$this->view->setScriptPath(APPPATH.'/views/');
$this->view->headTitle()->setSeparator(' | ');
// Запустить layout
$this->_divoStartLayout();
$this->divoInit();
}
Это все, что касается компонента Zend_Layout в нашем приложении, а использование других хэлперов вида, в том числе и написание своих, рассмотрим позже в следующих статьях.
Комментарии
Я так понимаю пхп код вырезался вначале? Я вообще то там писал что вот так: ?php echo HOST.BASEURL; не стоит делать.
Мне кажется вырезать теги на сайте про программирование как-то не того. Может их просто заменять на соотвествующие значки?) И предлагаю сделать как на вашем другом сайте программерз (я там уже тоже один гадкий комментарий оставил, простите :))) делать возможность вставки кода и как-то об этом написать как там, по-моему было удобно.
Или эт я напутал и сдуру нескопипастил ваш код? Тест:
Тест провален 10 минусов ))! Спасибо, поправим...
Не говорите о времени добавления комментариев )
С использованием хелперов, хидер получится примерно так. Помоему лайоуты лучше разделить на хидер, футер, контент. Можно будет заменить только отдельную часть.
<?php echo $this->doctype() ?>
<head>
<base href="<?php echo $_SERVER['HTTP_HOST'] ?>" />
<?php
$this->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=utf-8'); //Указываем кодировку
$this->headTitle()->setSeparator(' - '); //Указаваем сеператор для разделения текста в тайтле
$this->headLink()->appendStylesheet('/css/global.css'); //Добавляем CSS
$this->headScript()->prependFile('/js/jquery/jquery.min.js'); //Добавляем JS
?>
<?php echo $this->headTitle($this->translate('My First Project'))) ?>
<?php echo $this->headMeta() ?>
<?php echo $this->headLink() ?>
<?php echo $this->headScript() ?>
</head>