Partager via


Migrer de UserCustomAction vers les extensions SharePoint Framework

De nombreuses solutions d’entreprise basées sur Microsoft 365 et SharePoint Online ont tiré parti de la fonctionnalité CustomAction du site de SharePoint Feature Framework pour étendre l’interface utilisateur des pages. Dans l’interface utilisateur « moderne » actuelle de SharePoint Server 2019 et SharePoint Online, la plupart de ces personnalisations ne sont plus disponibles. Heureusement, avec SharePoint Framework extensions, vous pouvez fournir des fonctionnalités similaires dans l’interface utilisateur « moderne ».

Dans ce didacticiel, vous allez découvrir comment passer des anciennes personnalisations « classiques » au nouveau modèle basé sur les extensions SharePoint Framework.

Tout d’abord, voici les options disponibles lors du développement des extensions de SharePoint Framework :

  • Personnalisateur d’application : étend l’IU native « moderne » de SharePoint en ajoutant des éléments HTML personnalisés et du code côté client à des espaces réservés prédéfinis dans les pages « modernes ». Pour plus d’informations sur les personnalisateurs d’application, consultez Créer votre première extension SharePoint Framework (Hello World 1re partie).
  • Jeu de commandes : ajoutez des éléments de menu BCE personnalisés ou des boutons personnalisés à la barre de commandes d’un affichage de liste pour une liste ou une bibliothèque. Vous pouvez associer n’importe quelle action côté client à ces commandes. Pour plus d’informations sur les jeux de commandes, consultez Créer votre première extension de jeu de commandes ListView.
  • Personnalisateur de champ : personnalisez le rendu d’un champ dans un affichage de liste à l’aide d’éléments HTML personnalisés et de code côté client. Pour plus d’informations sur les personnalisateurs de champ, consultez Créer votre première extension de personnalisateur de champ.

L’option la plus utile dans ce contexte est l’extension Du personnalisateur d’application.

Supposons que vous disposez d’une customAction dans SharePoint Online pour avoir un pied de page personnalisé dans toutes les pages du site.

Dans l’extrait de code suivant, vous pouvez voir le code XML définissant cet élément CustomAction à l’aide de SharePoint Feature Framework.

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction Id="jQueryCDN"
                Title="jQueryCDN"
                Description="Loads jQuery from the public CDN"
                ScriptSrc="https://code.jquery.com/jquery-3.2.1.slim.min.js"
                Location="ScriptLink"
                Sequence="100" />
  <CustomAction Id="spoCustomBar"
                Title="spoCustomBar"
                Description="Loads a script to rendere a custom footer"
                Location="ScriptLink"
                ScriptSrc="SiteAssets/SPOCustomUI.js"
                Sequence="200" />
</Elements>

Comme vous le voyez, le fichier d’éléments de fonctionnalité définit quelques éléments de type CustomAction à inclure dans les pages du site cible : jQuery, chargé via le CDN public, et un fichier JavaScript personnalisé qui affiche le pied de page personnalisé.

Pour faire le tour de la question, vous pouvez voir le code JavaScript qui affiche un pied de page personnalisé. Par souci de simplicité, les éléments de menu sont déjà définis dans le code.

var SPOCustomUI = SPOCustomUI || {};

SPOCustomUI.setUpCustomFooter = function () {
  if ($("#SPOCustomFooter").length)
    return;

  var footerContainer = $("<div>");
  footerContainer.attr("id", "SPOCustomFooter");

  footerContainer.append("<ul>");

  $("#s4-workspace").append(footerContainer);
}

SPOCustomUI.addCustomFooterText = function (id, text) {
  if ($("#" + id).length)
    return;

  var customElement = $("<div>");
  customElement.attr("id", id);
  customElement.html(text);

  $("#SPOCustomFooter > ul").before(customElement);

  return customElement;
}

