Créer un menu  de navigation par taxonomie pour SharePoint Online en utilisant JSOM et Office UI Fabric

Créer un menu de navigation par taxonomie pour SharePoint Online en utilisant JSOM et Office UI Fabric


Le but de cet article est d’expliquer un peu plus en détails les mécanismes utilisés pour la réalisation d’un menu de navigation par taxonomie dans SharePoint Online utilisant Office UI Fabric et le JavaScript Object Model de SharePoint.

Présentation de la solution

Code source


Mise à jour (04/03/2016)

PnP

Cet exemple fait maintenant partie intégrante du repository OfficeDev Pattern & Practices disponible sur GitHub depuis la livraison de Mars 2016:

 OfficeDev/PnP/Components/Core.TaxonomyNavigationComponents

Cela signifie que l’ancien repository sur mon compte personnel devient maintenant obsolète et ne sera plus maintenu davantage. Pour toutes nouvelles mises à jour, se référer directement au nouvel emplacement dans PnP.


Prérequis

Pour pouvoir installer la solution, vous aurez besoin de quelques prérequis:

  • Installez le SDK SharePoint Online Client Components. Il se chargera de déployer les dlls clientes dans la GAC qui seront utilisées par le script de déploiement Utility\Navigation.ps1
  • Installez les cmdlets PowerShell de PnP (v16)
  • Créer une collection de sites de type publication ou bien une avec les fonctionnalités d’infrastructure de publication activées

Procédure de déploiement et utilisation

Simplement suivre la procédure indiquée sur GitHub 😉 dans le README.md.

Résultat final

Une fois la solution déployée dans votre collection de sites, voici ce que vous devriez voir apparaître:

Menu de navigation utilisant Office UI

Responsive par défaut!

Points clés de la solution

Voici une vue d’ensemble de la solution. Pour plus de détails, j’ai essayé le plus possible de documenter à même le code:

  • Ceci est une solution générique et réutilisable que vous pouvez utiliser avec vos propres ensembles de termes.
  • Tous les CSS et la logique des composants sont gérés par Office UI Fabric. Le menu principal supporte ainsi l’affichage mobile par défaut.
  • Le menu de navigation est chargé dynamiquement via le mécanisme de composants Knockout Js depuis des fichiers HTML séparés (expliqué plus loin dans l’article).
  • Les dépendances entre scripts sont gérées avec Require JS évitant ainsi le cauchemar SP.SOD.
  • Le déploiement de la solution est réalisé par PowerShell via les cmdlets PnP et du code CSOM.
  • Le code JavaScript s’appuie beaucoup sur l’utilisation des objets « différés » de jQuery. Cela permet de garder une certaine « platitude » dans les appels asynchrones et éviter des appels imbriqués en cascades rendant le code peu lisible. Cette technique est en effet particulièrement utile dès lors que vous jouez avec le CSOM de SharePoint (executeQueryAsync()).
  • La page maître « Oslo » est utilisée pour l’inclusion de menu de navigation principal.
  • Les menus de navigation s’adaptent à la langue du site.
  • La boîte de recherche est simplement « déplacée » dans le menu par manipulations jQuery.
  • Les URLs conviviales et les liens simples sont supportés ainsi que les URLs conviales et physiques.
  • L’ensemble de termes utilisé pour le menu de navigation ne doit pas être forcément être celui utilisé pour la navigation du site (par exemple dans le cas ou vous souhaitez uniquement des liens simples). Cependant, pour pouvoir bénéficier des URLs conviviales, il convient d’utiliser un ensemble de termes qui réutilise les termes de celui configuré pour la navigation du site (pour que SharePoint comprenne l’URL et ne vous insulte pas avec un 404 « Not found »).
  • La fonctionnalité de « local storage » du navigateur est utilisée pour mettre en cache les liens du menu principal et permettre un chargement plus rapide. Les liens du menu contextuel ainsi que ceux du fil d’Ariane sont calculés à partir du menu principal. La synchronisation entre les différents composants se fait selon le patron de conception Pub/Sub via AmplifyJS.
  • Si vous avez lu l’article Module #2: La navigation, disponible sur ce même blog, vous avez pu constater que la navigation par défaut SharePoint peut poser un certain nombre de problématiques. Parmi elles, l’impossiblité de séparer les sources de données par menus de navigation, SharePoint nous limitant à la navigation gloable et courante (donc pas de pied de page, ni de menu « autre »). Avec cette technique, il est possible de créer autant de menus de navigation que désiré sur une page.
  • Et enfin, étant une solution open source, libre à vous de la récupérer comme base et de l’adapter pour vos projets ou même de l’améliorer!

