This article reflects v3.4 and has not yet been revised

View Helpers (Tags)

Writing and maintaining HTML markup can quickly become a tedious task because of the naming conventions and numerous attributes that have to be taken into consideration. Phalcon deals with this complexity by offering the Phalcon\Tag component which in turn offers view helpers to generate HTML markup.

This component can be used in a plain HTML+PHP view or in a Volt template.

This guide is not intended to be a complete documentation of available helpers and their arguments. Please visit the Phalcon\Tag page in the API for a complete reference.

Document Type of Content

Phalcon offers the Phalcon\Tag::setDoctype() helper to set document type of the content. The document type setting may affect HTML output produced by other tag helpers. For example, if you set XHTML document type family, helpers that return or output HTML tags will produce self-closing tags to follow valid XHTML standard.

Available document type constants in Phalcon\Tag namespace are:

Constante Tipo de documento
HTML32 HTML 4.0
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

Setting document type.

<?php

use Phalcon\Tag;

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

Getting document type.

<?= $this->tag->getDoctype() ?>
<html>
<!-- tu código HTML -->
</html>

The following HTML will be produced.

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

Sintaxis Volt:


{{ get_doctype() }}

<html>
<!-- your HTML code -->
</html>

Generando enlaces

A real common task in any web application or website is to produce links that allow us to navigate from one page to another. When they are internal URLs we can create them in the following manner:

<!-- para el router por defecto -->
<?= $this->tag->linkTo('products/search', 'Buscar') ?>

<!-- con atributos CSS -->
<?= $this->tag->linkTo(['products/edit/10', 'Editar', 'class' => 'edit-btn']) ?>

<!-- para un router con nombre -->
<?= $this->tag->linkTo([['for' => 'show-product', 'title' => 123, 'name' => 'carrots'], 'Ver']) ?>

Actually, all produced URLs are generated by the component Phalcon\Url. The same links can be generated with Volt:


<!-- for the default route -->
{{ link_to('products/search', 'Search') }}

<!-- for a named route -->
{{ link_to(['for': 'show-product', 'id': 123, 'name': 'carrots'], 'Show') }}

<!-- for a named route with a HTML class -->
{{ link_to(['for': 'show-product', 'id': 123, 'name': 'carrots'], 'Show', 'class': 'edit-btn') }}

Creating Forms

Forms in web applications play an essential part in retrieving user input. The following example shows how to implement a simple search form using view helpers:

<!-- Enviando el formulario por el método POST -->
<?= $this->tag->form('products/search') ?>
    <label for='q'>Buscar:</label>

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

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

<!-- Especificando otro método o atributos para la etiqueta FORM -->
<?= $this->tag->form(['products/search', 'method' => 'get']); ?>
    <label for='q'>Buscar:</label>

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

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

This last code will generate the following HTML:

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

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

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

Same form generated in 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 also provides a form builder to create forms in an object-oriented manner.

Helpers to Generate Form Elements

Phalcon provides a series of helpers to generate form elements such as text fields, buttons and more. The first parameter of each helper is always the name of the element to be generated. When the form is submitted, the name will be passed along with the form data. In a controller you can get these values using the same name by using the getPost() and getQuery() methods on the request object ($this->request).

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

<?php echo $this->tag->textArea(
    [
        'comment',
        'Este es el contenido del textarea',
        'cols' => '6',
        'rows' => 20,
    ]
) ?>

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

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

Sintaxis Volt:


{{ text_field('username') }}

{{ text_area('comment', 'This is the content', 'cols': '6', 'rows': 20) }}

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

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

Making Select Boxes

Generating select boxes (select box) is easy, especially if the related data is stored in PHP associative arrays. The helpers for select elements are Phalcon\Tag::select() and Phalcon\Tag::selectStatic(). Phalcon\Tag::select() has been was specifically designed to work with the Phalcon Models (Phalcon\Mvc\Model), while Phalcon\Tag::selectStatic() can with PHP arrays.

<?php

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

// Usando datos desde un Resultset
echo $this->tag->select(
    [
        'productId',
        $products,
        'using' => [
            'id',
            'name',
        ]
    ]
);

// Usando datos desde un array
echo $this->tag->selectStatic(
    [
        'status',
        [
            'A' => 'Active',
            'I' => 'Inactive',
        ]
    ]
);

The following HTML will generated:

    <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>

You can add an empty option to the generated HTML:

    <?php

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

    // Creando una etiqueta select con una opción vacía
    echo $this->tag->select(
        [
            'productId',
            $products,
            'using'    => [
                'id',
                'name',
            ],
            'useEmpty' => true,
        ]
    );

Produces this 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'");

// Creando una etiqueta Select con una opción vacía y un texto por defecto
echo $this->tag->select(
    [
        'productId',
        $products,
        'using'      => [
            'id',
            'name',
        ],
        'useEmpty'   => true,
        'emptyText'  => 'Por favor, seleccionar una opción...',
        'emptyValue' => '@',
    ]
);
<select id='productId' name='productId'>
    <option value='@'>Por favor, seleccione una opción..</option>
    <option value='101'>Tomato</option>
    <option value='102'>Lettuce</option>
    <option value='103'>Beans</option>
</select>

Volt syntax for above example:


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

Assigning HTML attributes

All the helpers accept an array as their first parameter which can contain additional HTML attributes for the element generated.

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

or using Volt:


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

The following HTML is generated:

<input type='text' name='price' id='price' size='20' maxlength='30'
       placeholder='Ingrese el precio' />

Setting Helper Values

From Controllers