SPOCustomUI.addCustomFooterLink = function (id, text, url) {
  if ($("#" + id).length)
    return;

  var customElement = $("<a>");
  customElement.attr("id", id);
  customElement.attr("href", url);
  customElement.html(text);

  $("#SPOCustomFooter > ul").append($("<li>").append(customElement));

  return customElement;
}

SPOCustomUI.loadCSS = function (url) {
  var head = document.getElementsByTagName('head')[0];
  var style = document.createElement('link');
  style.type = 'text/css';
  style.rel = 'stylesheet';
  style.href = url;
  head.appendChild(style);
}

SPOCustomUI.init = function (whenReadyDoFunc) {
  // avoid executing inside iframes (used by SharePoint for dialogs)
  if (self !== top) return;

  if (!window.jQuery) {
    // jQuery is needed for Custom Bar to run
    setTimeout(function () { SPOCustomUI.init(whenReadyDoFunc); }, 50);
  } else {
    $(function () {
      SPOCustomUI.setUpCustomFooter();
      whenReadyDoFunc();
    });
  }
}

// The following initializes the custom footer with some fake links
SPOCustomUI.init(function () {
  var currentScriptUrl;

  var currentScript = document.querySelectorAll("script[src*='SPOCustomUI']");
  if (currentScript.length > 0) {
    currentScriptUrl = currentScript[0].src;
  }
  if (currentScriptUrl != undefined) {
    var currentScriptBaseUrl = currentScriptUrl.substring(0, currentScriptUrl.lastIndexOf('/') + 1);
    SPOCustomUI.loadCSS(currentScriptBaseUrl + 'SPOCustomUI.css');
  }

  SPOCustomUI.addCustomFooterText('SPOFooterCopyright', '&copy; 2017, Contoso Inc.');
  SPOCustomUI.addCustomFooterLink('SPOFooterCRMLink', 'CRM', 'CRM.aspx');
  SPOCustomUI.addCustomFooterLink('SPOFooterSearchLink', 'Search Center', 'SearchCenter.aspx');
  SPOCustomUI.addCustomFooterLink('SPOFooterPrivacyLink', 'Privacy Policy', 'Privacy.aspx');
});

Dans l’illustration suivante, vous pouvez voir le résultat de cette action personnalisée dans la page d’accueil d’un site classique.

Pied de page personnalisé dans une page classique

Pour migrer la solution précédente vers l’interface utilisateur « moderne », suivez les étapes ci-dessous.

Créer une nouvelle solution SharePoint Framework

  1. À partir de la console, créez un dossier pour votre projet comme suit :

    md spfx-react-custom-footer
    
  2. Accédez au dossier du projet :

    cd spfx-react-custom-footer
    
  3. Dans le dossier du projet, exécutez le générateur Yeoman pour SharePoint Framework afin de structurer un projet SharePoint Framework :

    yo @microsoft/sharepoint
    
  4. Lorsque vous y êtes invité, entrez les valeurs suivantes (sélectionnez l’option par défaut pour toutes les invites qui ne sont pas mentionnées ci-dessous) :

    • Quel est le nom de votre solution ? : spfx-react-custom-footer
    • Quels packages de base voulez-vous cibler pour votre ou vos composants ? : SharePoint Online uniquement (dernière version)
    • Quel type de composant côté client voulez-vous créer ? : Extension
    • Quel type d’extension côté client créer ? Personnalisateur d’application
    • Quel est le nom de votre personnalisateur de champ ? CustomFooter

    À ce stade, Yeoman installe les dépendances requises et établit la structure des fichiers et dossiers de la solution avec l’extension CustomFooter. Cette opération peut prendre quelques minutes.

  5. Démarrez Visual Studio Code (ou l’éditeur de code de votre choix) et commencez à développer la solution. Pour démarrer Visual Studio Code, vous pouvez exécuter l’instruction suivante.

    code .
    

Définir les nouveaux éléments d’interface utilisateur