Gestion des styles et comportements

Pourquoi Office UI Fabric?

Office UI Fabric est une boîte à outils de composants et de styles graphiques réutilisables, destinés à Office et Office 365. Son utilisation permet à vos applications d’adopter les mêmes normes et composants que la plateforme originale, sans avoir à gérer les styles et comportements de base et tout en restant à jour par rapport aux évolutions. Si comme moi, le CSS n’est clairement pas votre spécialité et que vous souhaitez intégrer très rapidement vos applications dans le style de l’outil, Office UI Fabric est fait pour vous! Il vous suffit juste d’utiliser les briques qui vous conviennent.

Office UI Fabric

Le site officiel est disponible ici: http://dev.office.com/fabric. À noter que le projet est avant tout maintenu par des designers de Microsoft ainsi que par la communauté. Le projet GitHub est disponible à cette adresse: https://github.com/OfficeDev/Office-UI-Fabric.

Dans cet exemple, nous utilisons le menu de navigation principal disponible dans la liste des composants d’Office UI Fabric :

Composant de menu de navigation d'Office UI Fabric

L’avantage de ces composants est qu’ils sont, pour la grande majorité, « responsive » par défaut. Cela ce qui signifie que vous n’avez pas à intégrer de framework tiers (tel que « Bootstrap »)  pour gérer l’affichage mobile. Ramené à un contexte SharePoint Online, cela signifie que vous n’avez pas à modifier la page maître.

Sachez également qu’il existe un système de grille disponible dans l’outil (à la manière de Bootstrap).

Inclusion dynamique des composants

Du temps ou le développement « server side » sur SharePoint  était encore à la mode, il existait une technique bien pratique consistant à modulariser l’inclusion de composants dans les gabarits de pages, les pages applicatives et les pages maîtres de SharePoint (typiquement des menus de navigation, etc.). Je veux bien entendu parler des « Delegate Controls » (que j’ai déjà abordé dans un autre article). L’avantage majeur était de pouvoir modulariser le code et ne pas à avoir à inclure tout la structure HTML du composant directement dans les pages permettant ainsi de le réutiliser à plusieurs endroits.

Avec SharePoint Online, cette technique n’est désormais plus possible, même en modifiant la page maître. Il faut désormais passer par la technique dite « d’injection par JavaScript« . Cependant, vous constaterez que dans la plupart des exemples que vous trouverez sur internet concernant cette pratique (et PnP en tête), la structure HTML est bien souvent ajoutée directement par code JavaScript ou bien même dans le code behind d’une page .aspx d’un provider hosted Add-In, ce qui, disons le, n’est ni « clean » ni modulaire à mon sens (et qui, je pense, rebute pas mal de monde).

