View attribute


1Overview

Temma provides an attribute that allows specifying the view used by a controller in general and/or by a specific action.


2View definition

2.1View definition: principle

The attribute takes a first optional parameter null|false|string $view, which is used to specify the view to use.

This parameter can be empty or null; in that case, the defaultView value from the etc/temma.php file is used (if this value is not defined, the Smarty view is used).

The parameter can also be set to false, which disables view rendering.

If the string passed as a parameter starts with the tilde character (~), this means that the remainder of the string contains the name of a standard view provided by Temma. In that case, the \Temma\Views\ prefix is added.
For example: ~Json will be interpreted as \Temma\Views\Json


2.2View definition: examples

To make all actions of a controller use the JSON view:

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

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

To make a specific action use the RSS view (other actions using the default view as usual):

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

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

    // Uses the default view
    public function myOtherAction() {
        // ...
    }
}

To make all actions use the JSON view, except for one specific action that uses the RSS view, and another that uses the default view:

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

// defines the JSON view for this controller
#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    // this action uses the JSON view
    public function firstAction() {
        // ...
    }

    // this action also uses the JSON view
    public function secondAction() {
        // ...
    }

    // this action uses the RSS view
    #[TµView('~Rss')]
    public function thirdAction() {
        // ...
    }

    // this action uses the default view
    #[TµView]
    public function fourthAction() {
        // ...
    }
}

To disable view rendering for an action:

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

class MyController extends \Temma\Web\Controller {
    // no view is executed after this action
    #[TµView(false)]
    public function sayHello() {
        print('Hello');
    }
}

3Content negotiation

3.1Content negotiation: principle

The attribute can take a second optional parameter null|bool|string|array $negotiation, which is used to enable content negotiation. When enabled, the view used is adapted to the type of content requested by the client.

If the parameter is set to true, the attribute automatically enables the Smarty, JSON, CSV, RSS or iCal view depending on what the browser sends in the Accept header.

If the parameter is a string, it must contain a list of values (comma-separated) accepted in the Accept header (or aliases – see below), for which the attribute will automatically enable the corresponding view.

If the parameter is a list, it must contain values accepted in the Accept header (or aliases – see below), for which the attribute will automatically enable the corresponding view.

If the parameter is an associative array, its keys must be values accepted in the Accept header (or aliases – see below), and the values must be view object names.

MIME type Alias View
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.2Content negotiation: examples

To automatically adapt the view to the client’s request:

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

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

To send JSON if requested, and otherwise use the default view:

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

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

To specify view objects based on what the client requests:

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

#[TµView(negotiation: [
    'json'             => '~Json',                  // for JSON, use the JSON view provided by Temma
    'application/toml' => '\Toml\TemmaView',        // specific view for TOML format
    'application/pdf'  => '\App\View\PdfGenerator', // specific view for PDF files
])]
class MyController extends \Temma\Web\Controller {
    // ...
}

To specify that the INI view should be used by default, while still allowing JSON or CSV responses if the client explicitly requests them:

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

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

It is possible to retrieve the view currently in use from the Response object:

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 */;
        // check the active view
        $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;
        }
    }
}

4Conditional view

When the view to use cannot be determined in advance, the controller’s _view() method must be used to define the view:

class MyController extends \Temma\Web\Controller {
    public function myAction() {
        if ($this['responseType'] == 'api') {
            // explicit use of the JSON view
            $this->_view('~Json');
        }
        // ...
    }
}

It is of course possible to combine the attribute and the _view() method:

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

// use the JSON view by default for this controller
#[TµView('~Json')]
class MyController extends \Temma\Web\Controller {
    public function myAction() {
        if ($this['must_use_smarty'] == true) {
            // explicit use of the Smarty view
            $this->_view('~Smarty');
        }
        // ...
    }
}