Нелперы представления (Tags)

Написание и поддержание разметки HTML может быстро стать утомительной задачей из-за соглашений об именах и многочисленных атрибутов, которые необходимо учитывать. Phalcon справляется с этой сложностью, предлагая компонент Phalcon\Tag , в свою очередь, предлагает хелперы представления для создания разметки HTML.

Этот компонент может использоваться в простом представлении HTML + PHP или в шаблоне Volt.

Тип документа для контента.

Phalcon предлагает помощник Phalcon\Tag::setDoctype() для установки типа документа содержимого. Настройка типа документа может повлиять на вывод HTML, созданный другими помощниками тегов. Например, если вы установите семейство типов документов XHTML, помощники, которые возвращают или выводят теги HTML, будут создавать самозакрывающиеся теги в соответствии с действующим стандартом XHTML.

Доступные константы типа документа в пространстве имен Phalcon\Tag:

ConstantDocument type
HTML32 HTML 3.2
HTML401_STRICT HTML 4.01 Strict
HTML401_TRANSITIONAL HTML 4.01 Transitional
HTML401_FRAMESET HTML 4.01 Frameset
HTML5 HTML 5
XHTML10_STRICT XHTML 1.0 Strict
XHTML10_TRANSITIONAL XHTML 1.0 Transitional
XHTML10_FRAMESET XHTML 1.0 Frameset
XHTML11 XHTML 1.1
XHTML20 XHTML 2.0
XHTML5 XHTML 5

Установка типа документа.

<?php

use Phalcon\Tag;

$this->tag->setDoctype(Tag::HTML401_STRICT);

Получение типа документа.

<?= $this->tag->getDoctype() ?>
<html>
<!-- your HTML code -->
</html>

Следующий HTML будет произведен.

<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'
        'http://www.w3.org/TR/html4/strict.dtd'>
<html>
<!-- your HTML code -->
</html>

Volt синтаксис:

{{ get_doctype() }}
<html>
<!-- your HTML code -->
</html>

Генерация ссылок

Реальная общая задача в любом веб-приложении или веб-сайте - создавать ссылки, которые позволяют нам переходить с одной страницы на другую. Когда они являются внутренними URL-адресами, мы можем создать их следующим образом:

<!-- для маршрута по умолчанию -->
<?= $this->tag->linkTo('products/search', 'Search') ?>

<!-- с атрибутами CSS -->
<?= $this->tag->linkTo(['products/edit/10', 'Edit', 'class' => 'edit-btn']) ?>

<!-- для названного маршрута -->
<?= $this->tag->linkTo([['for' => 'show-product', 'title' => 123, 'name' => 'carrots'], 'Show']) ?>

На самом деле все созданные URL-адреса создаются компонентом Phalcon\Mvc\Url. Те же ссылки могут быть созданы с помощью Volt:

<!-- для маршрута по умолчанию -->
{{ link_to('products/search', 'Search') }}

<!-- для названного маршрута -->
{{ link_to(['for': 'show-product', 'id': 123, 'name': 'carrots'], 'Show') }}

<!-- для именованного маршрута с классом HTML -->
{{ link_to(['for': 'show-product', 'id': 123, 'name': 'carrots'], 'Show', 'class': 'edit-btn') }}

Создание форм

Формы в веб-приложениях играют важную роль в извлечении пользовательского ввода. В следующем примере показано, как реализовать простую форму поиска с помощью помощников вида:

<!-- Отправка формы методом POST -->
<?= $this->tag->form('products/search') ?>
    <label for='q'>Search:</label>

    <?= $this->tag->textField('q') ?>

    <?= $this->tag->submitButton('Search') ?>
<?= $this->tag->endForm() ?>

<!-- Указание другого метода или атрибутов для тега FORM -->
<?= $this->tag->form(['products/search', 'method' => 'get']); ?>
    <label for='q'>Search:</label>

    <?= $this->tag->textField('q'); ?>

    <?= $this->tag->submitButton('Search'); ?>
<?= $this->tag->endForm() ?>

Этот последний код будет генерировать следующий HTML:

<form action='/store/products/search/' method='get'>
    <label for='q'>Search:</label>

    <input type='text' id='q' value='' name='q' />

    <input type='submit' value='Search' />
</form>

Та же форма, сгенерированная в Volt:

<!-- Specifying another method or attributes for the FORM tag -->
{{ form('products/search', 'method': 'get') }}
    <label for='q'>Search:</label>

    {{ text_field('q') }}

    {{ submit_button('Search') }}
{{ endForm() }}

Phalcon также предоставляет конструктор форм для создания форм объектно-ориентированным способом.

