Attribut View


1Présentation

Temma propose un attribut permettant de spécifier la vue utilisée par un contrôleur en général et/ou par une action en particulier.


2Définition de la vue

2.1Définition de la vue : principe

L'attribut prend un premier paramètre optionnel null|false|string $view qui sert à spécifier la vue à utiliser.

Ce paramètre peut être vide ou nul, et dans ce cas c'est la valeur defaultView du fichier etc/temma.php qui est utilisée (si cette valeur n'est pas définie, c'est la vue Smarty qui est utilisée).

Le paramètre peut aussi prendre la valeur false, ce qui a pour effet de désactiver l'utilisation de la vue.

Si la chaîne passée en paramètre commence par le caractère tilde (~), cela veut dire que la suite de la chaîne contient le nom d'une vue standard fournie par Temma. Ainsi, le préfixe \Temma\Views\ lui sera ajouté.
Par exemple : ~Json sera interprété comme \Temma\Views\Json


2.2Définition de la vue : exemples

Pour que toutes les actions d'un contrôleur utilisent la vue JSON :

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

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

Pour qu'une action spécifique utilise la vue RSS (les autres actions utilisant la vue par défaut, comme d'habitude) :

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

class MonControleur extends \Temma\Web\Controller {
    // Utilise la vue RSS
    #[TµView('~Rss')]
    public function monAction() {
        // ...
    }

    // utilise la vue par défaut
    public function monAutreAction() {
        // ...
    }
}

Pour que toutes les actions utilisent la vue Json, sauf une action spécifique qui utilise la vue RSS, et une autre qui utilise la vue par défaut :

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

// définit la vue JSON pour ce contrôleur
#[TµView('~Json')]
class MonControleur extends \Temma\Web\Controller {
    // cette action utilise la vue JSON
    public function premiereAction() {
        // ...
    }

    // cette action utilise aussi la vue JSON
    public function secondeAction() {
        // ...
    }

    // cette action utilise la vue RSS
    #[TµView('~Rss')]
    public function troisiemeAction() {
        // ...
    }

    // cette action utilise la vue par défaut
    #[TµView]
    public function quatriemeAction() {
        // ...
    }
}

Pour qu'aucune vue ne soit utilisée pour une action :

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

class MonControleur extends \Temma\Web\Controller {
    // aucune vue n'est exécutée après cette action
    #[TµView(false)]
    public function ditBonjour() {
        print('Bonjour');
    }
}

3Négociation de contenu

3.1Négociation de contenu : principe

L'attribut peut prendre un second paramètre optionnel null|bool|string|array $negotiation qui sert à activer la négociation de contenu. En l'activant, la vue utilisée sera adaptée au type de contenu demandé par le client.

Si le paramètre est passé à true, l'attribut active automatiquement la vue Smarty, JSON, CSV, RSS ou iCal en fonction de ce que le navigateur a envoyé dans l'en-tête Accept.

Si le paramètre est une chaîne, elle doit contenir une liste de valeurs (séparées par des virgules) acceptées dans l'en-tête Accept (ou des alias − voir plus bas), et pour lesquelles l'attribut activera automatiquement la vue correspondante.

Si le paramètre est une liste (tableau indexé), elle doit contenir des valeurs acceptées dans l'en-tête Accept (ou des alias − voir plus bas), et pour lesquelles l'attribut activera automatiquement la vue correspondante.

Si le paramètre est un tableau associatif, ses clés doivent être des valeurs acceptées dans l'en-tête Accept (ou des alias − voir plus bas), et les valeurs doivent être des noms d'objets de vue.

Type MIME Alias Vue
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.2Négociation de contenu : exemples

Pour adapter automatiquement la vue à la demande du client :

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

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

Pour envoyer du JSON si demandé, et sinon utiliser la vue par défaut :

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

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

Pour spécifier les objets de vue en fonction de ce que demande le client :

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

#[TµView(negotiation: [
    'json'             => '~Json',                  // pour du JSON, on prend la vue JSON fournie par Temma
    'application/toml' => '\Toml\TemmaView',        // vue spécifique pour le format TOML
    'application/pdf'  => '\App\View\PdfGenerator', // vue spécifique pour les fichiers PDF
])]
class MonControleur extends \Temma\Web\Controller {
    // ...
}

Pour spécifier que la vue INI est celle à utiliser par défaut, tout en permettant d'envoyer du JSON ou du CSV si le client le demande de manière préférentielle :

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

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

Il est possible de récupérer la vue utilisée auprès de l'objet Response :

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

#[TµView(negotiation: 'html, xhtml, json, csv')]
class MonControleur extends \Temma\Web\Controller {
    public function monAction() {
        $data = /* traitement */;
        // on vérifie la vue active
        $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;
        }
    }
}

4Vue conditionnelle

Dans le cas où la vue à utiliser ne peut pas être déterminée à l'avance, il faut utiliser la méthode _view() du contrôleur pour définir la vue :

class MonControleur extends \Temma\Web\Controller {
    public function monAction() {
        if ($this['responseType'] == 'api') {
            // utilisation explicite de la vue JSON
            $this->_view('~Json');
        }
        // ...
    }
}

Il est évidemment possible de mélanger l'attribut et la méthode _view() :

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

// utilisation de la vue JSON par défaut pour ce contrôleur
#[TµView('~Json')]
class MonControleur extends \Temma\Web\Controller {
    public function monAction() {
        if ($this['il_faut_utiliser_smarty'] == true) {
            // utilisation explicite de la vue Smarty
            $this->_view('~Smarty');
        }
        // ...
    }
}