Show Menu
SUJETS×

Plan directeur d’applications sur une seule page (SPA)

Pour permettre à l’auteur d’utiliser l’éditeur d’applications monopages AEM de modifier le contenu d’une application monopages, les exigences que l’application doit respecter sont décrites dans ce document.
La fonctionnalité Editeur d’application monopage (SPA) requiert AEM 6.4 Service Pack 2 ou version ultérieure.
L’éditeur d’applications monopages est la solution recommandée pour les projets qui nécessitent un rendu côté client basé sur la structure d’applications monopages (par exemple, Réagir ou Angular).

Présentation

Ce document décrit le contrat général que toute structure d’application d’une seule page doit respecter (c’est-à-dire le type de couche de prise en charge d’AEM) afin de mettre en oeuvre des composants d’application d’une seule page modifiables dans AEM.
Les exigences suivantes sont indépendantes de la structure. Si ces exigences sont satisfaites, un calque spécifique à l’infrastructure, constitué de modules, de composants et de services, peut être fourni.
Ces exigences sont déjà satisfaites pour les structures Réagir et Angular dans AEM. Les exigences de ce plan directeur ne sont pertinentes que si vous souhaitez mettre en oeuvre une autre structure destinée à être utilisée avec AEM.
Bien que les fonctionnalités d’application d’une seule page soient indépendantes de la structure, seules les structures React et Angular sont actuellement prises en charge.
Pour permettre à l’auteur d’utiliser l’éditeur de page AEM pour modifier les données exposées par une structure d’application d’une seule page, un projet doit être en mesure d’interpréter la structure du modèle représentant la sémantique des données stockées pour une application dans le référentiel AEM. Pour atteindre cet objectif, deux bibliothèques indépendantes du cadre sont fournies : le PageModelManager et le ComponentMapping .

PageModelManager

La PageModelManager bibliothèque est fournie sous la forme d'un package NPM à utiliser par un projet SPA. Il accompagne l’application sur une seule page et fait office de gestionnaire de modèles de données.
Au nom de l’application sur une seule page, il extrait la récupération et la gestion de la structure JSON qui représente la structure de contenu proprement dite. Il est également responsable de la synchronisation avec l’application d’une seule page pour lui indiquer quand elle doit effectuer un nouveau rendu de ses composants.
Lors de l’initialisation de l’application PageModelManager , la bibliothèque charge d’abord le modèle racine fourni de l’application (par l’intermédiaire d’un paramètre, d’une propriété meta ou de l’URL active). Si la bibliothèque identifie que le modèle de la page active ne fait pas partie du modèle racine qu’elle récupère et l’inclut comme modèle de page enfant.

ComponentMapping

The ComponentMapping module is provided as an NPM package to the front-end project. Il stocke les composants frontaux et permet à l’application d’une seule page d’associer les composants frontaux aux types de ressources AEM. Ceci active une résolution dynamique des composants lors de l’analyse du modèle JSON de l’application.
Chaque élément présent dans le modèle contient un :type champ qui expose un type de ressource AEM. Une fois monté, le composant frontal peut être rendu à l’aide du fragment de modèle reçu des bibliothèques sous-jacentes.

Mappage du modèle dynamique au composant

Pour plus d’informations sur la façon dont le mappage du modèle dynamique avec les composants se produit dans le SDK SPA Javascript pour AEM, voir l’article Mappage du modèle dynamique avec les composants pour les applications monopages .

Couche spécifique au cadre

Une troisième couche doit être mise en oeuvre pour chaque structure frontale. Cette troisième bibliothèque est chargée d'interagir avec les bibliothèques sous-jacentes et de fournir une série de points d'entrée bien intégrés et faciles à utiliser pour interagir avec le modèle de données.
Le reste de ce document décrit les exigences de cette couche spécifique de cadre intermédiaire et aspire à être indépendante du cadre. En respectant les exigences suivantes, une couche spécifique au cadre peut être fournie pour que les composants du projet interagissent avec les bibliothèques sous-jacentes chargées de la gestion du modèle de données.

