Atributo View


1Visión general

Temma ofrece un atributo que permite especificar la vista usada por un controlador en general y/o por una acción específica.


2Definición de la vista

2.1Definición de la vista: principio

El atributo recibe un primer parámetro opcional null|false|string $view, que se usa para especificar la vista que debe utilizarse.

Este parámetro puede estar vacío o ser nulo; en ese caso, se usa el valor defaultView del archivo etc/temma.php (si este valor no está definido, se usa la vista Smarty).

El parámetro también puede definirse como false, lo que desactiva la renderización de la vista.

Si la cadena pasada como parámetro empieza con el carácter tilde (~), esto significa que el resto de la cadena contiene el nombre de una vista estándar proporcionada por Temma. En ese caso, se añade el prefijo \Temma\Views\.
Por ejemplo: ~Json se interpretará como \Temma\Views\Json


2.2Definición de la vista: ejemplos

Para que todas las acciones de un controlador usen la vista JSON:

use \Temma\Attributes\View as TµView;

#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para que una acción específica use la vista RSS (las demás acciones siguen usando la vista por defecto de forma habitual):

use \Temma\Attributes\View as TµView;

class MyController extends \Temma\Web\Controller {
    // Usa la vista RSS
    #[TµView('~Rss')]
    public function myAction() {
        // ...
    }

    // Usa la vista por defecto
    public function myOtherAction() {
        // ...
    }
}

Para que todas las acciones usen la vista JSON, excepto una acción específica que usa la vista RSS, y otra que usa la vista por defecto:

use \Temma\Attributes\View as TµView;

// define la vista JSON para este controlador
#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    // esta acción usa la vista JSON
    public function firstAction() {
        // ...
    }

    // esta acción también usa la vista JSON
    public function secondAction() {
        // ...
    }

    // esta acción usa la vista RSS
    #[TµView('~Rss')]
    public function thirdAction() {
        // ...
    }

    // esta acción usa la vista por defecto
    #[TµView]
    public function fourthAction() {
        // ...
    }
}

Para desactivar la renderización de la vista en una acción:

use \Temma\Attributes\View as TµView;

class MyController extends \Temma\Web\Controller {
    // no se ejecuta ninguna vista después de esta acción
    #[TµView(false)]
    public function sayHello() {
        print('Hello');
    }
}

3Negociación de contenido

3.1Negociación de contenido: principio

El atributo puede recibir un segundo parámetro opcional null|bool|string|array $negotiation, que se usa para activar la negociación de contenido. Cuando está activada, la vista usada se adapta al tipo de contenido solicitado por el cliente.

Si el parámetro se define como true, el atributo activa automáticamente la vista Smarty, JSON, CSV, RSS o iCal según lo que el navegador envíe en la cabecera Accept.

Si el parámetro es una cadena, debe contener una lista de valores (separados por comas) aceptados en la cabecera Accept (o alias, ver más abajo), para los cuales el atributo activará automáticamente la vista correspondiente.

Si el parámetro es una lista, debe contener valores aceptados en la cabecera Accept (o alias, ver más abajo), para los cuales el atributo activará automáticamente la vista correspondiente.

Si el parámetro es un array asociativo, sus claves deben ser valores aceptados en la cabecera Accept (o alias, ver más abajo), y los valores deben ser nombres de objetos de vista.

Tipo MIME Alias Vista
text/html html Smarty
application/xhtml+xml xhtml Smarty
application/json json JSON
text/csv csv CSV
application/rss+xml rss RSS
text/calendar calendar iCal

3.2Negociación de contenido: ejemplos

Para adaptar automáticamente la vista a la petición del cliente:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: true)]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para enviar JSON si se solicita, y en caso contrario usar la vista por defecto:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: 'json')]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para especificar objetos de vista según lo que solicite el cliente:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: [
    'json'             => '~Json',                  // para JSON, usa la vista JSON proporcionada por Temma
    'application/toml' => '\Toml\TemmaView',        // vista específica para el formato TOML
    'application/pdf'  => '\App\View\PdfGenerator', // vista específica para archivos PDF
])]
class MyController extends \Temma\Web\Controller {
    // ...
}

Para especificar que la vista INI debe usarse por defecto, permitiendo aun así respuestas en JSON o CSV si el cliente las solicita explícitamente:

use \Temma\Attributes\View as TµView;

#[TµView('~Ini', negotiation: 'json, csv')]
class MyController extends \Temma\Web\Controller {
    // ...
}

Es posible recuperar la vista actualmente en uso a partir del objeto Response:

use \Temma\Attributes\View as TµView;

#[TµView(negotiation: 'html, xhtml, json, csv')]
class MyController extends \Temma\Web\Controller {
    public function myAction() {
        $data = /* processing */;
        // comprueba la vista activa
        $view = $this->_response->getView();
        if ($view == '\Temma\Views\Json') {
            $this['json'] = $data;
        } else if ($view == '\Temma\Views\Csv') {
            $this['csv'] = $data;
            $this['filename'] = 'export.csv';
        } else {
            $this['data'] = $data;
        }
    }
}

4Vista condicional

Cuando la vista que debe usarse no puede determinarse de antemano, debe usarse el método _view() del controlador para definirla:

class MyController extends \Temma\Web\Controller {
    public function myAction() {
        if ($this['responseType'] == 'api') {
            // uso explícito de la vista JSON
            $this->_view('~Json');
        }
        // ...
    }
}

Por supuesto, también es posible combinar el atributo con el método _view():

use \Temma\Attributes\View as TµView;

// usa la vista JSON por defecto para este controlador
#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    public function myAction() {
        if ($this['must_use_smarty'] == true) {
            // uso explícito de la vista Smarty
            $this->_view('~Smarty');
        }
        // ...
    }
}