Les éléments de l’interface utilisateur du pied de page personnalisé sont affichés à l’aide de React et d’un composant React personnalisé. Vous pouvez créer les éléments d’interface utilisateur de l’exemple de pied de page avec la technologie de votre choix. Dans ce didacticiel, nous utilisons React afin d’utiliser les composants Office UI Fabric pour React.

  1. Ouvrez le fichier ./src/extensions/customFooter/CustomFooterApplicationCustomizer.manifest.json . Copiez la valeur de la propriété id et stockez-la dans un endroit sûr, car vous en aurez besoin plus tard.

  2. Ouvrez le fichier ./src/extensions/customFooter/CustomFooterApplicationCustomizer.ts, puis importez les types PlaceholderContent et PlaceholderName à partir du package @microsoft/sp-application-base.

    Et, au tout début du fichier, ajoutez les import directives pour React.

    Dans l’extrait de code suivant, vous pouvez voir la section des importations du fichier CustomFooterApplicationCustomizer.ts.

    import * as React from 'react';
    import * as ReactDom from 'react-dom';
    
    import { override } from '@microsoft/decorators';
    import { Log } from '@microsoft/sp-core-library';
    import {
      BaseApplicationCustomizer,
      PlaceholderContent,
      PlaceholderName
    } from '@microsoft/sp-application-base';
    import { Dialog } from '@microsoft/sp-dialog';
    
    import * as strings from 'CustomFooterApplicationCustomizerStrings';
    import CustomFooter from './components/CustomFooter';
    
  3. Localisez la définition de la classe CustomFooterApplicationCustomizer et déclarez un nouveau membre privé appelé bottomPlaceholder de type PlaceholderContent | undefined.

  4. Au sein du remplacement de la méthode onInit(), appelez une fonction personnalisée nommée renderPlaceHolders et définissez cette fonction.

    Dans l’extrait de code suivant, vous pouvez voir l’implémentation de la classe du personnalisateur d’application de pied de page personnalisé.

    /** A Custom Action which can be run during execution of a Client Side Application */
    export default class CustomFooterApplicationCustomizer
    extends BaseApplicationCustomizer<ICustomFooterApplicationCustomizerProperties> {
    
      // This private member holds a reference to the page's footer
      private _bottomPlaceholder: PlaceholderContent | undefined;
    
      @override
      public onInit(): Promise<void> {
        Log.info(LOG_SOURCE, `Initialized ${strings.Title}`);
    
        let message: string = this.properties.testMessage;
        if (!message) {
          message = '(No properties were provided.)';
        }
    
        // Call render method for rendering the needed html elements
        this._renderPlaceHolders();
    
        return Promise.resolve();
      }
    
      private _renderPlaceHolders(): void {
    
        // Handling the bottom placeholder
        if (!this._bottomPlaceholder) {
          this._bottomPlaceholder =
            this.context.placeholderProvider.tryCreateContent(PlaceholderName.Bottom);
    
          // The extension should not assume that the expected placeholder is available.
          if (!this._bottomPlaceholder) {
            console.error('The expected placeholder (Bottom) was not found.');
            return;
          }
    
          const element: React.ReactElement<{}> = React.createElement(CustomFooter);
    
          ReactDom.render(element, this._bottomPlaceholder.domElement);
        }
      }
    }
    

    La méthode renderPlaceHolders() recherche l’espace réservé de type Bottom et restitue son contenu s’il existe. En fait, à la toute fin de la renderPlaceHolders() méthode, le code crée une nouvelle instance d’un CustomFooter composant React et la restitue dans l’espace réservé du bas des pages (autrement dit, où le pied de page doit être affiché).

    Remarque

    Le composant React est l’alternative de remplacement, dans l’interface utilisateur « moderne », au fichier JavaScript dans le modèle « classique ». Bien entendu, vous pouvez toujours restituer la totalité du pied de page en utilisant du code JavaScript et en réutilisant la plus grande partie du code que vous avez déjà. Toutefois, il est préférable d’envisager une mise à niveau de l’implémentation, non seulement pour des questions technologiques, mais également pour des questions de code.

  5. Ajoutez un nouveau dossier nommé components dans le dossier src/extensions/customFooter .

  6. Créez un fichier dans le nouveau dossier et nommez-le CustomFooter.tsx.

    Ajoutez le code suivant à ce fichier :

    import * as React from 'react';
    import { CommandButton } from 'office-ui-fabric-react/lib/Button';
    
    export default class CustomFooter extends React.Component<{}, {}> {
      public render(): React.ReactElement<{}> {
        return (
          <div className={`ms-bgColor-neutralLighter ms-fontColor-white`}>
            <div className={`ms-bgColor-neutralLighter ms-fontColor-white`}>
              <div className={`ms-Grid`}>
                <div className="ms-Grid-row">
                  <div className="ms-Grid-col ms-sm2 ms-md2 ms-lg2">
                    <CommandButton
                        data-automation="CopyRight"
                        href={`CRM.aspx`}>&copy; 2017, Contoso Inc.</CommandButton>
                  </div>
                  <div className="ms-Grid-col ms-sm2 ms-md2 ms-lg2">
                    <CommandButton
                            data-automation="CRM"
                            iconProps={ { iconName: 'People' } }
                            href={`CRM.aspx`}>CRM</CommandButton>
                  </div>
                  <div className="ms-Grid-col ms-sm2 ms-md2 ms-lg2">
                    <CommandButton
                            data-automation="SearchCenter"
                            iconProps={ { iconName: 'Search' } }
                            href={`SearchCenter.aspx`}>Search Center</CommandButton>
                  </div>
                  <div className="ms-Grid-col ms-sm2 ms-md2 ms-lg2">
                    <CommandButton
                        data-automation="Privacy"
                        iconProps={ { iconName: 'Lock' } }
                        href={`Privacy.aspx`}>Privacy Policy</CommandButton>
                  </div>
                  <div className="ms-Grid-col ms-sm4 ms-md4 ms-lg4"></div>
                </div>
              </div>
            </div>
          </div>
        );
      }
    }
    

    Ce document n’a pas pour but de vous apprendre à écrire un composant React. Notez les import instructions au début, où le composant importe React, et le CommandButton composant React à partir de la bibliothèque de composants Office UI Fabric.

    Dans la méthode render() du composant, la sortie du CustomFooter est définie avec plusieurs instances du composant CommandButton pour les liens présents dans le pied de page. Toutes les sorties HTML sont comprises dans une disposition en grille d’Office UI Fabric.

    Remarque

    Pour obtenir plus d’informations sur la disposition en grille d’Office UI Fabric, consultez la page relative à la disposition réactive.

    Dans l’illustration suivante, vous pouvez voir le résultat obtenu.

    Le pied de page personnalisé restitué dans un site « moderne »