Concepts généraux

Modèle de page

La structure de contenu de la page est stockée dans AEM. Le modèle de la page est utilisé pour mapper et instancier les composants de l’application d’une seule page (SPA). Les développeurs d’applications d’une seule page créent des composants SPA qu’ils mappent sur des composants AEM. Pour ce faire, ils utilisent le type de ressource (ou le chemin d’accès au composant AEM) comme clé unique.
Les composants de l’application d’une seule page doivent être synchronisés avec le modèle de page et être mis à jour en fonction des modifications apportées à son contenu. Un modèle qui a recours à des composants dynamiques doit être utilisé pour instancier des composants à la volée, suivant la structure de modèle de page fournie.

Champs Meta

The page model leverages the JSON Model Exporter, which is itself based on the Sling Model API. Les modèles sling exportables exposent la liste de champs suivante afin de permettre aux bibliothèques sous-jacentes d’interpréter le modèle de données :
  • :type : Type de la ressource AEM (par défaut = type de ressource)
  • :children : Enfants hiérarchiques de la ressource actuelle. Les enfants ne font pas partie du contenu interne de la ressource actuelle (se trouvent sur les éléments représentant une page)
  • :hierarchyType : Type hiérarchique d'une ressource. Actuellement, le type de page PageModelManager est pris en charge
  • :items : Ressources de contenu enfant de la ressource actuelle (structure imbriquée, présente uniquement sur les conteneurs)
  • :itemsOrder : liste ordonnée des enfants. L’objet de mappage JSON ne garantit pas l’ordre de ses champs. En disposant à la fois de la carte et de la baie actuelle, le consommateur de l'API bénéficie des avantages des deux structures.
  • :path : Chemin d’accès au contenu d’un élément (présent sur les éléments représentant une page)

Module spécifique au cadre

La séparation des préoccupations aide à faciliter la mise en oeuvre du projet. Par conséquent, un package spécifique au régime npm devrait être fourni. Ce package est chargé d’agréger et d’exposer les modules, services et composants de base. Ces composants doivent encapsuler la logique de gestion des modèles de données et fournir un accès aux données attendues par le composant du projet. Le module est également chargé d'exposer de façon transitoire les points d'entrée utiles des bibliothèques sous-jacentes.
Pour faciliter l’interopérabilité des bibliothèques, Adobe conseille au module spécifique à la structure de regrouper les bibliothèques suivantes. Si nécessaire, la couche peut encapsuler et adapter les API sous-jacentes avant de les exposer au projet.

Mises en œuvre

Angular

module npm : à venir

Services principaux et composants

Les entités suivantes devraient être mises en oeuvre conformément aux lignes directrices spécifiques à chaque cadre. En fonction de l'architecture du cadre, la mise en oeuvre peut varier considérablement, mais les fonctionnalités décrites doivent être fournies.

Fournisseur de modèles

Les composants du projet doivent déléguer l'accès aux fragments d'un modèle à un fournisseur de modèles. Le fournisseur de modèles est alors chargé d'écouter les modifications apportées au fragment spécifié du modèle et de renvoyer le modèle mis à jour au composant délégué.
Pour ce faire, le Fournisseur de modèles doit s'inscrire au PageModelManager . Ensuite, lorsqu’une modification se produit, elle reçoit et transmet les données mises à jour au composant de délégation. Par convention, la propriété mise à la disposition du composant de délégation qui transportera le fragment de modèle est nommée cqModel . L’implémentation est libre de fournir cette propriété au composant mais doit prendre en compte des aspects tels que l’intégration à l’architecture de la structure, la découverte et la facilité d’utilisation.

Le décorateur HTML du composant

Le décorateur de composants est chargé de décorer le code HTML extérieur de l’élément de chaque instance de composant avec une série d’attributs de données et de noms de classe attendus par l’éditeur de page.

Déclaration des composants