Помощники для создания элементов формы

Phalcon предоставляет ряд помощников для создания элементов формы, таких как текстовые поля, кнопки и многое другое. Первым параметром каждого помощника всегда является имя генерируемого элемента. Когда форма будет отправлена, имя будет передано вместе с данными формы. В контроллере вы можете получить эти значения, используя одно и то же имя, используя методы getPost() и getQuery() объекта запроса ($this->request).

<?php echo $this->tag->textField('username') ?>

<?php echo $this->tag->textArea(
    [
        'comment',
        'Это содержимое текстовой области',
        'cols' => '6',
        'rows' => 20,
    ]
) ?>

<?php echo $this->tag->passwordField(
    [
        'password',
        'size' => 30,
    ]
) ?>

<?php echo $this->tag->hiddenField(
    [
        'parent_id',
        'value' => '5',
    ]
) ?>

Volt syntax:

{{ text_field('username') }}

{{ text_area('comment', 'Это содержимое текстовой области', 'cols': '6', 'rows': 20) }}

{{ password_field('password', 'size': 30) }}

{{ hidden_field('parent_id', 'value': '5') }}

Создание Селектов

Создать блоки выбора (поле выбора) легко, особенно если связанные данные хранятся в ассоциативных массивах PHP. Помощниками для элементов select являются Phalcon\Tag::select() и Phalcon\Tag::selectStatic(). Phalcon\Tag::select() был специально разработан для работы с Phalcon моделями (Phalcon\Mvc\Model), а Phalcon\Tag::selectStatic() может работать с массивами PHP.

<?php

$products = Products::find("type = 'vegetables'");

// Использование данных из набора результатов
echo $this->tag->select(
    [
        'productId',
        $products,
        'using' => [
            'id',
            'name',
        ]
    ]
);

// Использование данных из массива
echo $this->tag->selectStatic(
    [
        'status',
        [
            'A' => 'Active',
            'I' => 'Inactive',
        ]
    ]
);

Будет сгенерирован следующий HTML-код:

    <select id='productId' name='productId'>
        <option value='101'>Tomato</option>
        <option value='102'>Lettuce</option>
        <option value='103'>Beans</option>
    </select>

    <select id='status' name='status'>
        <option value='A'>Active</option>
        <option value='I'>Inactive</option>
    </select>

Вы можете добавить пустую опцию empty к сгенерированному HTML:

   <?php

    $products = Products::find("type = 'vegetables'");

    // Создание тега выбора с пустой опцией
    echo $this->tag->select(
        [
            'productId',
            $products,
            'using'    => [
                'id',
                'name',
            ],
            'useEmpty' => true,
        ]
    );

Производит этот HTML:

<select id='productId' name='productId'>
    <option value=''>Choose..</option>
    <option value='101'>Tomato</option>
    <option value='102'>Lettuce</option>
    <option value='103'>Beans</option>
</select>

 

<?php

$products = Products::find("type = 'vegetables'");

// Создание тега выбора с пустой опцией с текстом по умолчанию
echo $this->tag->select(
    [
        'productId',
        $products,
        'using'      => [
            'id',
            'name',
        ],
        'useEmpty'   => true,
        'emptyText'  => 'Please, choose one...',
        'emptyValue' => '@',
    ]
);
<select id='productId' name='productId'>
    <option value='@'>Please, choose one..</option>
    <option value='101'>Tomato</option>
    <option value='102'>Lettuce</option>
    <option value='103'>Beans</option>
</select>

