Использование представлений
Представления представляют пользовательский интерфейс вашего приложения. Представления часто являются файлами HTML с встроенным PHP-кодом, выполняющим задачи, связанные исключительно с представлением данных. Представления выполняют задачу предоставления данных веб-браузеру или другому инструменту, используемому для запросов к вашему приложению.
Phalcon\Mvc\View и Phalcon\Mvc\View\Simple отвечают за управление слоем представлений вашего приложения MVC.
Интеграция представлений с контроллерами
Phalcon автоматически передает выполнение компоненту представления, как только определенный контроллер завершает свой цикл. Компонент представления будет искать в папке views папку с тем же именем, что и последний выполненный контроллер, а затем файл с именем последнего выполненного действия. Например, если запрос отправлен на URL http://127.0.0.1/blog/posts/show/301, Phalcon проанализирует URL следующим образом:
| Адрес сервера | 127.0.0.1 |
| Директория Phalcon | blog |
| Контроллер | posts |
| Действие | show |
| Параметр | 301 |
Диспетчер будет искать «PostsController» и его действие «showAction». Простой файл контроллера для этого примера:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction($postId)
{
// Pass the $postId parameter to the view
$this->view->postId = $postId;
}
}
Метод setVar() позволяет нам создавать переменные представления по требованию, чтобы они могли использоваться в шаблоне представления. Приведенный выше пример демонстрирует, как передать параметр $postId соответствующему шаблону представления.
Иерархическое отображение
Phalcon\Mvc\View поддерживает иерархию файлов и является компонентом по умолчанию для отображения представлений в Phalcon. Эта иерархия позволяет использовать общие точки макета (часто используемые представления), а также папки контроллеров с именами, определяющими соответствующие шаблоны представлений.
Этот компонент по умолчанию использует сам PHP в качестве движка шаблонов, поэтому представления должны иметь расширение .phtml. Если папка представлений — app/views, то компонент представления автоматически найдет эти 3 файла представления.
| Имя | Файл | Описание |
|---|---|---|
| Представление действия | app/views/posts/show.phtml | Это представление, связанное с действием. Оно будет отображаться только при выполнении действия «show». |
| Макет контроллера | app/views/layouts/posts.phtml | Это представление, связанное с контроллером. Оно отображается для каждого действия, выполненного в контроллере «posts». Весь код, реализованный в макете, будет повторно использован для всех действий в этом контроллере. |
| Основной макет | app/views/index.phtml | Это основное действие; оно будет отображаться для каждого контроллера или действия, выполненного в приложении. |
Вы не обязаны реализовывать все упомянутые выше файлы. Phalcon\Mvc\View просто перейдет к следующему уровню представления в иерархии файлов. Если все три файла представления реализованы, они будут обработаны следующим образом:
<!-- app/views/posts/show.phtml --> <h3>This is show view!</h3> <p>I have received the parameter <?php echo $postId; ?></p>
<!-- app/views/layouts/posts.phtml --> <h2>This is the "posts" controller layout!</h2> <?php echo $this->getContent(); ?>
<!-- app/views/index.phtml -->
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>This is main layout!</h1>
<?php echo $this->getContent(); ?>
</body>
</html>
Обратите внимание на строки, где был вызван метод $this->getContent(). Этот метод указывает Phalcon\Mvc\View, где вставить содержимое предыдущего выполненного представления в иерархии. Для приведенного выше примера выходными данными будут:
Сгенерированный HTML в результате запроса будет:
<!-- app/views/index.phtml -->
<html>
<head>
<title>Example</title>
</head>
<body>
<h1>This is main layout!</h1>
<!-- app/views/layouts/posts.phtml -->
<h2>This is the "posts" controller layout!</h2>
<!-- app/views/posts/show.phtml -->
<h3>This is show view!</h3>
<p>I have received the parameter 101</p>
</body>
</html>
Использование шаблонов
Шаблоны — это представления, которые могут использоваться для совместного использования кода представления. Они действуют как макеты контроллеров, поэтому их необходимо размещать в папке layouts.
Шаблоны могут быть отображены до макета (используя $this->view->setTemplateBefore()) или после макета (используя this->view->setTemplateAfter()). В следующем примере шаблон (layouts/common.phtml) отображается после основного макета (layouts/posts.phtml):
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function initialize()
{
$this->view->setTemplateAfter("common");
}
public function lastAction()
{
$this->flash->notice(
"These are the latest posts"
);
}
}
<!-- app/views/index.phtml -->
<!DOCTYPE html>
<html>
<head>
<title>Blog's title</title>
</head>
<body>
<?php echo $this->getContent(); ?>
</body>
</html>
<!-- app/views/layouts/common.phtml -->
<ul class="menu">
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/contact">Contact us</a></li>
</ul>
<div class="content"><?php echo $this->getContent(); ?></div>
<!-- app/views/layouts/posts.phtml --> <h1>Blog Title</h1> <?php echo $this->getContent(); ?>
<!-- app/views/posts/last.phtml -->
<article>
<h2>This is a title</h2>
<p>This is the post content</p>
</article>
<article>
<h2>This is another title</h2>
<p>This is another post content</p>
</article>
Конечный результат будет следующим:
<!-- app/views/index.phtml -->
<!DOCTYPE html>
<html>
<head>
<title>Blog's title</title>
</head>
<body>
<!-- app/views/layouts/common.phtml -->
<ul class="menu">
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/contact">Contact us</a></li>
</ul>
<div class="content">
<!-- app/views/layouts/posts.phtml -->
<h1>Blog Title</h1>
<!-- app/views/posts/last.phtml -->
<article>
<h2>This is a title</h2>
<p>This is the post content</p>
</article>
<article>
<h2>This is another title</h2>
<p>This is another post content</p>
</article>
</div>
</body>
</html>
Если бы мы использовали $this->view->setTemplateBefore("common"), это был бы конечный результат:
<!-- app/views/index.phtml -->
<!DOCTYPE html>
<html>
<head>
<title>Blog's title</title>
</head>
<body>
<!-- app/views/layouts/posts.phtml -->
<h1>Blog Title</h1>
<!-- app/views/layouts/common.phtml -->
<ul class="menu">
<li><a href="/">Home</a></li>
<li><a href="/articles">Articles</a></li>
<li><a href="/contact">Contact us</a></li>
</ul>
<div class="content">
<!-- app/views/posts/last.phtml -->
<article>
<h2>This is a title</h2>
<p>This is the post content</p>
</article>
<article>
<h2>This is another title</h2>
<p>This is another post content</p>
</article>
</div>
</body>
</html>
Управление уровнями отображения
Как показано выше, Phalcon\Mvc\View поддерживает иерархию представлений. Вам может потребоваться контролировать уровень отображения, производимого компонентом представления. Метод Phalcon\Mvc\View::setRenderLevel() предлагает эту функциональность.
Этот метод может быть вызван из контроллера или из верхнего уровня представления для вмешательства в процесс отображения.
use Phalcon\Mvc\View;
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function findAction()
{
// This is an Ajax response so it doesn't generate any kind of view
$this->view->setRenderLevel(
View::LEVEL_NO_RENDER
);
// ...
}
public function showAction($postId)
{
// Shows only the view related to the action
$this->view->setRenderLevel(
View::LEVEL_ACTION_VIEW
);
}
}
Доступные уровни отображения:
| Постоянная класса | Описание | Порядок |
|---|---|---|
| LEVEL_NO_RENDER | Указывает на отказ от генерации какого-либо представления. | |
| LEVEL_ACTION_VIEW | Генерирует представление для представления, связанного с действием. | 1 |
| LEVEL_BEFORE_TEMPLATE | Генерирует шаблоны представлений до макета контроллера. | 2 |
| LEVEL_LAYOUT | Генерирует представление для макета контроллера. | 3 |
| LEVEL_AFTER_TEMPLATE | Генерирует представление для шаблонов после макета контроллера. | 4 |
| LEVEL_MAIN_LAYOUT | Генерирует представление для основного макета. Файл views/index.phtml | 5 |
Отключение уровней отображения
Вы можете временно или постоянно отключить уровни отображения. Уровень может быть постоянно отключен, если он вообще не используется во всем приложении:
use Phalcon\Mvc\View;
$di->set(
"view",
function () {
$view = new View();
// Disable several levels
$view->disableLevel(
[
View::LEVEL_LAYOUT => true,
View::LEVEL_MAIN_LAYOUT => true,
]
);
return $view;
},
true
);
Или временно отключить его в какой-то части приложения:
use Phalcon\Mvc\View;
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function findAction()
{
$this->view->disableLevel(
View::LEVEL_MAIN_LAYOUT
);
}
}
Выбор представлений
Как упоминалось выше, когда Phalcon\Mvc\View управляется Phalcon\Mvc\Application, отображается представление, связанное с последним выполненным контроллером и действием. Вы можете переопределить это, используя метод Phalcon\Mvc\View::pick().
use Phalcon\Mvc\Controller;
class ProductsController extends Controller
{
public function listAction()
{
// Pick "views-dir/products/search" as view to render
$this->view->pick("products/search");
// Pick "views-dir/books/list" as view to render
$this->view->pick(
[
"books",
]
);
// Pick "views-dir/products/search" as view to render
$this->view->pick(
[
1 => "search",
]
);
}
}
Отключение представления
Если ваш контроллер не производит никакого вывода в представлении (или даже не имеет его), вы можете отключить компонент представления, избежав ненужной обработки:
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function closeSessionAction()
{
// Close session
// ...
// Disable the view to avoid rendering
$this->view->disable();
}
}
В качестве альтернативы, вы можете вернуть false, чтобы получить тот же эффект:
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function closeSessionAction()
{
// ...
// Disable the view to avoid rendering
return false;
}
}
Вы можете вернуть объект «ответ», чтобы не отключать представление вручную:
use Phalcon\Mvc\Controller;
class UsersController extends Controller
{
public function closeSessionAction()
{
// Close session
// ...
// A HTTP Redirect
return $this->response->redirect("index/index");
}
}
Простое отображение
Phalcon\Mvc\View\Simple — это альтернативный компонент для Phalcon\Mvc\View. Он сохраняет большую часть философии Phalcon\Mvc\View, но лишен иерархии файлов, которая фактически является его основной особенностью.
Этот компонент позволяет разработчику контролировать время отображения представления и его расположение. Кроме того, этот компонент может использовать наследование представлений, доступное в таких движках шаблонов, как Volt и других.
Компонент по умолчанию необходимо заменить в контейнере сервисов:
use Phalcon\Mvc\View\Simple as SimpleView;
$di->set(
"view",
function () {
$view = new SimpleView();
$view->setViewsDir("../app/views/");
return $view;
},
true
);
Автоматическое отображение должно быть отключено в Phalcon\Mvc\Application (при необходимости):
use Exception;
use Phalcon\Mvc\Application;
try {
$application = new Application($di);
$application->useImplicitView(false);
$response = $application->handle();
$response->send();
} catch (Exception $e) {
echo $e->getMessage();
}
Для отображения представления необходимо явно вызвать метод render, указав относительный путь к представлению, которое требуется отобразить:
use Phalcon\Mvc\Controller;
class PostsController extends \Controller
{
public function indexAction()
{
// Render 'views-dir/index.phtml'
echo $this->view->render("index");
// Render 'views-dir/posts/show.phtml'
echo $this->view->render("posts/show");
// Render 'views-dir/index.phtml' passing variables
echo $this->view->render(
"index",
[
"posts" => Posts::find(),
]
);
// Render 'views-dir/posts/show.phtml' passing variables
echo $this->view->render(
"posts/show",
[
"posts" => Posts::find(),
]
);
}
}
Это отличается от Phalcon\Mvc\View, где метод render() использует контроллеры и действия в качестве параметров:
$params = [
"posts" => Posts::find(),
];
// Phalcon\Mvc\View
$view = new \Phalcon\Mvc\View();
echo $view->render("posts", "show", $params);
// Phalcon\Mvc\View\Simple
$simpleView = new \Phalcon\Mvc\View\Simple();
echo $simpleView->render("posts/show", $params);
Использование частичных представлений
Частичные шаблоны — это еще один способ разбить процесс отображения на более простые и управляемые фрагменты, которые могут использоваться различными частями приложения. С помощью частичного представления вы можете перенести код для отображения определенной части ответа в отдельный файл.
Один из способов использования частичных представлений — рассматривать их как эквивалент подпрограмм: как способ вынести детали из представления, чтобы ваш код был более понятным. Например, у вас может быть представление, которое выглядит так:
<div class="top"><?php $this->partial("shared/ad_banner"); ?></div>
<div class="content">
<h1>Robots</h1>
<p>Check out our specials for robots:</p>
...
</div>
<div class="footer"><?php $this->partial("shared/footer"); ?></div>
Метод partial() принимает второй параметр в виде массива переменных/параметров, которые существуют только в области действия частичного представления:
<?php $this->partial("shared/ad_banner", ["id" => $site->id, "size" => "big"]); ?>
Передача значений из контроллера в представления
Phalcon\Mvc\View доступен в каждом контроллере с использованием переменной view ($this->view). Вы можете использовать этот объект для прямой установки переменных в представлении из действия контроллера, используя метод setVar().
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function indexAction()
{
}
public function showAction()
{
$user = Users::findFirst();
$posts = $user->getPosts();
// Pass all the username and the posts to the views
$this->view->setVar("username", $user->username);
$this->view->setVar("posts", $posts;
// Using the magic setter
$this->view->username = $user->username;
$this->view->posts = $posts;
// Passing more than one variable at the same time
$this->view->setVars(
[
"username" => $user->username,
"posts" => $posts,
]
);
}
}
Переменная с именем первого параметра метода setVar() будет создана в представлении, готовая к использованию. Переменная может быть любого типа, от простой строки, целого числа и т. д. до более сложной структуры, такой как массив, коллекция и т. д.
<h1>
{{ username }}'s Posts
</h1>
<div class="post">
<?php
foreach ($posts as $post) {
echo "<h2>", $post->title, "</h2>";
}
?>
</div>
Кэширование фрагментов представления
Иногда, при разработке динамических веб-сайтов, некоторые области которых не обновляются очень часто, вывод остается точно таким же между запросами. Phalcon\Mvc\View предлагает кэширование части или всего отрендеренного вывода для повышения производительности.
Phalcon\Mvc\View интегрируется с Phalcon\Cache для более простого кэширования фрагментов вывода. Вы можете вручную установить обработчик кэша или установить глобальный обработчик:
use Phalcon\Mvc\Controller;
class PostsController extends Controller
{
public function showAction()
{
// Cache the view using the default settings
$this->view->cache(true);
}
public function showArticleAction()
{
// Cache this view for 1 hour
$this->view->cache(
[
"lifetime" => 3600,
]
);
}
public function resumeAction()
{
// Cache this view for 1 day with the key "resume-cache"
$this->view->cache(
[
"lifetime" => 86400,
"key" => "resume-cache",
]
);
}
public function downloadAction()
{
// Passing a custom service
$this->view->cache(
[
"service" => "myCache",
"lifetime" => 86400,
"key" => "resume-cache",
]
);
}
}
Если мы не определяем ключ для кэша, компонент автоматически создает его, используя хэш MD5 имени контроллера и представления, которые в данный момент отображаются в формате «контроллер/представление». Хорошей практикой является определение ключа для каждого действия, чтобы вы могли легко идентифицировать кэш, связанный с каждым представлением.
Когда компоненту представления требуется кэшировать что-либо, он запросит службу кэширования из контейнера служб. Конвенция именования для этой службы — «viewCache»:
use Phalcon\Cache\Frontend\Output as OutputFrontend;
use Phalcon\Cache\Backend\Memcache as MemcacheBackend;
// Set the views cache service
$di->set(
"viewCache",
function () {
// Cache data for one day by default
$frontCache = new OutputFrontend(
[
"lifetime" => 86400,
]
);
// Memcached connection settings
$cache = new MemcacheBackend(
$frontCache,
[
"host" => "localhost",
"port" => "11211",
]
);
return $cache;
}
);
Фронтальный интерфейс всегда должен быть Phalcon\Cache\Frontend\Output, а служба «viewCache» должна быть зарегистрирована как всегда открытая (не общая) в контейнере служб (DI).
При использовании представлений кэширование может использоваться для предотвращения необходимости контроллерам генерировать данные представления при каждом запросе.
Для этого мы должны однозначно идентифицировать каждый кэш с помощью ключа. Сначала мы проверяем, существует ли кэш или он истек, чтобы произвести вычисления/запросы для отображения данных в представлении:
use Phalcon\Mvc\Controller;
class DownloadController extends Controller
{
public function indexAction()
{
// Check whether the cache with key "downloads" exists or has expired
if ($this->view->getCache()->exists("downloads")) {
// Query the latest downloads
$latest = Downloads::find(
[
"order" => "created_at DESC",
]
);
$this->view->latest = $latest;
}
// Enable the cache with the same key "downloads"
$this->view->cache(
[
"key" => "downloads",
]
);
}
}
Сайт PHP alternative site — пример реализации кэширования фрагментов.
Двигатели шаблонов
Двигатели шаблонов помогают разработчикам создавать представления без использования сложной синтаксической конструкции. Phalcon включает мощный и быстрый движок шаблонов под названием Volt.
Кроме того, Phalcon\Mvc\View позволяет использовать другие движки шаблонов вместо простого PHP или Volt.
Использование другого движка шаблонов обычно требует сложного разбора текста с использованием внешних библиотек PHP для генерации конечного вывода для пользователя. Это обычно увеличивает количество ресурсов, используемых приложением.
Если используется внешний движок шаблонов, Phalcon\Mvc\View предоставляет точно такую же иерархию представлений, и всё ещё возможно получить доступ к API внутри этих шаблонов с небольшими усилиями.
Этот компонент использует адаптеры, которые помогают Phalcon взаимодействовать с внешними движками шаблонов унифицированным способом, давайте рассмотрим, как выполнить эту интеграцию.
Создание собственного адаптера движка шаблонов
Существует множество движков шаблонов, которые вы можете интегрировать или создать свой собственный. Первым шагом для начала использования внешнего движка шаблонов является создание адаптера для него.
Адаптер движка шаблонов — это класс, который служит мостом между Phalcon\Mvc\View и самим движком шаблонов. Обычно ему требуются только две реализованные функции: __construct() и render(). Первая функция получает экземпляр Phalcon\Mvc\View, который создаёт адаптер движка, и контейнер DI, используемый приложением.
Функция render() принимает абсолютный путь к файлу представления и параметры представления, установленные с помощью $this->view->setVar(). Вы можете читать или включать его, когда это необходимо.
use Phalcon\DiInterface;
use Phalcon\Mvc\Engine;
class MyTemplateAdapter extends Engine
{
/**
* Adapter constructor
*
* @param \Phalcon\Mvc\View $view
* @param \Phalcon\Di $di
*/
public function __construct($view, DiInterface $di)
{
// Initialize here the adapter
parent::__construct($view, $di);
}
/**
* Renders a view using the template engine
*
* @param string $path
* @param array $params
*/
public function render($path, $params)
{
// Access view
$view = $this->_view;
// Access options
$options = $this->_options;
// Render the view
// ...
}
}
Изменение движка шаблонов
Вы можете полностью заменить движок шаблонов или использовать более одного движка шаблонов одновременно. Функция Phalcon\Mvc\View::registerEngines() принимает массив, содержащий данные, определяющие движки шаблонов. Ключ каждого движка — это расширение, которое помогает отличить один от другого. Файлы шаблонов, относящиеся к конкретному движку, должны иметь эти расширения.
Порядок определения движков шаблонов с помощью Phalcon\Mvc\View::registerEngines() определяет релевантность выполнения. Если Phalcon\Mvc\View находит два представления с одинаковым именем, но различными расширениями, он отобразит только первое.
Если вы хотите зарегистрировать движок шаблонов или набор из них для каждого запроса в приложении, вы можете зарегистрировать его при создании службы представления:
use Phalcon\Mvc\View;
// Setting up the view component
$di->set(
"view",
function () {
$view = new View();
// A trailing directory separator is required
$view->setViewsDir("../app/views/");
// Set the engine
$view->registerEngines(
[
".my-html" => "MyTemplateAdapter",
]
);
// Using more than one template engine
$view->registerEngines(
[
".my-html" => "MyTemplateAdapter",
".phtml" => "Phalcon\\Mvc\\View\\Engine\\Php",
]
);
return $view;
},
true
);
Адаптеры для нескольких движков шаблонов доступны в Phalcon Incubator
Вставка служб в представление
Каждое выполняемое представление включено в экземпляр Phalcon\Di\Injectable, что обеспечивает легкий доступ к контейнеру служб приложения.
Следующий пример демонстрирует, как написать запрос jQuery ajax request с использованием URL с использованием соглашений фреймворка. Служба «url» (обычно Phalcon\Mvc\Url) вставляется в представление путём доступа к свойству с тем же именем:
<script type="text/javascript">
$.ajax({
url: "<?php echo $this->url->get("cities/get"); ?>"
})
.done(function () {
alert("Done!");
});
</script>
Компонент в отрыве от остальных
Все компоненты в Phalcon могут использоваться как отдельные компоненты-«соединители», потому что они слабо связаны друг с другом:
Иерархическое рендеринг
Использование Phalcon\Mvc\View в режиме автономного функционирования показано ниже:
use Phalcon\Mvc\View;
$view = new View();
// A trailing directory separator is required
$view->setViewsDir("../app/views/");
// Passing variables to the views, these will be created as local variables
$view->setVar("someProducts", $products);
$view->setVar("someFeatureEnabled", true);
// Start the output buffering
$view->start();
// Render all the view hierarchy related to the view products/list.phtml
$view->render("products", "list");
// Finish the output buffering
$view->finish();
echo $view->getContent();
Также доступен короткий синтаксис:
use Phalcon\Mvc\View;
$view = new View();
echo $view->getRender(
"products",
"list",
[
"someProducts" => $products,
"someFeatureEnabled" => true,
],
function ($view) {
// Set any extra options here
$view->setViewsDir("../app/views/");
$view->setRenderLevel(
View::LEVEL_LAYOUT
);
}
);
Простое рендеринг
Использование Phalcon\Mvc\View\Simple в режиме автономного функционирования показано ниже:
use Phalcon\Mvc\View\Simple as SimpleView;
$view = new SimpleView();
// A trailing directory separator is required
$view->setViewsDir("../app/views/");
// Render a view and return its contents as a string
echo $view->render("templates/welcomeMail");
// Render a view passing parameters
echo $view->render(
"templates/welcomeMail",
[
"email" => $email,
"content" => $content,
]
);
События представления
Phalcon\Mvc\View и Phalcon\Mvc\View\Simple могут отправлять события в EventsManager, если он присутствует. События вызываются с типом «view». Некоторые события при возвращении false могут остановить активную операцию. Поддерживаются следующие события:
| Имя события | Вызвано | Может остановить операцию? |
|---|---|---|
| beforeRender | Вызывается перед началом процесса рендеринга | Да |
| beforeRenderView | Вызывается перед рендерингом существующего представления | Да |
| afterRenderView | Вызывается после рендеринга существующего представления | Нет |
| afterRender | Вызывается после завершения процесса рендеринга | Нет |
| notFoundView | Вызывается, когда представление не найдено | Нет |
Следующий пример демонстрирует, как прикрепить обработчики к этому компоненту:
use Phalcon\Events\Event;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Mvc\View;
$di->set(
"view",
function () {
// Create an events manager
$eventsManager = new EventsManager();
// Attach a listener for type "view"
$eventsManager->attach(
"view",
function (Event $event, $view) {
echo $event->getType(), " - ", $view->getActiveRenderPath(), PHP_EOL;
}
);
$view = new View();
$view->setViewsDir("../app/views/");
// Bind the eventsManager to the view component
$view->setEventsManager($eventsManager);
return $view;
},
true
);
Следующий пример показывает, как создать плагин, который очищает/исправляет HTML, генерируемый процессом рендеринга, с помощью Tidy:
use Phalcon\Events\Event;
class TidyPlugin
{
public function afterRender(Event $event, $view)
{
$tidyConfig = [
"clean" => true,
"output-xhtml" => true,
"show-body-only" => true,
"wrap" => 0,
];
$tidy = tidy_parse_string(
$view->getContent(),
$tidyConfig,
"UTF8"
);
$tidy->cleanRepair();
$view->setContent(
(string) $tidy
);
}
}
// Attach the plugin as a listener
$eventsManager->attach(
"view:afterRender",
new TidyPlugin()
);
© 2011–2017 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/latest/reference/views.html