Modifier l’application React avec l’éditeur universel
Dans ce chapitre, vous apprenez à rendre l’application React créée dans le chapitre précédent modifiable à l’aide de l’éditeur universel d’AEM. L’éditeur universel permet aux personnes en charge de la création de contenu de modifier du contenu directement dans le contexte de l’expérience de l’application React, tout en conservant l’expérience transparente d’une application découplée.
L’éditeur universel offre un moyen puissant d’activer la modification contextuelle pour n’importe quelle application web, ce qui permet aux créateurs et aux créatrices de modifier le contenu sans basculer entre différentes interfaces de création.
Prérequis
- Les étapes précédentes de ce tutoriel ont été terminées, en particulier Créer une application React qui utilise les OpenAPI de diffusion de fragments de contenu AEM
- Une connaissance pratique de comment utiliser et implémenter l’éditeur universel.
Objectifs
Découvrez comment :
- Ajoutez l’instrumentation de l’éditeur universel à l’application React.
- Configurez l’application React pour l’éditeur universel.
- Activez la modification de contenu directement dans l’interface de l’application React à l’aide de l’éditeur universel.
Instrumentation de l’éditeur universel
L’éditeur universel requiert les attributs HTML et les balises meta pour identifier le contenu modifiable et établir la connexion entre l’interface utilisateur et le contenu AEM.
Ajout de balises d’éditeur universel
Tout d’abord, ajoutez les balises méta nécessaires pour identifier l’application React comme compatible avec l’éditeur universel.
-
Ouvrez
public/index.html
dans votre application React. -
Ajoutez les balises méta de l’éditeur universel et script CORS dans la section
<head>
de l’application React :code language-html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="theme-color" content="#000000" /> <meta name="description" content="WKND Teams React App" /> <!-- Universal Editor meta tags and CORS script --> <meta name="urn:adobe:aue:system:aemconnection" content="aem:%REACT_APP_AEM_AUTHOR_HOST_URI%" /> <script src="https://universal-editor-service.adobe.io/cors.js"></script> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <title>WKND Teams</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> </body> </html>
-
Mettez à jour le fichier
.env
de l’application React afin d’inclure l’hôte du service de création AEM pour prendre en charge les écritures différées dans l’éditeur universel (utilisé dans la valeur de la balise metaturn:adobe:aue:system:aemconnection
).code language-bash # The AEM Publish (or Preview) service REACT_APP_HOST_URI=https://publish-p123-e456.adobeaemcloud.com # The AEM Author service REACT_APP_AEM_AUTHOR_HOST_URI=https://author-p123-e456.adobeaemcloud.com
Instrumenter le composant Équipes
Ajoutez maintenant les attributs de l’éditeur universel pour rendre le composant Équipes modifiable.
-
Ouvrez
src/components/Teams.js
. -
Mettez à jour le composant
Team
pour inclure les attributs de données de l’éditeur universel :Lors de la définition de l’attribut
data-aue-resource
, assurez-vous que le chemin d’accès AEM au fragment de contenu, tel que renvoyé par la diffusion de fragment de contenu AEM avec les API OpenAPI, est postfixé avec le sous-chemin d’accès à la variation de fragment de contenu ; dans ce cas,/jcr:content/data/master
.code language-javascript import { useEffect, useState } from "react"; import { Link } from "react-router-dom"; import "./Teams.scss"; function Teams() { // The teams folder is the only folder-tree that is allowed to contain Team Content Fragments. const TEAMS_FOLDER = '/content/dam/my-project/en/teams'; // State to store the teams data const [teams, setTeams] = useState(null); useEffect(() => { /** * Fetches all teams and their associated member details * This is a two-step process: * 1. First, get all team content fragments from the specified folder * 2. Then, for each team, fetch the full details including hydrated references to get the team member names */ const fetchData = async () => { try { // Step 1: Fetch all teams from the teams folder const response = await fetch( `${process.env.REACT_APP_HOST_URI}/adobe/contentFragments?path=${TEAMS_FOLDER}` ); const allTeams = (await response.json()).items || []; // Step 2: Fetch detailed information for each team with hydrated references const hydratedTeams = []; for (const team of allTeams) { const hydratedTeamResponse = await fetch( `${process.env.REACT_APP_HOST_URI}/adobe/contentFragments/${team.id}?references=direct-hydrated` ); hydratedTeams.push(await hydratedTeamResponse.json()); } setTeams(hydratedTeams); } catch (error) { console.error("Error fetching content fragments:", error); } }; fetchData(); }, [TEAMS_FOLDER]); // Show loading state while teams data is being fetched if (!teams) { return <div>Loading teams...</div>; } // Render the teams return ( <div className="teams"> {teams.map((team, index) => { return ( <Team key={index} {...team} /> ); })} </div> ); } /** * Team - renders a single team with its details and members * @param {Object} fields - The authored Content Fragment fields * @param {Object} references - Hydrated references containing member details such as fullName * @param {string} path - Path of the team content fragment */ function Team({ fields, references, path }) { if (!fields.title || !fields.teamMembers) { return null; } return ( <> {/* Specify the correct Content Fragment variation path suffix in the data-aue-resource attribute */} <div className="team" data-aue-resource={`urn:aemconnection:${path}/jcr:content/data/master`} data-aue-type="component" data-aue-label={fields.title}> <h2 className="team__title" data-aue-prop="title" data-aue-type="text" data-aue-label="Team Title">{fields.title}</h2> <p className="team__description" data-aue-prop="description" data-aue-type="richtext" data-aue-label="Team Description" dangerouslySetInnerHTML={{ __html: fields.description.value }} /> <div> <h4 className="team__members-title">Members</h4> <ul className="team__members"> {fields.teamMembers.map((teamMember, index) => { return ( <li key={index} className="team__member"> <Link to={`/person/${teamMember}`}> {references[teamMember].value.fields.fullName} </Link> </li> ); })} </ul> </div> </div> </> ); } export default Teams;
Instrumenter le composant Personne
De même, ajoutez les attributs de l’éditeur universel au composant Personne .
-
Ouvrez
src/components/Person.js
. -
Mettez à jour le composant pour inclure les attributs de données de l’éditeur universel :
Lors de la définition de l’attribut
data-aue-resource
, assurez-vous que le chemin d’accès AEM au fragment de contenu, tel que renvoyé par la diffusion de fragment de contenu AEM avec les API OpenAPI, est postfixé avec le sous-chemin d’accès à la variation de fragment de contenu ; dans ce cas,/jcr:content/data/master
.code language-javascript import "./Person.scss"; import { useEffect, useState } from "react"; import { useParams } from "react-router-dom"; /** * Person component - displays detailed information about a single person * Fetches person data from AEM using the ID from the URL parameters */ function Person() { const { id } = useParams(); const [person, setPerson] = useState(null); useEffect(() => { const fetchData = async () => { try { const response = await fetch( `${process.env.REACT_APP_HOST_URI}/adobe/contentFragments/${id}?references=direct-hydrated` ); const json = await response.json(); setPerson(json || null); } catch (error) { console.error("Error fetching person data:", error); } }; fetchData(); }, [id]); if (!person) { return <div>Loading person...</div>; } /* Add the Universal Editor data-aue-* attirbutes to the rendered HTML */ return ( <div className="person" data-aue-resource={`urn:aemconnection:${person.path}/jcr:content/data/master`} data-aue-type="component" data-aue-label={person.fields.fullName}> <img className="person__image" src={process.env.REACT_APP_HOST_URI + person.references[person.fields.profilePicture].value.path} alt={person.fields.fullName} data-aue-prop="profilePicture" data-aue-type="media" data-aue-label="Profile Picture" /> <div className="person__occupations"> {person.fields.occupation.map((occupation, index) => { return ( <span key={index} className="person__occupation"> {occupation} </span> ); })} </div> <div className="person__content"> <h1 className="person__full-name" data-aue-prop="fullName" data-aue-type="text" data-aue-label="Full Name"> {person.fields.fullName} </h1> <div className="person__biography" data-aue-prop="biographyText" data-aue-type="richtext" data-aue-label="Biography" dangerouslySetInnerHTML={{ __html: person.fields.biographyText.value }} /> </div> </div> ); }
Obtenir le code terminé
Le code source complet de ce chapitre est disponible sur Github.com.
$ git fetch --tags
$ git tag
$ git checkout tags/headless_open-api_basic_5-end
Test de l’intégration de l’éditeur universel
Testez maintenant les mises à jour de compatibilité de l’éditeur universel en ouvrant l’application React dans l’éditeur universel.
Démarrer l’application React
-
Vérifiez que votre application React est en cours d’exécution :
code language-bash $ cd ~/Code/aem-guides-wknd-openapi/basic-tutorial $ npm install $ npm start
-
Vérifiez que l’application se charge à l’
http://localhost:3000
et affiche le contenu des équipes et des personnes.
Exécuter le proxy SSL local
L’éditeur universel nécessite que l’application modifiable soit chargée via HTTPS.
-
Pour exécuter l’application React locale via HTTPS, utilisez le module npm local-ssl-proxy à partir de la ligne de commande.
code language-bash $ npm install -g local-ssl-proxy $ local-ssl-proxy --source 3001 --target 3000
-
Ouvrez
https://localhost:3001
dans votre navigateur web -
Accepter le certificat auto-signé.
-
Vérifiez que l’application React se charge.
Ouvrir dans l’éditeur universel
- Accédez à Éditeur universel.
- Dans le champ URL du site, saisissez l’URL de l’application React HTTPS :
https://localhost:3001
. - Sélectionnez Cliquer Ouvrir.
L’éditeur universel doit charger votre application React avec les fonctionnalités d’édition activées.
Tester la fonctionnalité d’édition
-
Dans l’éditeur universel, passez la souris sur les éléments modifiables de votre application React.
-
Pour naviguer dans l’application React, activez le mode Aperçu puis désactivez-le pour le modifier. N’oubliez pas que le Aperçu n’a rien à voir avec le service d’aperçu AEM. Il active et désactive plutôt la fonction Modifier Chrome dans l’éditeur universel.
-
Vous devriez voir les indicateurs d’édition et être en mesure de cliquer sur les différents éléments modifiables de l’application React.
-
Essayez de modifier le titre d’une équipe :
- Clic sur le titre d'une équipe
- Modifier le texte dans le panneau des propriétés
- Enregistrez les modifications.
-
Essayez de modifier la photo de profil d’une personne :
- Cliquer sur la photo de profil d’une personne
- Sélectionner une nouvelle image à partir du sélecteur de ressources
- Enregistrez les modifications.
-
Appuyez sur Publier dans le coin supérieur droit de l’éditeur universel pour publier les modifications sur le service de Publication AEM (ou Aperçu), afin qu’elles soient répercutées dans l’application React dans l’éditeur universel.
Attributs de données de l’éditeur universel
Pour obtenir une documentation complète sur l’instrumentation d’une application pour l’éditeur universel, reportez-vous à la documentation de l’éditeur universel.
Félicitations !
Félicitations. Vous avez correctement intégré l’éditeur universel à votre application React. Les auteurs de contenu peuvent désormais modifier des fragments de contenu directement dans l’interface de l’application React, offrant ainsi une expérience de création transparente tout en conservant les avantages d’une architecture découplée.
N’oubliez pas que vous pouvez toujours obtenir le code source final de ce tutoriel à partir de la branche main
du référentiel GitHub.com.