Vues¶
Contenus
Introduction¶
Les vues sont responsables de la création des sorties. Elles gèrent tout depuis :
la disposition des pages
des morceaux de sortie d’affichage (comme un pied de page ou une barre d’outils)
des liens individuels et des entrées de formulaire.
des images, js, et css nécessaires pour votre page web
Utiliser les vues¶
À leur niveau le plus élémentaire, les vues par défaut ne sont que des fichiers PHP avec des extraits de html :
<h1>Hello, World!</h1>
En supposant que cette vue se trouve dans /views/default/hello.php
, nous pourrions l’afficher comme ceci :
echo elgg_view('hello');
Pour votre commodité, Elgg est livré avec beaucoup de vues par défaut. Afin de garder les choses gérables, elles sont organisées en sous-répertoires. Elgg gère très bien cette organisation. Par exemple, notre vue simple peut être située dans /views/default/hello/world.php
, auquel cas elle sera appelée comme ceci :
echo elgg_view('hello/world');
Le nom de la vue reflète simplement l’emplacement de la vue dans le répertoire des vues.
Les vues comme modèles (templates)¶
Vous pouvez transmettre des données arbitraires à une vue via le tableau $vars
. Notre vue hello/wordl
pourrait être modifié pour accepter une variable comme ceci :
<h1>Hello, <?= $vars['name']; ?>!</h1>
Dans ce cas, nous pouvons passer un paramètre de nom arbitraire à la vue comme ceci :
echo elgg_view('hello/world', ['name' => 'World']);
qui produirait la sortie suivante :
<h1>Hello, World!</h1>
Avertissement
Les vues ne font aucune sorte d’assainissement automatique de la sortie par défaut. Vous êtes responsable de faire l’assainissement correct vous-même pour prévenir les attaques XSS et similaires.
Les vues en tant qu’actifs pouvant être mis en cache¶
Comme mentionné précédemment, les vues peuvent contenir du JS, des CSS, ou même des images.
Les actifs doivent correspondre à certaines exigences :
Elles ne doivent pas utiliser de paramètre de
$vars
Elles ne doivent pas modifier leur sortie en fonction de l’état global comme
qui est connecté
l’heure de la journée
Elles doivent avoir une extension de fichier valide
Mauvais :
my/cool/template
Bon :
my/cool/template.html
Par exemple, supposons que vous vouliez charger certains CSS sur une page. Vous pouvez définir une vue messtyles.css
, qui ressemblerait à ceci :
/* /views/default/mystyles.css */
.mystyles-foo {
background: red;
}
Note
Omettez l’extension « .php » du nom de fichier et Elgg reconnaîtra automatiquement la vue comme pouvant être mise en cache.
Pour obtenir une URL de ce fichier, vous utiliseriez elgg_get_simplecache_url
:
// Returns "https://mysite.com/.../289124335/default/mystyles.css
elgg_get_simplecache_url('mystyles.css');
Elgg ajoute automatiquement les numéros magiques que vous voyez là pour le cache-busting et définit les entêtes Expires à long terme sur le fichier renvoyé.
Avertissement
Elgg pourrait décider de modifier l’emplacement ou la structure de l’URL retournée dans une version ultérieure pour une raison quelconque, et les numéros d’invalidation du cache (cache-busting) changent à chaque fois que vous videz les caches d’Elgg, de sorte que l’URL exacte n’est pas stable par design.
Avec cela à l’esprit, voici quelques anti-modèles à éviter :
Ne vous fiez pas à la structure/emplacement exacts de cette URL
N’essayez pas de générer les URL vous-même
Ne stockez pas les URL renvoyées dans une base de données
Dans la fonction init de votre plugin, enregistrez le fichier css :
elgg_register_css('mystyles', elgg_get_simplecache_url('mystyles.css'));
Sur la page où vous souhaitez charger le css, appelez :
elgg_load_css('mystyles');
Vues et actifs tierce-partie (assets)¶
La meilleure manière de servir des actifs tiers est par le biais des vues. Toutefois, au lieu de copier/coller manuellement les actifs au bon endroit dans /views/*
, vous pouvez mapper les actifs dans le système de vues via la clef "views"
dans le fichier de configuration elgg-plugin.php
de votre plugin.
La valeur des vues doit être un tableau à 2 dimensions. Le premier niveau mappe un type de vue à une liste de mappage de vues. Le deuxième niveau associe les noms des vues à des chemins de fichiers, absolus ou relatifs au répertoire racine de Elgg.
Si vous ajoutez vos actifs au suivi de version, pointez-les comme ceci :
<?php // mod/example/elgg-plugin.php
return [
// view mappings
'views' => [
// viewtype
'default' => [
// view => /path/from/filesystem/root
'js/jquery-ui.js' => __DIR__ . '/bower_components/jquery-ui/jquery-ui.min.js',
],
],
];
Pour pointer vers les actifs installés avec fxp/composer-asset-plugin
, utilisez les chemins install-root-relative sans le slash initial :
<?php // mod/example/elgg-plugin.php
return [
'views' => [
'default' => [
// view => path/from/install/root
'js/jquery-ui.js' => 'vendor/bower-asset/jquery-ui/jquery-ui.min.js',
],
],
];
Le noyau de Elgg utilise cette fonctionnalité largement, bien que la valeur soit retournée directement à partir de /engine/views.php
.
Note
Vous n’avez pas besoin d’utiliser Bower, Composer Asset Plugin, ou tout autre script pour gérer les actifs de votre plugin, mais nous vous recommandons fortement d’utiliser un gestionnaire de package, car cela rend la mise à niveau tellement plus facile.
En spécifiant des répertoires supplémentaires pour les vues¶
Dans elgg-plugin.php
vous pouvez également spécifier des répertoires à scanner pour les vues. Il suffit de fournir un préfixe de nom de vue se terminant par /
et un chemin de répertoire (comme ci-dessus).
<?php // mod/file/elgg-plugin.php
return [
'views' => [
'default' => [
'file/icon/' => __DIR__ . '/graphics/icons',
],
],
];
Avec ce qui précède, les fichiers trouvés dans le dossier icons
seront interprétés comme des vues. Par exemple, l’affichage file/icon/general.gif
sera créé et mappé à mod/file/graphics/icons/general.gif
.
Note
Il s’agit d’un scan entièrement récursif. Tous les fichiers trouvés seront introduits dans le système de vues.
Plusieurs chemins peuvent partager le même préfixe, il suffit de donner un tableau de chemins :
<?php // mod/file/elgg-plugin.php
return [
'views' => [
'default' => [
'file/icon/' => [
__DIR__ . '/graphics/icons',
__DIR__ . '/more_icons', // processed 2nd (may override)
],
],
],
];
Types de vues (viewtypes)¶
Vous pouvez vous demandez : « Pourquoi /views/default/hello/world.php
au lieu de simplement /views/hello/world.php
? ».
Le sous-répertoire dans /views
détermine le viewtype des vues qu’il contient. Un type de vue correspond généralement au format de sortie des vues.
Le type de vue par défaut est supposé être HTML et d’autres actifs statiques nécessaires pour rendre une page Web réactive dans un navigateur de bureau ou mobile, mais il peut également être :
RSS
ATOM
JSON
HTML optimisé pour mobile
HTML optimisé pour TV
N’importe quel nombre d’autres formats de données
Vous pouvez forcer Elgg à utiliser un type de vue particulier pour afficher la page en définissant la variable d’entrée view
comme ceci : https://monsite.com/?view=rss
.
Vous pourriez également écrire un plugin pour définir ceci automatiquement à l’aide de la fonction elgg_set_viewtype()
. Par exemple, votre plugin peut détecter que la page a été consultée avec la chaîne de navigateur d’un iPhone, et définir le type de vue sur iphone
en appelant :
elgg_set_viewtype('iphone');
Le plugin fournirait probablement également un ensemble de vues optimisées pour ces appareils.
Modification des vues via des plugins¶
Sans modifier le noyau d’Elgg, Elgg offre plusieurs manières de personnaliser quasiement toutes les sorties :
Vous pouvez remplacer une vue, en modifiant complètement le fichier utilisé pour l’afficher.
Vous pouvez étendre une vue en y insérant la sortie d’une autre vue avant ou après.
Vous pouvez modifier les entrées d’une vue avec un hook plugin.
Vous pouvez modifier la sortie d’une vue avec un hook plugin.
Surcharger les vues (override)¶
Les vues dans les répertoires des plugins remplacent toujours les vues du répertoire du noyau ; toutefois, quand les plugins remplacent les vues d’autres plugins, les vues des derniers plugins remplacent celles de précédents.
Par exemple, si nous voulions personnaliser la vue hello/world
pour utiliser un h2
au lieu d’un h1
, nous pourrions créer un fichier à mod/exemple/views/default/hello/world.php
comme ceci :
<h2>Hello, <?= $vars['name']; ?></h2>
Note
Quand vous considérez la maintenance à long terme, la surcharge des vues du noyau et des plugins groupés a un coût : les mises à niveau peuvent apporter des changements dans les vues, et si vous les avez remplacés, vous n’obtiendrez pas ces changements ou devrez les réintégrer dans vos vues.
Vous pouvez plutôt souhaiter modifier l’entrée ou :ref:{la sortie <guides/views#altering-view-output>` de la vue via des hooks plugin.
Note
Elgg met en cache les chemins des vues. Cela signifie que vous devez désactiver le cache système quand vous développez avec des vues. Lorsque vous installez les modifications apportées dans un environnement de production, vous devez vider les caches.
Étendre les vues¶
Il peut y avoir d’autres situations dans lesquelles vous ne voulez pas remplacer l’ensemble de la vue, et plutôt y ajouter un peu plus de contenu au début ou à la fin. Dans Elgg, c’est ce qu’on appelle étendre une vue.
Par exemple, au lieu de remplacer la vue hello/world
, nous pourrions l’étendre comme ceci :
elgg_extend_view('hello/world', 'hello/greeting');
Si le contenu de /views/default/hello/greeting.php
est :
<h2>How are you today?</h2>
Ensuite, chaque fois que nous appelons elgg_view('hello/world');
, nous obtiendrons :
<h1>Hello, World!</h1>
<h2>How are you today?</h2>
Vous pouvez ajouter des choses avant la vue en transmettant au 3ème paramètre une valeur inférieure à 500 :
// appends 'hello/greeting' to every occurrence of 'hello/world'
elgg_extend_view('hello/world', 'hello/greeting');
// prepends 'hello/greeting' to every occurrence of 'hello/world'
elgg_extend_view('hello/world', 'hello/greeting', 450);
Toutes les extensions de vues doivent être enregistrées dans le gestionnaire d’événements init,system
de votre plugin dans start.php
.
Modification de l’entrée d’une vue¶
Il peut être utile de modifier le tableau $vars
d’une vue avant que la vue ne soit rendue.
Depuis 1.11, avant le rendu de chaque vue le tableau $vars
est filtré par le hook plugin ["view_vars", $view_name]
. Ces arguments sont passés à chaque fonction de gestionnaire enregistrée :
$hook
- la chaîne"view_vars"
$view_name
- le nom de la vue (le premier argument est passé àelgg_view()
)$returnvalue
- le tableau modifié$vars
$params
- un tableau contenant :vars
- le tableau original$vars
, inchangéview
- le nom de la vueviewtype
- Le type de vue en train d’être affiché
Exemple de modification des entrées d’une vue¶
Ici, nous allons modifier la limite de pagination par défaut pour la vue des commentaires :
elgg_register_plugin_hook_handler('view_vars', 'page/elements/comments', 'myplugin_alter_comments_limit');
function myplugin_alter_comments_limit($hook, $type, $vars, $params) {
// only 10 comments per page
$vars['limit'] = elgg_extract('limit', $vars, 10);
return $vars;
}
Modification de la sortie d’une vue¶
Parfois, il est préférable de modifier la sortie d’une vue au lieu de la remplacer.
La sortie de chaque vue passe par le hook plugin ["view", $view_name]
avant d’être renvoyé par elgg_view()
. Chaque fonction de gestionnaire enregistrée dispose de ces arguments :
$hook
- la chaîne"view"
$view_name
- le nom de la vue (le premier argument est passé àelgg_view()
)$result
- la sortie modifiée de la vue$params
- un tableau contenant :viewtype
- Le type de vue en train d’être affiché
Pour modifier le résultat de la vue, le gestionnaire n’a qu’à modifier $returnvalue
et à renvoyer une nouvelle chaîne.
Exemple de modification d’affichage d’une vue¶
Ici, nous allons éliminer le fil d’Ariane lorsqu’il ne contient aucun lien.
elgg_register_plugin_hook_handler('view', 'navigation/breadcrumbs', 'myplugin_alter_breadcrumb');
function myplugin_alter_breadcrumb($hook, $type, $returnvalue, $params) {
// we only want to alter when viewtype is "default"
if ($params['viewtype'] !== 'default') {
return $returnvalue;
}
// output nothing if the content doesn't have a single link
if (false === strpos($returnvalue, '<a ')) {
return '';
}
// returning nothing means "don't alter the returnvalue"
}
Remplacement complet du résultat de la vue¶
Vous pouvez pré-définir la sortie de la vue en définissant $vars['__view_output']
. La valeur sera retournée sous forme de chaîne. Les extensions de vue ne seront pas utilisées et le hook view
ne sera pas déclenché.
elgg_register_plugin_hook_handler('view_vars', 'navigation/breadcrumbs', 'myplugin_no_page_breadcrumbs');
function myplugin_no_page_breadcrumbs($hook, $type, $vars, $params) {
if (elgg_in_context('pages')) {
return ['__view_output' => ""];
}
}
Afficher des entités¶
Si vous ne savez pas ce qu’est une entité, commencez par lire cette page.
Le code suivant affiche automatiquement l’entité dans $entity
:
echo elgg_view_entity($entity);
Comme vous le savez après la lecture de l’introduction au modèle de données, toutes les entités ont un type (object, site, user ou group), et éventuellement un sous-type (qui pourrait être n’importe quoi - blog
, forumpost
, banane
).
''elgg_view_entity
va automatiquement rechercher une vue appelée type/subtype
; s’il n’y a pas de sous-type, elle recherchera type/type
. À défaut, elle essaiera type/default
avant de renoncer.
Les flux RSS d’Elgg fonctionnent généralement en affichant la vue object/default
dans le type de vue “rss”.
Par exemple, la vue pour afficher un article de blog peut être object/blog
. La vue pour afficher un utilisateur est user/default
.
Vues des entités partielles et complètes¶
elgg_view_entity
dispose en fait d’un certain nombre de paramètres, bien que seul le tout premier soit nécessaire. Les trois premiers sont :
$entity
- L’entité à afficher''$viewtype
- Le type de vue à afficher (par défaut c’est celui actuellement utilisé, mais il peut être forcé - par exemple pour afficher un extrait RSS dans une page HTML)$full_view
- Affichage d’une version complète de l’entité. (Par défaut false.)
Ce dernier paramètre est transmis à la vue sous le nom de $vars['full_view']
. C’est à vous de déterminer comment vous souhaitez l’utiliser ; le comportement habituel consiste à afficher uniquement des commentaires et des informations de ce type si cela est défini sur true.
Lister des entités¶
Ceci est ensuite utilisé dans les fonctions de liste fournies. Pour afficher automatiquement une liste d’articles de blog (voir le tutoriel complet), vous pouvez appeler :
echo elgg_list_entities([
'type' => 'object',
'subtype' => 'blog',
]);
Cette fonction vérifie s’il y a des entités ; s’il y en a, elle affiche d’abord la vue navigation/pagination
afin d’afficher un moyen de passer d’une page à l’autre. Elle appelle ensuite à plusieurs reprises elgg_view_entity
sur chaque entité avant de renvoyer le résultat.
Notez que elgg_list_entities
permet à l’URL de définir ses options limit
et offset
, aussi définissez-les explicitement si vous avez besoin de valeurs particulières (par exemple si vous ne les utilisez pas pour la pagination).
Elgg sait qu’il peut automatiquement fournir un flux RSS sur les pages qui utilisent elgg_list_entities
. Il initialise le hook de plugin ["head","page"]
(qui est utilisé par l’entête) afin de fournir la découverte automatique RSS, c’est pourquoi vous pouvez voir l’icône RSS orange sur ces pages dans certains navigateurs.
Si votre liste d’entités affiche les propriétaires des entités, vous pouvez améliorer un peu les performances en préchargeant toutes les entités propriétaires :
echo elgg_list_entities([
'type' => 'object',
'subtype' => 'blog',
// enable owner preloading
'preload_owners' => true,
]);
Voyez aussi ces informations de contexte sur la base de données d’Elgg.
Si vous souhaitez afficher un message lorsque la liste ne contient aucun élément, vous pouvez passer un message no_results
. Si vous voulez encore plus de contrôle sur le message no_results
, vous pouvez également passer une Closure (une fonction anonyme).
echo elgg_list_entities([
'type' => 'object',
'subtype' => 'blog',
'no_results' => elgg_echo('notfound'),
]);
Rendu d’une liste avec une autre vue¶
Depuis 1.11, vous pouvez définir une autre vue pour rendre des éléments de liste à l’aide du paramètre item_view
.
Dans certains cas, les vues d’entité par défaut peuvent ne pas convenir à vos besoins. L’utilisation de item_view
vous permet de personnaliser l’apparence, tout en préservant la pagination, le balisage HTML de la liste, etc.
Prenons les deux exemples suivants :
echo elgg_list_entities_from_relationship([
'type' => 'group',
'relationship' => 'member',
'relationship_guid' => elgg_get_logged_in_user_guid(),
'inverse_relationship' => false,
'full_view' => false,
]);
echo elgg_list_entities_from_relationship([
'type' => 'group',
'relationship' => 'invited',
'relationship_guid' => (int) $user_guid,
'inverse_relationship' => true,
'item_view' => 'group/format/invitationrequest',
]);
Dans le premier exemple, nous affichons une liste de groupes dont un utilisateur est membre à l’aide de l’affichage de groupe par défaut. Dans le deuxième exemple, nous voulons afficher une liste de groupes auxquels l’utilisateur a été invité.
Étant donné que les invitations ne sont pas des entités, elles n’ont pas leurs propres vues et ne peuvent pas être répertoriées à l’aide de elgg_list_ *
. Nous fournissons une vue d’élément alternative, qui utilisera l’entité de groupe pour afficher une invitation qui contient un nom de groupe et des boutons pour accéder ou rejeter l’invitation.
Rendu d’une liste en tant que tableau¶
Depuis 2.3, vous pouvez afficher des listes sous forme de tableaux. Définissez $options[`list_type'] = 'table'
et fournissez un tableau d’objets TableColumn comme $options['columns']
. Le service elgg()->table_columns
fournit plusieurs méthodes pour créer des objets de colonnes basés sur des vues (comme page/components/column/*
), des propriétés, ou des méthodes existantes.
Dans cet exemple, nous répertorions les derniers objets mon_plugin
dans un tableau de 3 colonnes : icône de l’entité, nom d’affichage, et date dans un format convivial.
echo elgg_list_entities([
'type' => 'object',
'subtype' => 'my_plugin',
'list_type' => 'table',
'columns' => [
elgg()->table_columns->icon(),
elgg()->table_columns->getDisplayName(),
elgg()->table_columns->time_created(null, [
'format' => 'friendly',
]),
],
]);
Pour plus d’informations sur la façon dont les colonnes sont spécifiées et rendues, consultez la classe Elgg\Views\TableColumn\ColumnFactory
. Vous pouvez ajouter ou remplacer des méthodes de elgg()->table_columns
de diverses façons, en fonction des vues, des propriétés/méthodes sur les éléments ou des fonctions données.