Vues

Introduction

Les vues sont responsables de la création des sorties. Elles gèrent tout depuis :

  • la disposition / mise en page 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 un bon nombre de vues par défaut. Afin de garder les choses gérables, elles sont organisées en sous-répertoires. Elgg gère parfaitement 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/world 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 :

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 par vous-même l’assainissement correct 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, du CSS, ou même des images.

Les actifs doivent correspondre à certaines exigences :

  • Elles ne doivent pas utiliser de paramètre de $vars

  • Ils ne doivent pas modifier leur sortie en fonction de l’état global, tels que

    • qui est connecté

    • l’heure de la journée

  • Ils 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 mystyles.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 vers 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 de 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 URLs vous-même

  • Ne stockez pas les URLs renvoyées dans une base de données

Sur la page où vous souhaitez charger le css, appelez :

elgg_require_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, soit absolus, soit 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__ . '/node_modules/components-jqueryui/jquery-ui.min.js',
        ],
    ],
];

Pour pointer vers les actifs installés avec composer, utilisez les chemins install-root-relative en omettant le slash initial :

<?php // mod/example/elgg-plugin.php
return [
    'views' => [
        'default' => [
            // view => path/from/install/root
            'js/jquery-ui.js' => 'vendor/npm-asset/components-jqueryui/jquery-ui.min.js',
        ],
    ],
];

Le noyau de Elgg utilise cette fonctionnalité largement, cependant la valeur est retournée directement à partir de /engine/views.php.

Note

Vous n’avez pas besoin d’utiliser NPM, Composer Asset Plugin, ou n’importe quel autre script pour gérer les actifs de votre plugin, mais nous vous recommandons fortement d’utiliser un gestionnaire de package quel qu’il soit, car cela facilite grandement la mise à niveau.

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, la vue file/icon/general.gif sera créée et mappée vers 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 avoir /views/default/hello/world.php au lieu de simplement /views/hello/world.php ? ».

Le sous-répertoire dans /views détermine le type de vue, ou 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

  • De nombreux 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://mysite.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.

Modifier des vues via des plugins

Sans modifier le noyau de Elgg, Elgg offre plusieurs manières de personnaliser quasiment toutes les sorties :

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 des 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 inclus a un coût : les mises à niveau peuvent apporter des changements dans les vues, et si vous les avez remplacées, vous n’obtiendrez pas ces changements ou devrez les réintégrer dans vos vues.

Vous souhaiterez peut-être plutôt modifier l’entrée input ou la sortie output de la vue via des événements.

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 vue doivent être enregistrées dans le elgg-plugin.php de votre plugin.

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

Avant le rendu de chaque vue, le tableau $vars est filtré par l” événement ["view_vars", $view_name]. Chaque fonction de gestionnaire enregistrée reçoit ces arguments :

  • $event - 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 vue

    • viewtype - 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_event_handler('view_vars', 'page/elements/comments', 'myplugin_alter_comments_limit');

function myplugin_alter_comments_limit(\Elgg\Event $event) {
    $vars = $event->getValue();

    // 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 est exécutée via l”événement ["view", $view_name] avant d’être renvoyée par elgg_view(). Chaque fonction de gestionnaire enregistrée reçoit ces arguments :

  • $event - 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 rendu de la vue, le gestionnaire n’a qu’à modifier $returnvalue et renvoyer une nouvelle chaîne.

Exemple de modification de la sortie d’une vue

Ici, nous allons éliminer le fil d’Ariane lorsqu’il ne contient aucun lien.

elgg_register_event_handler('view', 'navigation/breadcrumbs', 'myplugin_alter_breadcrumb');

function myplugin_alter_breadcrumb($event, $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 === elgg_strpos($returnvalue, '<a ')) {
        return '';
    }

    // returning nothing means "don't alter the returnvalue"
}

Remplacer complètement le rendu d’une vue

Vous pouvez prédéfinir la sortie de la vue en définissant $vars['__view_output']. La valeur sera renvoyée sous forme de chaîne. Les extensions de vue ne seront pas utilisées et l’événement view ne sera pas déclenché.

elgg_register_event_handler('view_vars', 'navigation/breadcrumbs', 'myplugin_no_page_breadcrumbs');

function myplugin_no_page_breadcrumbs(\Elgg\Event $event) {
    if (elgg_in_context('pages')) {
        return ['__view_output' => ""];
    }
}

Note

Pour plus de facilité d’utilisation, vous pouvez également utiliser un callback d’événement par défaut déjà existant pour bloquer la sortie \Elgg\Values::preventViewOutput