Les métadonnées suivantes doivent être ajoutées à l'élément HTML externe produit par le composant du projet. Ils permettent à l’éditeur de page de récupérer la configuration de modification correspondante.
  • data-cq-data-path : Chemin d’accès à la ressource relative à la variable jcr:content

Modification de la déclaration de capacité et de l’espace réservé

Les métadonnées et les noms de classe suivants doivent être ajoutés à l'élément HTML externe produit par le composant du projet. Ils permettent à l’éditeur de page d’accéder aux fonctionnalités liées à l’offre.
  • cq-placeholder : Nom de classe qui identifie l'espace réservé pour un composant vide
  • data-emptytext : Libellé à afficher par l’incrustation lorsqu’une instance de composant est vide
Espace réservé pour les composants vides
Chaque composant doit être étendu avec une fonctionnalité qui décorera l’élément HTML externe avec des attributs de données et des noms de classe spécifiques aux espaces réservés et aux incrustations connexes lorsque le composant est identifié comme vide.
A propos de l'état vide d'un composant
  • Le composant est-il logiquement vide ?
  • Quel doit être l’étiquette affichée par l’incrustation lorsque le composant est vide ?

Conteneur

Un conteneur est un composant conçu pour contenir des composants enfants et en effectuer le rendu. Pour ce faire, le conteneur effectue une itération sur les propriétés :itemsOrder , :items et :children des propriétés de son modèle.
Le conteneur obtient dynamiquement les composants enfants à partir du magasin de la ComponentMapping bibliothèque. Le conteneur étend ensuite le composant enfant avec les fonctionnalités du fournisseur de modèles et l'instancie finalement.

Page

Le Page composant étend le Container composant. Un conteneur est un composant destiné à contenir et à générer des composants enfants, y compris des pages enfants. Pour ce faire, le conteneur effectue une itération sur les propriétés :itemsOrder , :items et :children des propriétés de son modèle. Le Page composant obtient dynamiquement les composants enfants à partir du magasin de la bibliothèque ComponentMapping . Il Page est responsable de l’instanciation des composants enfants.

Grille réactive

Le composant Grille réactive est un conteneur. Il contient une variante spécifique du fournisseur de modèles représentant ses colonnes. La grille réactive et ses colonnes sont chargées de décorer l'élément HTML externe du composant du projet avec les noms de classe spécifiques contenus dans le modèle.
Le composant de grille réactive doit être prémappé à son homologue AEM, car ce composant est complexe et rarement personnalisé.

Champs de modèle spécifiques

  • gridClassNames: Noms de classe fournis pour la grille dynamique
  • columnClassNames: Noms de classe fournis pour la colonne réactive

Espace réservé de la grille réactive

Le composant SPA est mappé à un conteneur graphique tel que la grille réactive et doit ajouter un espace réservé enfant virtuel lors de la création du contenu. When the content of the SPA is being authored by the Page Editor, that content is embedded into the editor using an iframe and the data-cq-editor attribute is added to the document node of that content. Lorsque l’ data-cq-editor attribut est présent, le conteneur doit inclure un HTMLElement pour représenter la zone avec laquelle l’auteur interagit lors de l’insertion d’un nouveau composant dans la page.
Par exemple :
<div data-cq-data-path={"path/to/the/responsivegrid/*"} className="new section aem-Grid-newComponent"/>

Les noms de classe utilisés dans l’exemple sont actuellement requis par l’éditeur de page.
  • "new section"  : indique que l’élément en cours est l’espace réservé du conteneur.
  • "aem-Grid-newComponent" : Normalise le composant pour la création de mise en page.

Mappage de composant

La Component Mapping bibliothèque sous-jacente et sa MapTo fonction peuvent être encapsulées et étendues afin de fournir les fonctionnalités relatives à la configuration d'édition fournie avec la classe de composants actuelle.
const EditConfig = {
 
    emptyLabel: 'My Component',
 
    isEmpty: function() {
        return !this.props || !this.props.cqModel || this.props.cqModel.isEmpty;
    }
};
 