Pour régler ce problème, j’utilise la fonctionnalité de « component binding » de la librairie JavaScript Knockout JS. Couplée à un « loader » personnalisé (voir exemple #2 dans le lien), celle-ci permet d’injecter dynamiquement des composants dont la structure HTML se trouve dans des fichiers physiques séparés.

ko-logo

Ainsi pour insérer dynamiquement le menu de navigation dans les pages du site, il suffit juste d’inclure la ligne suivante, puis d’appeller ko.applyBindings() uniquement sur cet élément pour que la structure HTML du composant s’insère automatiquement dans la page. Cette technique permet d’obtenir un comportement similaire aux « Delegate Controls » et ainsi améliorer grandement la lisibilité du code:

Gestion des dépendances entre les fichiers JavaScript

Personnellement, dès lors que j’ai a travailler avec SharePoint en JavaScript, l’ordre de chargement des scripts devient vite un véritable casse tête. En effet, de manière générale, lorsque vous utilisez des fonctions du JSOM (JavaScript Object Model) de SharePoint comme la taxonomie, les profils utilisateurs ou autre, il devient nécéssaire de respecter un certain ordre de chargement des scripts pour que tout fonctionne correctement (le plus souvent, une dépendance sur sp.js).

Très honnêtement, je n’ai jamais été un grand adepte du mécanisme « Script On Demand » (SOD) proposé par SharePoint, trouvant la syntaxe bien trop lourde à utiliser. Dans un contexte ou la modification des pages maîtres n’est pas possible, ce qui devient de plus en plus la norme en SharePoint Online (autrement, il est possible de s’en sortir via les  <SharePoint:ScriptLink/>), il n’est donc pas rare d’avoir à faire à ce genre de chose (tiré de l’exemple de menu de navigation de PnP): une suite d’appels imbriqués pour garantir l’ordre de chargement.

Il est évident que ce genre de code, bien que tout à fait valide, devient vite difficile à lire pour des besoins plus complexes. Pour résoudre ce problème, j’utilise donc la librairie Require JS, qui permet justement de créer des applications JavaScript modulaires et de gérer les dépendances entre ceux-ci (une librairie ou fichier externe à votre application pouvant être vu comme un module).

Require JS

De la syntaxe SOD vue précédemment, nous obtenons l’équivalent suivant avec Require JS (pas mal plus lisible non?):

Avec cette configuration, nous nous assurons d’avoir toutes les dépendances chargées lors de l’éxécution du code dans le module de taxonomie:

Un autre avantage de Require JS est que la résolution des modules se fait relativement à un script principal. Ainsi, il suffit d’inclure seulement un seul script dans la page pour que toutes les dépendances soient résolues automatiquement relativement au script principal et selon la hiérarchie de dossiers/scripts dans la bibliothèque de styles du site SharePoint:

Déploiement de la solution

La solution est déployée par PowerShell, à la fois par l’intermédiaire des cmdlets PnP (Pattern & Practices), et aussi par du code CSOM (pour la configuration de l’ensemble de termes en tant que source de navigation du site).

PnP

Voici quelques commentaires sur le déploiement:

  • Tous les scripts *.js et fichiers *.html sont déployés dans la bibliothèque de styles du site racine de la collection de sites via la commande Add-SPOFile. L’avantage de cette commande est qu’elle créée automatiquement la hiérarchie de dossiers si elle n’existe pas déjà. De même utilisez le paramètre « -Checkout » pour…archiver le fichier après ajout (logique hein).
  • Seuls les CSS d’Office UI sont chargés depuis une URL externe.
  • L’injection de JavaScript dans toutes les pages se fait via la commande Add-SPOJavaScriptBlock. Sous le capot, une « Custom Action » est utilisée pour inclure le script dans toutes les pages. Autant vous le dire tout de suite, le paramètre « -Sequence » n’a strictement aucun effet et ne peut pas garantir l’ordre de chargement des fichiers dans la page (préférez donc l’utilisation de RequireJS pour ce point là).
  • Il n’est pas possible de « mélanger » les commandes PnP et du code CSOM. Par exemple si vous utilisez le résultat de la commande Get-SPOContext pour passer un contexte SharePoint dans une méthode CSOM, cela ne fonctionnera pas (vous aurez une erreur de cast d’objet).
  • Lors de l’utilisation du CSOM SharePoint, préférez charger les assemblys depuis la GAC via la commande Add-Type (vous devrez obligatoirement préciser le FQDN de l’assembly). Pour rappel, celles-ci s’installent via le SDK SharePoint Online Client Components.

4 Comments

Add yours
  1. PooLP

    Bonjour,
    Sur un Windows 10 (machine sans SharePoint), il faut apparemment SharePoint Online Management Shell (https://www.microsoft.com/fr-FR/download/details.aspx?id=35588) et il a fallu que je modifie la MasterPage, car DeltaPlaceHolderLeftNavBar était déclaré deux fois, certainement un problème d’injection, sinon tout fonctionne. Il faut à terme corriger l’apparition des menus dans les popup et essayer de trouver une solution pour que le menu par défaut n’apparaisse pas avant son remplacement (un simple display:none dessus devrait régler le problème).
    Bon boulot !

  2. Franck Cornu

    Merci! De mémoire, le SDK de SharePoint Online était suffisant pour déployer la solution depuis un Windows 10, bizarre. Pour la master page, avez-vous bien utilisé celle nommée « Oslo »? Sinon, ravi de savoir que la solution fonctionne dans votre environnement ;)!

  3. PooLP

    J’ai suivi votre article, mais je ne connais pas très bien ces nouvelles méthodes de déploiement, il manquait juste SharePoint Online Management Shell. Pour la MasterPage, c’est bien Oslo. Mais en cherchant un peu, on y arrive ;). Pour ma part, je vais approfondir ce que vous avais fait pour que ça colle aux Branding que je fais habituellement.

  4. Franck Cornu

    Aucun problème! Si vous avez des questions n’hésitez pas! Pour information, je travaille actuellement à remplacer RequireJS par Webpack pour la gestion des dépendances et le packaging de l’application. Par ailleurs, si vous souhaitez optimiser davantage la solution actuelle (dans un contexte de production par exemple), je vous conseille l’utilisation de l’outil r.js (bunlder pour Require JS) http://requirejs.org/docs/optimization.html

+ Leave a Comment