Le développeur de présentation de contenu doit normaliser la structure des données que la présentation de contenu reçoit.
Si toutes les données sont présentes, la présentation de contenu peut tout simplement afficher le composant. S'il manque des données, la présentation de contenu peut avoir besoin d'effectuer des requêtes supplémentaires. Dans tous les cas, la présentation de contenu ne doit jamais utiliser un certain format de données, elle doit plutôt contraindre les données dans un format permettant l'affichage.
Vous devez veiller à disposer de toutes les données attendues. Si les données n'existent pas, vous devez effectuer des requêtes supplémentaires. Il est possible que les champs suivants soient manquants dans les données :
Entrée "fields
" des champs référencés
Champs de texte long
Etant donné que les présentations de contenu sont conçues pour des types spécifiques de contenu, le développeur d'une présentation de contenu connaît la liste des champs nécessaires. Pour chacun de ces champs, les données doivent être extraites pour que la présentation de contenu puisse être affichée. Vous disposez de deux options : extraire les données manquantes et afficher ensuite le contenu avec les données complètes ou afficher immédiatement le contenu et extraire ensuite les données manquantes pour remplir les blancs.
Option 1 : extraire les données manquantes et afficher ensuite le contenu avec les données complètes
Créez une promesse pour extraire les données requises et poursuivre l'affichage lorsque toutes les promesses sont renvoyées.
Prenons par exemple les types de contenu suivants et les champs correspondants :
starter-blog-author
Champs
starter-blog-author_name :
champ de texte
starter-blog-author_bio :
champ de texte
starter-blog-post
Champs
starter-blog-post_title :
champ de texte
starter-blog-post_content :
champ de texte long
starter-blog-post_author :
référence à un élément starter-blog-author
La présentation de contenu possède le modèle suivant pour afficher ces valeurs de champ attendues :
{{#fields}} <div class="blog_container"> <div class="blog-post-title">{{starter-blog-post_title}}</div> {{#starter-blog-post_author.fields}} <div class="blog-author-container"> <div class="blog-author-details"> <div class="blog-author-name">{{starter-blog-author_name}}</div> <div class="blog-author-bio">{{{starter-blog-author_bio}}}</div> <span class="more-from-author">More articles from this author</span> </div> </div> {{/starter-blog-post_author.fields}} <div class="blog-post-content">{{{starter-blog-post_content}}}</div> </div> {{/fields}}
La présentation de contenu peut être appelée avec les données des requêtes suivantes :
Requête d'élément avec "expand
" : toutes les données fournies
/content/published/api/v1.1/items/{id}?expand=fields.starter-blog-post_author&channelToken=8dd714be0096ffaf0f7eb08f4ce5630f
Ce format de données est requis pour remplir correctement toutes les valeurs du modèle. Si les autres requêtes sont employées, un travail supplémentaire est nécessaire pour extraire les données et les convertir dans ce format.
"fields": { "starter-blog-post_title": "...", "starter-blog-post_summary": "...", "starter-blog-post_content": "...", "starter-blog-post_author": { "id": "CORE386C8733274240D0AB477C62271C2A02", "type": "Starter-Blog-Author" "fields": { "starter-blog-author_bio": "...", "starter-blog-author_name": "..." } } }
Requête d'élément, sans "expand
" : champs d'élément référencés "starter-blog-post_author.fields" manquants :
/content/published/api/v1.1/items/{id}?channelToken=8dd714be0096ffaf0f7eb08f4ce5630f
"fields": { "starter-blog-post_title": "...", "starter-blog-post_summary": "...", "starter-blog-post_content": "...", "starter-blog-post_author": { "id": "CORE386C8733274240D0AB477C62271C2A02", "type": "Starter-Blog-Author" } }
Requête SCIM : champ de texte long "starter-blog-post_content" manquant, champs d'élément référencés "starter-blog-post_author.fields" manquants :
/content/published/api/v1.1/items?q=(type eq "Starter-Blog-Post")&fields=ALL&channelToken=8dd714be0096ffaf0f7eb08f4ce5630f
"fields": { "starter-blog-post_title": "...", "starter-blog-post_summary": "...", "starter-blog-post_author": { "id": "CORE386C8733274240D0AB477C62271C2A02", "type": "Starter-Blog-Author" } }
Pour pouvoir obtenir un affichage cohérent avec ces requêtes, le fichier render.js
de la présentation de contenu doit garantir que tous les champs référencés sont développés et que les champs de texte long sont présents.
Si ce n'est pas le cas, il doit réexécuter les requêtes, corriger les données, puis exécuter l'affichage avec les données complètes.
Exemple de fonction render()
:
render: function (parentObj) { var self = this, template, contentClient = self.contentClient, content = self.contentItemData; var getRefItems = function (contentClient, ids) { // Calling getItems() with no "ids" returns all items. // If no items are requested, just return a resolved Promise. if (ids.length === 0) { return Promise.resolve({}); } else { return contentClient.getItems({ "ids": ids }); } }; var fetchIDs = [], // list of items to fetch referedFields = ['starter-blog-post_author'], // names of reference fields largeTextFields = ['starter-blog-post_content'], // large text fields in this asset fieldsData = content.fields; // See if we need to fetch any referenced fields referedFields.forEach(function (fieldName) { if(fieldsData[fieldName] && fieldsData[fieldName].fields) { // got data already, nothing else to do } else { // fetch this item fetchIDs.push(fieldsData[fieldName].id); } }); // See if we need to fetch any large text fields for(var i = 0; i < largeTextFields.length; i++) { if(!fieldsData[largeTextFields[i]]) { // need to fetch this content item directly to get all the large text fields fetchIDs.push(content.id); break; } } // now we have the IDs of all the content items we need to fetch, get them all before continuing getRefItems(contentClient, fetchIDs).then(function (referenceData) { var items = referenceData && referenceData.items || []; // add the data back in items.forEach(function (referencedItem){ // check if it's the current item if(referencedItem.id === content.id) { // copy across the large text fields largeTextFields.forEach(function (fieldName) { fieldsData[fieldName] = referencedItem.fields[fieldName]; }); } else{ // check for any referenced fields for (var i = 0; i < referedFields.length; i++) { if(referencedItem.id === fieldsData[referedFields[i]].id){ // copy across the fields values fieldsData[referedFields[i]].fields = referencedItem.fields; break; } } } }); // now data is fixed up, we can continue as before try{ // Mustache template = Mustache.render(templateHtml, content); if(template) { $(parentObj).append(template); } } catch (e) { console.error(e.stack); } }); }
Option 2 : afficher immédiatement le contenu et extraire ensuite les données manquantes pour remplir les blancs
Les performances peuvent être améliorées si les éléments éventuellement non présents sont séparés et affichés lors d'une deuxième transmission. Pour ce faire, vous avez besoin de deux modèles Mustache, le premier pour l'affichage initial, laissant des "vides", et le second pour l'affichage suivant qui remplit les vides une fois que les données sont complètes.
Vous devez donc configurer le modèle Mustache de sorte qu'il prenne en charge plusieurs transmissions. Pour ce faire, configurez des modèles séparés pour les "vides" ou configurez le modèle pour qu'il renvoie des macros plutôt que des valeurs réelles. Dans les deux cas, vous devez "masquer" ces vides jusqu'à ce que les données soient extraites, puis les remplir et les afficher avec l'animation appropriée d'interface utilisateur pour éviter que la page ne "saute" trop.