class MyComponent extends Component {
 
    render() {
        return <div className={'my-component'}></div>;
    }
}
 
MapTo('component/resource/path')(MyComponent, EditConfig);

Dans l’implémentation ci-dessus, le composant de projet est étendu avec la fonctionnalité de vide avant d’être réellement enregistré dans le magasin de mappage des composants. Pour ce faire, encapsulez et étendez la ComponentMapping bibliothèque afin d’introduire la prise en charge de l’objet EditConfig de configuration :
/**
 * Configuration object in charge of providing the necessary data expected by the page editor to initiate the authoring. The provided data will be decorating the associated component
 *
 * @typedef {{}} EditConfig
 * @property {String} [dragDropName]       If defined, adds a specific class name enabling the drag and drop functionality
 * @property {String} emptyLabel           Label to be displayed by the placeholder when the component is empty. Optionally returns an empty text value
 * @property {function} isEmpty            Should the component be considered empty. The function is called using the context of the wrapper component giving you access to the component model
 */
 
/**
 * Map a React component with the given resource types. If an {@link EditConfig} is provided the <i>clazz</i> is wrapped to provide edition capabilities on the AEM Page Editor
 *
 * @param {string[]} resourceTypes                      - List of resource types for which to use the given <i>clazz</i>
 * @param {class} clazz                                 - Class to be instantiated for the given resource types
 * @param {EditConfig} [editConfig]                     - Configuration object for enabling the edition capabilities
 * @returns {class}                                     - The resulting decorated Class
 */
ComponentMapping.map = function map (resourceTypes, clazz, editConfig) {};

Contrat avec l’éditeur de page

Les composants du projet doivent générer au minimum les attributs de données suivants pour permettre à l’éditeur d’interagir avec eux.
  • data-cq-data-path : Chemin relatif du composant tel que fourni par le PageModel (p. ex. "root/responsivegrid/image" ). Cet attribut ne doit pas être ajouté aux pages.
En résumé, pour être interprété par l’éditeur de page comme modifiable, un composant de projet doit respecter le contrat suivant :
  • Fournissez les attributs attendus pour associer une instance de composant principal à une ressource AEM.
  • Fournissez la série attendue d'attributs et de noms de classe qui permet la création d'espaces réservés vides.
  • Fournissez les noms de classe attendus permettant le glisser-déposer des ressources.

Structure d’élément HTML standard

Le fragment suivant illustre la représentation HTML type d’une structure de contenu de page. Voici quelques points importants :
  • L’élément de grille réactive contient les noms de classe, précédés de aem-Grid--
  • The responsive column element carries class names prefixed with aem-GridColumn--
  • Une grille réactive qui est également la colonne d’une grille parent est encapsulée, de sorte que les deux préfixes précédents n’apparaissent pas sur le même élément.
  • Elements corresponding to editable resources carry a data-cq-data-path property. Consultez la section Contrat avec l'éditeur de page de ce document.
<div data-cq-data-path="/content/page">
    <div class="aem-Grid aem-Grid--12 aem-Grid--default--12">
        <div class="aem-container aem-GridColumn aem-GridColumn--default--12" data-cq-data-path="/content/page/jcr:content/root/responsivegrid">
            <div class="aem-Grid aem-Grid--12 aem-Grid--default--12">
                <div class="cmp-image cq-dd-image aem-GridColumn aem-GridColumn--default--12" data-cq-data-path="/root/responsivegrid/image">
                    <img src="/content/we-retail-spa-sample/react/jcr%3acontent/root/responsivegrid/image.img.jpeg/1512113734019.jpeg">
                </div>
            </div>
        </div>
    </div>
</div>

Application d’une seule page en action

Découvrez le fonctionnement d’une application sur une seule page simple et exercez-vous avec une application de ce type en consultant le document Prise en main des applications sur une seule page dans AEM .

Informations complémentaires

Pour plus d’informations sur les applications sur une seule page dans AEM, consultez les documents suivants :