Tester la solution en mode de débogage

  1. Revenez à la fenêtre de la console et exécutez la commande suivante pour créer la solution et lancer le serveur local Node.js qui l’hébergera.

    gulp serve --nobrowser
    
  2. Maintenant, ouvrez votre navigateur préféré et accédez à une page « moderne » de n’importe quel site d’équipe « moderne ». À présent, ajoutez les paramètres de chaîne de requête suivants à l’URL de la page.

    ?loadSPFX=true&debugManifestsFile=https://localhost:4321/temp/manifests.js&customActions={"82242bbb-f951-4c71-a978-80eb8f35e4c1":{"location":"ClientSideExtension.ApplicationCustomizer"}}
    

    Dans la chaîne de requête ci-dessus, remplacez le GUID par la valeur id enregistrée précédemment à partir du fichier CustomFooterApplicationCustomizer.manifest.json.

    Notez que, lors de l’exécution de la demande de page, une boîte de message d’avertissement intitulée « Autoriser scripts de débogage ? » apparaît pour vous demander l’autorisation d’exécuter du code à partir de l’hôte local pour des raisons de sécurité. Si vous souhaitez déboguer localement et tester la solution, vous devez autoriser l’action « Charger les scripts de débogage ».

    Remarque

    Par ailleurs, vous pouvez créer des entrées de configuration du serveur dans le fichier config/serve.json dans votre projet pour automatiser la création des paramètres de chaîne de requête de débogage comme indiqué dans ce document : Débogage de solutions SharePoint Framework sur des pages SharePoint modernes