It is a good programming principle for MVC frameworks to set specific values for form elements in the view. You can set those values directly from the controller using Phalcon\Tag::setDefault(). This helper preloads a value for any helpers present in the view. If any helper in the view has a name that matches the preloaded value, it will use it, unless a value is directly assigned on the helper in the view.

<?php

use Phalcon\Mvc\Controller;

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

At the view, a selectStatic helper matches the same index used to preset the value. In this case color:

<?php

echo $this->tag->selectStatic(
    [
        'color',
        [
            'Amarillo' => 'Amarillo',
            'Azul'     => 'Azul',
            'Rojo'     => 'Rojo',
        ]
    ]
);

This will generate the following select tag with the value ‘Blue’ selected:

<select id='color' name='color'>
    <option value='Amarillo'>Amarillo</option>
    <option value='Azul' selected='selected'>Azul</option>
    <option value='Rojo'>Rojo</option>
</select>

From the Request

A special feature that the Phalcon\Tag helpers have is that they keep the values of form helpers between requests. This way you can easily show validation messages without losing entered data.

Specifying values directly

Every form helper supports the parameter ‘value’. With it you can specify a value for the helper directly. When this parameter is present, any preset value using setDefault() or via request will be ignored.

Changing dynamically the Document Title

Phalcon\Tag offers helpers to change dynamically the document title from the controller. The following example demonstrates just that:

<?php

use Phalcon\Mvc\Controller;

class PostsController extends Controller
{
    public function initialize()
    {
        $this->tag->setTitle('Tu sitio Web');
    }

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

    <body>

    </body>
</html>

The following HTML will generated:

<html>
    <head>
        <title>Indice de los Posts - Tu sitio Web</title>
    </head>

    <body>

    </body>
</html>

Static Content Helpers

Phalcon\Tag also provide helpers to generate tags such as script, link or img. They aid in quick and easy generation of the static resources of your application

Images

<?php

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

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

Sintaxis Volt:


{# 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='https://fonts.googleapis.com/css?family=Rosario' type='text/css'>
echo $this->tag->stylesheetLink('https://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');

Sintaxis Volt:


{# Generate <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Rosario' type='text/css'> #}
{{ stylesheet_link('https://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='https://localhost/javascript/jquery.min.js' type='text/javascript'></script>
echo $this->tag->javascriptInclude('https://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');

Sintaxis Volt:


{# Generate <script src='https://localhost/javascript/jquery.min.js' type='text/javascript'></script> #}
{{ javascript_include('https://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 elements - generic HTML helper

Phalcon offers a generic HTML helper that allows the generation of any kind of HTML element. It is up to the developer to produce a valid HTML element name to the helper.

<?php

// Genera
// <canvas id='canvas1' width='300' class='cnvclass'>
// Este es mi lienzo
// </canvas>
echo $this->tag->tagHtml(
    'canvas', 
    [
        'id'    => 'canvas1', 
        'width' => '300', 
        'class' => 'cnvclass',
    ], 
    false, 
    true, 
    true
);
echo 'Este es mi lienzo';
echo $this->tag->tagHtmlClose('canvas');

Sintaxis Volt:


{# 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') }}

Tag Service

Phalcon\Tag is available via the tag service, this means you can access it from any part of the application where the services container is located:

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

You can easily add new helpers to a custom component replacing the service ‘tag’ in the services container:

<?php

use Phalcon\Tag;

class MyTags extends Tag
{
    // ...

    // Crear un nuevo ayudante
    public static function myAmazingHelper($parameters)
    {
        // ...
    }

    // Sobrecargar un método existente
    public static function textField($parameters)
    {
        // ...
    }
}

Then change the definition of the service tag:

<?php

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

Creating your own helpers

You can easily create your own helpers. First, start by creating a new folder within the same directory as your controllers and models. Give it a title that is relative to what you are creating. For our example here, we can call it ‘customhelpers’. Next we will create a new file titled MyTags.php within this new directory. At this point, we have a structure that looks similar to : /app/customhelpers/MyTags.php. In MyTags.php, we will extend the Phalcon\Tag and implement your own helper. Below is a simple example of a custom helper:

<?php

use Phalcon\Tag;

class MyTags extends Tag
{
    /**
     * Generamos un widget para mostrar la etiqueta audio de HTML5
     *
     * @param array
     * @return string
     */
    public static function audioField($parameters)
    {
        // Convirtimos los parámetros en array si no lo son
        if (!is_array($parameters)) {
            $parameters = [$parameters];
        }

        // Determinamos el atributo 'id' y '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;
            }
        }

        // Determinamos el valor de widget,
        // \Phalcon\Tag::setDefault() permite establecer el valor del mismo
        if (isset($parameters['value'])) {
            $value = $parameters['value'];
            unset($parameters['value']);
        } else {
            $value = self::getValue($id);
        }

        // Generamos el código de la etiqueta
        $code = '<audio id="' . $id . '" value="' . $value . '" ';

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

        $code.=' />';

        return $code;
    }
}

After creating our custom helper, we will autoload the new directory that contains our helper class from our index.php located in the public directory.

<?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', // Agregamos la nueva carpeta de ayudantes
        ]
    );

    $loader->register();

    $di = new FactoryDefault();

    // Asignamos la nueva definición de etiquetas para que podamos llamarla
    $di->set(
        'MyTags',
        function () {
            return new MyTags();
        }
    );

    $application = new Application($di);

    $response = $application->handle();

    $response->send();
} catch (PhalconException $e) {
    echo 'Excepción de Phalcon: ', $e->getMessage();
}

Now you are ready to use your new helper within your views:

<body>

    <?php

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

    ?>

</body>

You can also check out Volt a faster template engine for PHP, where you can use a more developer friendly syntax for helpers provided by Phalcon\Tag.