Синтаксис Volt для приведенного выше примера:

    {# Creating a Select Tag with an empty option with default text #}
    {{ select('productId', products, 'using': ['id', 'name'],
        'useEmpty': true, 'emptyText': 'Please, choose one...', 'emptyValue': '@') }}

Назначение атрибутов HTML

Все помощники принимают массив в качестве первого параметра, который может содержать дополнительные атрибуты HTML для сгенерированного элемента.

<?php $this->tag->textField(
    [
        'price',
        'size'        => 20,
        'maxlength'   => 30,
        'placeholder' => 'Enter a price',
    ]
) ?>

или используя Volt:

{{ text_field('price', 'size': 20, 'maxlength': 30, 'placeholder': 'Enter a price') }}

Следующий HTML генерируется:

<input type='text' name='price' id='price' size='20' maxlength='30'
       placeholder='Enter a price' />

Установка значений помощника

Из Контроллеров

Хороший принцип программирования для сред MVC - устанавливать конкретные значения для элементов формы в представлении. Вы можете установить эти значения непосредственно из контроллера, используя Phalcon\Tag::setDefault(). Этот помощник предварительно загружает значение для любых помощников, присутствующих в представлении. Если какой-либо помощник в представлении имеет имя, которое соответствует предварительно загруженному значению, он будет использовать его, если только значение непосредственно не назначено помощнику в представлении.

<?php

use Phalcon\Mvc\Controller;

class ProductsController extends Controller
{
    public function indexAction()
    {
        $this->tag->setDefault('color', 'Blue');
    }
}

В представлении помощник selectStatic соответствует тому же индексу, который использовался для предварительной установки значения. В этом случае color:

<?php

echo $this->tag->selectStatic(
    [
        'color',
        [
            'Yellow' => 'Yellow',
            'Blue'   => 'Blue',
            'Red'    => 'Red',
        ]
    ]
);

Это сгенерирует следующий тег выбора с выбранным значением «Синий»:

<select id='color' name='color'>
    <option value='Yellow'>Yellow</option>
    <option value='Blue' selected='selected'>Blue</option>
    <option value='Red'>Red</option>
</select>

Из запроса

Особенность, которой обладают помощники Phalcon\Tag , заключается в том, что они сохраняют значения помощников форм между запросами. Таким образом, вы можете легко показывать сообщения проверки без потери введенных данных.

Указание значений напрямую

Каждый помощник по формам поддерживает параметр 'value'. Когда этот параметр присутствует, любое предустановленное значение с помощью setDefault () или с помощью запроса будет игнорироваться.

Динамическое изменение заголовка документа

Phalcon\Tag предлагает помощникам динамически изменять заголовок документа из контроллера. Следующий пример демонстрирует именно это:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function initialize()
    {
        $this->tag->setTitle('Your Website');
    }

    public function indexAction()
    {
        $this->tag->prependTitle('Index of Posts - ');
    }
}
<html>
    <head>
        <?php echo $this->tag->getTitle(); ?>
    </head>

    <body>

    </body>
</html>

Будет сгенерирован следующий HTML-код:

<html>
    <head>
        <title>Index of Posts - Your Website</title>
    </head>

    <body>

    </body>
</html>

Помощники по статическому содержимому

Phalcon\Tag также предоставляет помощников для создания тегов, таких как скрипт, ссылка или img. Они помогают в быстрой и простой генерации статических ресурсов вашего приложения

Изображения

<?php

// Generate <img src='/your-app/img/hello.gif'>
echo $this->tag->image('img/hello.gif');

// Generate <img alt='alternative text' src='/your-app/img/hello.gif'>
echo $this->tag->image(
    [
       'img/hello.gif',
       'alt' => 'alternative text',
    ]
);

Volt syntax:

