Страницы с содержимым автоматически соединяются с шаблонами и выводят блоки контента. Класс Page является основным элементом платформы WebForms.PHP. Страницы могут иметь пользовательские свойства, методы и обработчики событий. При помощи директив можно упростить процесс программирования страниц и расширить их функционал за счет пользовательских элементов управления.
Для использования шаблонов, файлы страниц должны обрабатываться PHP (как правило, иметь расширение .php).
Страницы могут быть простыми, состоять из одного файла, содержащего HTML и, при необходимости, код PHP.
Но для использования всех возможностей движка потребуется разделение кода HTML и PHP, как минимум, на два файла. В основном файле должно содержаться объектное представление страницы - класс. Во втором файле - разметка страницы (код HTML).
Файл с разметкой должен иметь тоже название, что и файл страницы, но с расширением .html.php.
Помимо этого, каждая страница может иметь ресурсы локализации, которые должны располагаться в файлах .json.
Содержимое для блоков контента должно располагаться в тегах: <php:Content />
. Имя (идентификатор) блока указывается в параметре ID
.
<php:Content ID="имяМетки">
Содержимое блока.
Допустимо использование любых тэгов,
серверного кода и
элементов управления.
</php:Content>
Все, что располагается за переделами тегов <php:Content />
будет проигнорировано.
Этот текст будет проигнорирован, т.к. находится вне блока <php:Content />.
<php:Content ID="MainContent">
Это текст будет выведен вместо метки <php:MainContent/>.
</php:Content>
Этот текст будет проигнорирован, т.к. находится вне блока <php:Content />.
Допустимо размещение блоков для несуществующих в шаблоне меток. Это будет полезно при динамическом изменении шаблона, когда в одном шаблоне определен один набор блоков контента, а в другом - другой.
В следующем примере показано два шаблона. В первом определен блок <php:MainContent/>
, во втором два блока: <php:MainContent/>
и <php:RightPanel/>
. На странице контента определено содержимое для двух блоков. При использовании шаблона Layout1.php клиент получит только содержимое для блока <php:MainContent/>
, поскольку в шаблоне нет других блоков (см. Результат #1). А при использовании шаблона Layout2.php, клиенту будет выдано содержимое определенное для обоих блоков (см. Результат #2).
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="container">
<php:MainContent/>
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="container">
<div class="col-md-10">
<php:MainContent/>
</div>
<div class="col-md-2">
<php:RightPanel/>
</div>
</div>
</body>
</html>
<php:Content ID="MainContent">
Это содержимое для блока MainContent.
</php:Content>
<php:Content ID="RightPanel">
Это содержимое для блока RightPanel.
</php:Content>
<!DOCTYPE html>
<html>
<head>
<title>Заголовок по умолчанию</title>
</head>
<body>
<div class="container">
Это содержимое для блока MainContent.
</div>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Заголовок по умолчанию</title>
</head>
<body>
<div class="container">
<div class="col-md-10">
Это содержимое для блока MainContent.
</div>
<div class="col-md-2">
Это содержимое для блока RightPanel.
</div>
</div>
</body>
</html>
Если на одной контентной странице будет размещено несколько блоков контента с одинаковым идентификатором, то будет использоваться последний блок. Так лучше не делать, т.к. будут расходоваться ресурсы на обработку всех блоков.
<php:Content ID="MainContent">
Это текст будет обработан, но не будет выведен, т.к. ниже размещен второй блок с идентификатором MainContent.
</php:Content>
<php:Content ID="MainContent">
Это текст будет выведен вместо метки <php:MainContent/>.
</php:Content>
Простые страницы состоят из одного файла, содержащего разметку и блоки контента, а также могут содержать директивы, пользовательские элементы управления и любой серверный код.
Простые страницы могут быть полезны для вывода статичного содержимого, когда не требуется управление процессом формирования страницы на сервере.
Для работы шаблонизатора, на страницу необходимо включить файл global.php, а также вызвать процесс обработки страницы командной App::Magic()
.
<?php
require_once 'global.php';
\Nemiro\App::Magic();
?>
В следующем примере показана реализация простой страницы, которая формирует содержимое для метки <php:MainContent/>
. В директиве #Page
указана ссылка на файл шаблона, а также заголовок страницы (<title />
).
<?#Page Layout="~/Layouts/_Layout.php" Title="Это простая страница"?>
<php:Content ID="MainContent">
<h2>Привет, мир!</h2>
</php:Content>
<?php
require_once 'global.php';
Nemiro\App::Magic();
?>
Простые страницы не предоставляют доступ к объектному представлению страницы и имеют ограниченный функционал по управлению шаблонами и пользовательскими элементами управления.
Для использования всех возможностей, рекомендуется разделять код HTML и PHP.
В основном файле страницы создается класс страницы. Имя класса должно соответствовать имени файла страницы (без расширения). Разметка должна находиться в файле с расширением .html.php.
Например, есть страница index.php, она должна иметь примерно следующее содержание:
<?php
require_once 'global.php';
class Index extends \Nemiro\UI\Page
{
}
\Nemiro\App::Magic();
?>
А разметка должна располагаться в файле index.html.php. В следующем примере показан возможный вариант файла index.html.php.
<php:Content ID="MainContent">
<h2>Привет, мир!</h2>
</php:Content>
Такая модель позволяет снизить смешивание серверного и клиентского кода, а также позволяет полностью управлять процессом формирования страницы.
Класс страницы может содержать любые публичные свойства и функции, которые можно использовать в коде разметки, через ключевое слово $this
. Например, базовый класс \Nemiro\UI\Page
имеет свойство Title
, которое содержит заголовок текущей страницы и его можно вывести на страницу следующим образом:
<php:Content ID="MainContent">
<h2>Заголовок страницы: <?=$this->Title?></h2>
</php:Content>
Допустимо не создавать файлы с разметкой. В таком случае, страница будет состоять только из класса, а содержимое для блоков контента должно формироваться программно.
Например, файл index.php может иметь следующее содержание.
<?php
require_once 'global.php';
class Index extends \Nemiro\UI\Page
{
function Load()
{
$this->Title = 'Это страница без разметки';
$this->Content['MainContent'] = 'А здесь у нас контент для блока MainContent.';
}
}
\Nemiro\App::Magic();
?>
Но такой подход используется редко, поскольку для большинства случаев это не очень удобно.
Директива <?#Page ?>
позволяет переопределить параметры инициализации страницы заданные по умолчанию (в файле config.php).
Директива располагается в верхней части страницы HTML, параметры записываются в стиле атрибутов тегов HTML/XML. Например: <?#Page Title="Заголовок страницы" Layout="~/Layouts/_Layout.php" ?>
Список поддерживаемых параметров представлен в следующей таблице.
Параметр | Описание | |
---|---|---|
Layout | Строка | Позволяет указать файл шаблона, который следует использовать при формировании страницы. |
Title | Строка | Позволяет указать html-заголовок страницы (аналог тега <title></title>). |
Optimized | Логический | Позволяет управлять режимом оптимизации результирующего html-кода страницы. |
Cache | Логический | Позволяет управлять кешированием страницы. |
Culture | Строка | Позволяет задать культуру (язык) для страницы. Как правило, используется стандартный двухбуквенный код языка. Например: ru, en. |
В следующем примере показано использование директивы <?#Page ?>
для назначения заголовка страницы и включения режима оптимизации HTML.
<?#Page Title="Заголовок страницы" Optimized="true" ?>
<php:Content ID="MainContent">
Привет, мир!
</php:Content>
Использование директивы <?#Page ?>
наиболее актуально при создании простых страниц.
Как и в шаблонах, на обычных страницах можно использовать директиву <?#Register ?>
для регистрации пользовательских элементов управления.
Директива <?#Register ?>
принимает четыре параметра, список которых представлен в следующей таблице.
Параметр | Описание | |
---|---|---|
Src | Строка | Обязательный параметр. Путь к основному файлу элемента управления. |
TagPrefix | Строка | Обязательный параметр. Префикс имени элемента управления, который будет использоваться при размещении экземпляра элемента на странице. Префикс может быть полезен для разделения элементов на группы, привязки к определенному источнику, или, когда на странице одновременно требуется разместить несколько элементов с одинаковыми именами, но разным источником. |
TagName | Строка | Обязательный параметр. Имя элемента управления, которое будет использоваться при размещении экземпляра элемента на странице. |
ClassName | Строка |
Опциональный параметр. Указывает имя класса элемента. По умолчанию, в качестве имени класса ожидается название файла элемента, без учета расширения. Например, основной файл элемента Message.php, то ClassName по умолчанию будет Message .
|
Количество директив <?#Register ?>
на одной странице ограничивается, разве что, здравым смыслом.
В следующем примере показано использование директивы <?#Register ?>
для регистрации на странице пользовательских элементов управления Message
и TabControl
, и их последующее использование.
<?#Register Src="~/Controls/Message.php" TagPrefix="php" TagName="Message"?>
<?#Register Src="~/Controls/TabControl.php" TagPrefix="php" TagName="TabControl"?>
<php:Content ID="MainContent">
Привет, мир!
<php:Message Type="success" Content="Всё хорошо!" />
<php:TabControl>
<php:Items>
<php:TabItem Key="Tab1" Title="Обратите внимание">
Элементы TabControl и Message не являются частью WebForms.PHP,
эти элементы были сделаны специально для демонстрационного сайта.
</php:TabItem>
<php:TabItem Key="Tab2" Title="Однако...">
Но при желании вы можете использовать эти элементы в своих проектах,
просто скопировав файлы элементов из папки /Controls.
Для правильной работы этих элементов также потребуется Bootstrap3.
</php:TabItem>
</php:Items>
</php:TabControl>
</php:Content>
<!DOCTYPE html>
<html>
<head>
<title>Заголовок по умолчанию</title>
</head>
<body>
<div class="container">
<!--Начало вывода блока контента MainContent-->
Привет, мир!
<!--Начало вывода элемента Message-->
<div class="alert alert-success">Всё хорошо!</div>
<!--Конец вывода элемента Message-->
<!--Начало вывода элемента TabControl-->
<ul class="nav nav-tabs" role="tablist">
<li class="active">
<a href="#Page_TabControl1_Tab1" aria-controls="Page_TabControl1_Tab1" role="tab" data-toggle="tab" aria-expanded="false">
Обратите внимание
</a>
</li>
<li>
<a href="#Page_TabControl1_Tab2" aria-controls="Page_TabControl1_Tab2" role="tab" data-toggle="tab" aria-expanded="true">
Однако...
</a>
</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane" id="Page_TabControl1_Tab1">
Элементы TabControl и Message не являются частью WebForms.PHP,
эти элементы были сделаны специально для демонстрационного сайта.
</div>
<div role="tabpanel" class="tab-pane" id="Page_TabControl1_Tab2">
Но при желании вы можете использовать эти элементы в своих проектах,
просто скопировав файлы элементов из папки /Controls.
Для правильной работы этих элементов также потребуется Bootstrap3.
</div>
</div>
<!--Конец вывода элемента TabControl-->
<!--Конец вывода блока контента MainContent-->
</div>
</body>
</html>
Класс \Nemiro\UI\Page
(далее Page
) - этой основной класс, который отвечает за формирование страниц.
От класса Page
должны наследоваться (extends
) классы всех страниц.
Если у страницы нет класса, то используется экземпляр класса Page
по умолчанию, с ограниченными возможностями.
В следующем фрагменте кода показан вариант наследования класса страницы Forum
от базового класса Page
.
<?php
require_once 'global.php';
class Forum extends \Nemiro\UI\Page
{
}
\Nemiro\App::Magic();
?>
Класс Page
имеет следующие публичные свойства.
Свойство | Описание | |
---|---|---|
Optimized | Логический | Позволяет управлять режимом оптимизации результирующего html-кода страницы. Программно изменить режим оптимизации можно в обработчике события PreLoad или Load. |
Cache | Логический | Позволяет управлять кешированием страницы. Программно изменить режим кеширования страницы можно в обработчике события PreLoad. |
Layout | Строка | Содержит путь к файлу шаблона. Это либо значение по умолчанию, из файла config.php, либо значение определенное в директиве <?#Page ?> , либо установленное программно значение.Программно изменить путь к файлу шаблона можно в обработчике события PreLoad. |
Encode | Строка | Название кодировки страницы. Передается в Content-Type .Программно изменить значение этого свойства можно в обработчике события PreLoad. |
Culture | Строка | Код культуры (язык) для страницы. Как правило, используется стандартный двухбуквенный код языка. Например: ru, en. Программно изменить значение этого свойства можно в обработчике события PreLoad или Load. |
Title | Строка | Заголовок страницы (аналог тега <title></title>). Программно изменить значение этого свойства можно в обработчике события PreLoad или Load. |
Content | Коллекция (ключ=значение) | Коллекция блоков содержимого страницы; где ключом является имя (идентификатор) блока, а значением - содержимое блока. Программно изменить блоки контента можно в обработчике события PreLoad или Load. Например: $this->Content['MainContent'] = 'Контент для блока MainContent.'; |
Meta | Коллекция (ключ=значение) | Коллекция метатегов; где ключом является имя (идентификатор) тега, а значением - содержимое тега. Программно добавить метатеги можно в обработчике события PreLoad или Load. Например: $this->Meta['DESCRIPTION'] = 'Описание страницы.'; , на выходе будет метатег:<meta name="DESCRIPTION" content="Описание страницы." /> .Для установки описания и ключевых слов также можно использовать методы SetDescription и SetKeyWords .Например: $this->SetDescription('Описание страницы.'); |
Scripts | Строковой массив | Массив ссылок на клиентские скрипты, которые будут включены в страницу. Программно добавить или изменить ссылки можно в обработчике события PreLoad или Load. |
Controls | Коллекция (ключ=значение) | Коллекция элементов управления; где ключ - идентификатор элемента (ID ), а значение - элемент управления.Программно изменить свойства элементов управления можно в обработчике события Load. Обратите внимание, что через эту коллекцию нельзя получить прямой доступ к экземплярам элементов управления, это лишь возможность определить значения свойств элементам, которые будут созданы в процессе формирования страницы. Через коллекцию Controls невозможно получить доступ к публичным методам элемента управления. |
Resources | Коллекция (ключ=значение) | Коллекция ресурсов локализации; где ключ - имя ресурса, а значение - локализованная строка. Программно изменить ресурсы можно в обработчике события Load. |
Все публичные свойства доступны для классов-потомков, т.е. классов страниц.
У страницы существует три события, которые можно обработать.
Событие PreLoad
возникает после инициализации страницы, до начала вывода HTTP-заголовков, загрузки шаблона и ресурсов локализации.
Как следствие этого, в обработчике события PreLoad
можно изменить путь к файлу шаблона и добавить произвольные заголовки HTTP.
Управлять ресурсами локализации (свойство Resources
) в обработчике этого события не имеет смысла, т.к. ресурсы перезаписываются при загрузке файлов локализации. Однако можно изменить Culture
, чтобы загрузились ресурсы для определенного языка.
В следующем примере показано изменение файла шаблона в обработчике события PreLoad
.
<?php
require_once 'global.php';
class Index extends \Nemiro\UI\Page
{
function PreLoad()
{
$this->Layout = '/example.html';
}
}
\Nemiro\App::Magic();
?>
Событие Load
происходит перед формированием данных для вывода.
В обработчике этого события можно изменить заголовок страницы, метатеги, список клиентских скриптов, содержимое блоков контента и определить значения свойствам пользовательских элементов управления.
В следующем примере показано изменение заголовка страницы в обработчике события Load
и добавление описания в метатеги страницы при помощи метода SetDescription
.
<?php
require_once 'global.php';
class Index extends \Nemiro\UI\Page
{
function Load()
{
$this->Title = 'Новый заголовок страницы';
$this->SetDescription('Описание страницы.');
}
}
\Nemiro\App::Magic();
?>
Событие LoadComplete
происходит после формирования и вывода данных.
В обработчике этого события ничего изменить нельзя сделать, это просто возможность зафиксировать процесс завершения создания страницы.
<?php
require_once 'global.php';
class Index extends \Nemiro\UI\Page
{
function LoadComplete()
{
echo 'Страница сформирована!';
}
}
\Nemiro\App::Magic();
?>
Для локализации страниц можно использовать локальные и глобальные ресурсы (global.json).
Локальные ресурсы - это файлы с расширением .json, имеющие тоже название, что и основной файл страницы. В имени файла должна указываться культура (язык), для которой предназначены ресурсы.
Например, для страницы index.php могут быть следующие файлы ресурсов: index.json - ресурсы по умолчанию, index.ru.json - ресурсы для русского языка, index.en.json - ресурсы для английского языка, index.de.json - ресурсы для немецкого языка и т.п.
Действие локальных ресурсов распространяется и на шаблоны. Эту особенность можно использовать для создания статичных ресурсов заголовков страниц и/или метатегов.