Empaqueter et héberger la solution

Si vous êtes satisfait du résultat, vous êtes maintenant prêt à empaqueter la solution et à l’héberger dans une infrastructure d’hébergement réelle.

Avant de générer l’offre groupée et le package, vous devez déclarer un fichier XML d’infrastructure de fonctionnalité afin de configurer l’extension.

Vérification des éléments d’infrastructure de fonctionnalité

  1. Dans l’éditeur de code, ouvrez le fichier /sharepoint/assets/elements.xml. Dans l’extrait de code suivant, vous pouvez voir à quoi le fichier doit ressembler.

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
      <CustomAction
          Title="CustomFooter"
          Location="ClientSideExtension.ApplicationCustomizer"
          ClientSideComponentId="82242bbb-f951-4c71-a978-80eb8f35e4c1">
      </CustomAction>
    </Elements>
    

    Comme vous le voyez, il rappelle le fichier SharePoint Feature Framework que nous avons vu dans le modèle « classique », mais il utilise l’attribut ClientSideComponentId afin de faire référence à l’id de l’extension personnalisée. Vous pouvez également ajouter un ClientSideComponentProperties attribut, si vous devez fournir des paramètres personnalisés à l’extension, ce qui n’est pas le cas dans ce didacticiel.

  2. Ouvrez le dossier ./config/package-solution.json de la solution. Dans le fichier, vous pouvez voir qu’il existe une référence au fichier elements.xml dans la assets section .

    {
      "$schema": "https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
      "solution": {
        "name": "spfx-react-custom-footer-client-side-solution",
        "id": "911728a5-7bde-4453-97b2-2eba59277ed3",
        "version": "1.0.0.0",
        "features": [
        {
          "title": "Application Extension - Deployment of custom action.",
          "description": "Deploys a custom action with ClientSideComponentId association",
          "id": "f16a2612-3163-46ad-9664-3d3daac68cff",
          "version": "1.0.0.0",
          "assets": {
            "elementManifests": [
              "elements.xml"
            ]
          }
        }]
      },
      "paths": {
        "zippedPackage": "solution/spfx-react-custom-footer.sppkg"
      }
    }
    

Regrouper, empaqueter et déployer la solution

Ensuite, vous devez regrouper et empaqueter l’offre groupée de solutions dans le catalogue d’applications. Pour réaliser cette tâche, procédez comme suit.

Préparez et déployez la solution pour le client SharePoint Online :

  1. Exécutez la tâche suivante pour regrouper votre solution. Cette procédure crée une version Release de votre projet :

    gulp bundle --ship
    
  2. Exécutez la tâche suivante pour créer un package pour votre solution. Cette commande crée un package *.sppkg dans le dossier sharepoint/solution .

    gulp package-solution --ship
    
  3. Chargez ou glissez-déplacez le nouveau package de solution côté client dans le catalogue d’applications de votre client, puis sélectionnez le bouton Déployer.

Installer et exécuter la solution

  1. Ouvrez le navigateur et accédez à n’importe quel site cible « moderne ».

  2. Accédez à la page Contenu du site, puis ajoutez une nouvelle application.

  3. Installez une nouvelle application De votre organisation pour parcourir les solutions disponibles dans le catalogue des applications.

  4. Sélectionnez la solution appelée spfx-react-custom-footer-client-side-solution et installez-la sur le site cible.

    Ajouter une application d’interface utilisateur pour ajouter la solution à un site

  5. Une fois l’installation de l’application terminée, actualisez la page ou accédez à la page d’accueil du site. Vous devez voir le pied de page personnalisé en action.

Profitez de votre nouveau pied de page personnalisé créé à l’aide des extensions SharePoint Framework !

Voir aussi