{# Generate <img src='/your-app/img/hello.gif'> #}
{{ image('img/hello.gif') }}

{# Generate <img alt='alternative text' src='/your-app/img/hello.gif'> #}
{{ image('img/hello.gif', 'alt': 'alternative text') }}

Stylesheets

<?php

// Generate <link rel='stylesheet' href='http://fonts.googleapis.com/css?family=Rosario' type='text/css'>
echo $this->tag->stylesheetLink('http://fonts.googleapis.com/css?family=Rosario', false);

// Generate <link rel='stylesheet' href='/your-app/css/styles.css' type='text/css'>
echo $this->tag->stylesheetLink('css/styles.css');

Volt syntax:

{# Generate <link rel='stylesheet' href='http://fonts.googleapis.com/css?family=Rosario' type='text/css'> #}
{{ stylesheet_link('http://fonts.googleapis.com/css?family=Rosario', false) }}

{# Generate <link rel='stylesheet' href='/your-app/css/styles.css' type='text/css'> #}
{{ stylesheet_link('css/styles.css') }}

Javascript

<?php

// Generate <script src='http://localhost/javascript/jquery.min.js' type='text/javascript'></script>
echo $this->tag->javascriptInclude('http://localhost/javascript/jquery.min.js', false);

// Generate <script src='/your-app/javascript/jquery.min.js' type='text/javascript'></script>
echo $this->tag->javascriptInclude('javascript/jquery.min.js');

Volt syntax:

{# Generate <script src='http://localhost/javascript/jquery.min.js' type='text/javascript'></script> #}
{{ javascript_include('http://localhost/javascript/jquery.min.js', false) }}

{# Generate <script src='/your-app/javascript/jquery.min.js' type='text/javascript'></script> #}
{{ javascript_include('javascript/jquery.min.js') }}

Элементы HTML5 - универсальный помощник HTML

Phalcon предлагает универсальный помощник HTML, который позволяет генерировать любые HTML-элементы. Разработчик должен создать действительное имя HTML-элемента для помощника.

<?php

// Generate
// <canvas id='canvas1' width='300' class='cnvclass'>
// This is my canvas
// </canvas>
echo $this->tag->tagHtml(
    'canvas', 
    [
        'id'    => 'canvas1', 
        'width' => '300', 
        'class' => 'cnvclass',
    ], 
    false, 
    true, 
    true
);
echo 'This is my canvas';
echo $this->tag->tagHtmlClose('canvas');

Volt syntax:

{# Generate
<canvas id='canvas1' width='300' class='cnvclass'>
This is my canvas
</canvas> #}
{{ tag_html('canvas', ['id': 'canvas1', width': '300', 'class': 'cnvclass'], false, true, true) }}
    This is my canvas
{{ tag_html_close('canvas') }}

Служба тегов

Phalcon\Tag доступен через службу tag , это означает, что вы можете получить к нему доступ из любой части приложения, где расположен контейнер служб:

<?php echo $this->tag->linkTo('pages/about', 'About') ?>

Вы можете легко добавить новых помощников в пользовательский компонент, заменив тег службы в контейнере служб:

<?php

use Phalcon\Tag;

class MyTags extends Tag
{
    // ...

    // Create a new helper
    public static function myAmazingHelper($parameters)
    {
        // ...
    }

    // Override an existing method
    public static function textField($parameters)
    {
        // ...
    }
}

Затем измените определение службы tag:

<?php

$di['tag'] = function () {
    return new MyTags();
};

Создание собственных помощников

Вы можете легко создавать своих собственных помощников. Сначала начните с создания новой папки в том же каталоге, что и ваши контроллеры и модели. Дайте ему название, относящееся к тому, что вы создаете. Для нашего примера здесь мы можем назвать его «customhelpers». Далее мы создадим новый файл с именем MyTags.php в этом новом каталоге. На данный момент у нас есть структура, которая выглядит примерно так: /app/customhelpers/MyTags.php. В MyTags.php мы расширим Phalcon\Tag и реализуем ваш собственный помощник. Ниже приведен простой пример пользовательского помощника:

<?php

use Phalcon\Tag;

class MyTags extends Tag
{
    /**
     * Создает виджет для отображения аудио тега HTML5
     *
     * @param array
     * @return string
     */
    public static function audioField($parameters)
    {
        // Преобразование параметров в массив, если это не так
        if (!is_array($parameters)) {
            $parameters = [$parameters];
        }

        // Определение атрибутов «id» и «name»
        if (!isset($parameters[0])) {
            $parameters[0] = $parameters['id'];
        }

        $id = $parameters[0];

        if (!isset($parameters['name'])) {
            $parameters['name'] = $id;
        } else {
            if (!$parameters['name']) {
                $parameters['name'] = $id;
            }
        }

        // Определение значения виджета,
        // \Phalcon\Tag::setDefault() allows to set the widget value
        if (isset($parameters['value'])) {
            $value = $parameters['value'];

            unset($parameters['value']);
        } else {
            $value = self::getValue($id);
        }

        // Сгенерировать код тега
        $code = '<audio id="' . $id . '" value="' . $value . '" ';

        foreach ($parameters as $key => $attributeValue) {
            if (!is_integer($key)) {
                $code.= $key . '="' . $attributeValue . '" ';
            }
        }

        $code.=' />';

        return $code;
    }
}

После создания нашего пользовательского помощника мы автоматически загрузим новый каталог, который содержит наш класс помощника из нашего index.php, расположенного в общедоступном каталоге.

<?php

use Phalcon\Loader;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault();
use Phalcon\Exception as PhalconException;

try {
    $loader = new Loader();

    $loader->registerDirs(
        [
            '../app/controllers',
            '../app/models',
            '../app/customhelpers', // Добавить новую папку помощников
        ]
    );

    $loader->register();

    $di = new FactoryDefault();

    // Присвойте нашему новому тегу определение, чтобы мы могли его назвать
    $di->set(
        'MyTags',
        function () {
            return new MyTags();
        }
    );

    $application = new Application($di);

    $response = $application->handle();

    $response->send();
} catch (PhalconException $e) {
    echo 'PhalconException: ', $e->getMessage();
}

Теперь вы готовы использовать нового помощника в своих представлениях:

<body>

    <?php

    echo MyTags::audioField(
        [
            'name' => 'test',
            'id'   => 'audio_test',
            'src'  => '/path/to/audio.mp3',
        ]
    );

    ?>

</body>

Вы также можете воспользоваться более быстрым механизмом шаблонов для PHP на Volt , где вы можете использовать более удобный для разработчиков синтаксис для помощников, предоставляемых Phalcon\Tag.