Affichage 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 de Elgg fonctionnent généralement en affichant la vue object/default du 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 partielle et complète des entités

elgg_view_entity dispose en fait de plusieurs 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 celui qui est utilisé actuellement, mais il peut être forcé - par exemple pour afficher un extrait RSS dans une page HTML)

  • $full_view - Détermine s’il faut afficher la version complète de l’entité. (Par défaut à true.)

Ce dernier paramètre est transmis à la vue via $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 successivement 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 fournir automatiquement un flux RSS sur les pages qui utilisent elgg_list_entities. Il initialise l’événement ["head","page"] (qui est utilisé par l’entête) afin de fournir une découverte automatique RSS, c’est pourquoi vous pouvez voir l’icône RSS orange sur ces pages dans certains navigateurs.

Les listes d’entités tenteront par défaut de charger les propriétaires des entités et les propriétaires de leur conteneur. Si vous voulez éviter ce comportement, vous pouvez le désactiver.

echo elgg_list_entities([
    'type' => 'object',
    'subtype' => 'blog',

    // disable owner preloading
    'preload_owners' => false,
]);

Voyez aussi ces informations de contexte sur la base de données de Elgg.

Si vous souhaitez afficher un message lorsque la liste ne contient pas d’élément à répertorier, vous pouvez transmettre un message avec no_results, ou true pour le message par défaut. Si vous voulez encore plus de contrôle sur le message le message no_results peut é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

Vous pouvez définir une autre vue pour afficher 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([
    'type' => 'group',
    'relationship' => 'member',
    'relationship_guid' => elgg_get_logged_in_user_guid(),
    'inverse_relationship' => false,
    'full_view' => false,
]);
echo elgg_list_entities([
    '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 la vue de groupe par défaut. Dans le deuxième exemple, nous voulons afficher une liste de groupes dans lesquels 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 sous forme de tableau

Depuis Elgg 2.3, vous pouvez afficher les listes sous forme de tableaux. Définissez $options[`list_type'] = 'table' et fournissez un tableau d’objets TableColumn dans $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.

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 la 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',
        ]),
    ],
]);

Consultez la classe Elgg\Views\TableColumn\ColumnFactory pour plus d’informations sur la façon dont les colonnes sont spécifiées et rendues. Vous pouvez ajouter ou remplacer les 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.

Icônes

Elgg supporte deux types d’icônes : les icônes génériques qui aident pour le style des pages (par exemple, afficher l’icône de suppression) et les icônes des Entités (par exemple l’avatar d’un utilisateur).

Icônes génériques

À partir de Elgg 2.0, les icônes génériques sont basées sur la bibliothèque FontAwesome. Vous pouvez obtenir n’importe laquelle des icônes prises en charge en appelant elgg_view_icon($icon_name, $vars); où :

  • $icon_name est le nom de l’icône FontAwesome (sans fa-) par exemple user

  • $vars est facultatif, par exemple vous pouvez définir une classe supplémentaire

elgg_view_icon() appelle la vue output/icon avec le nom d’icône donné et affiche toutes les classes correctes pour restituer l’icône FontAwesome. Si vous souhaitez remplacer une icône par une autre icône, vous pouvez écrire un événement view_vars, output/icon pour remplacer le nom de l’icône par votre remplacement.

A des fins de rétro-compatibilité, certains anciens noms d’icônes Elgg sont traduits en une icône FontAwesome correspondante.

Icônes des entités

Pour afficher une icône appartenant à une Entité appelez elgg_view_entity_icon($entity, $size, $vars); où :

  • $entity est l”ElggEntity dont vous voulez afficher l’icône

  • $size est la dimension demandée. Par défaut Elgg supporte large, medium, small, tiny et topbar (master est également disponible, mais ne l’utilisez pas)

  • $vars pour passer des informations additionnelles à la vue de l’icône

elgg_view_entity_icon() appelle une vue dans l’ordre :

  • icon/<type>/<subtype>

  • icon/<type>/default

  • icon/default

Ainsi si vous souhaitez personnaliser la mise en page de l’icône, vous pouvez surcharger la vue correspondante.

Un exemple d’affichage d’un avatar utilisateur est

// get the user
$user = elgg_get_logged_in_user_entity();

// show the small icon
echo elgg_view_entity_icon($user, 'small');

// don't add the user_hover menu to the icon
echo elgg_view_entity_icon($user, 'small', [
        'use_hover' => false,
]);