Udvikleren af indholdslayout skal standardisere strukturen af data, som indholdslayoutet modtager.
Hvis alle data er til stede, kan indholdslayoutet blot gengive komponenten. Hvis alle data ikke er til stede, skal indholdslayoutet muligvis foretage yderligere forespørgsler. Indholdslayoutet må aldrig antage, at der skal bruges et bestemt dataformat, men skal i stedet indsætte data i et format, der kan gengives.
Du skal sikre dig, at du har alle de forventede data. Hvis dataene ikke findes, skal du foretage yderligere forespørgsler. Følgende felter kan mangle i dataene:
Posten "fields
" for felter, der refereres til
Store tekstfelter
Da indholdslayout er designet til specifikke indholdstyper, kender udvikleren af et indholdslayout listen over nødvendige felter. Dataene skal hentes for hvert af disse felter, så indholdslayoutet kan gengives. Du har to valgmuligheder: Du kan hente manglende data og derefter gengive med alle data eller gengive straks og derefter hente manglende data for at udfylde hullerne.
Valgmulighed 1: Hente manglende data og derefter gengive med alle data
Opret et løfte for at hente de påkrævede data og derefter fortsætte med gengivelsen, når alle løfter er returneret.
Vi har for eksempel følgende indholdstyper med tilsvarende felter:
starter-blog-author
felter
starter-blog-author_name
- tekstfelt
starter-blog-author_bio
- tekstfelt
starter-blog-post
felter
starter-blog-post_title
- tekstfelt
starter-blog-post_content
- stort tekstfelt
starter-blog-post_author
- reference til elementet starter-blog-author
Indholdslayoutet har følgende skabelon til gengivelse af disse forventede feltværdier:
{{#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}}
Indholdslayoutet kan kaldes med data fra følgende forespørgsler:
Elementforespørgsel med "expand
" - alle data leveres
/content/published/api/v1.1/items/{id}?expand=fields.starter-blog-post_author&channelToken=8dd714be0096ffaf0f7eb08f4ce5630f
Dette er det dataformat, der kræves at opnå en vellykket udfyldelse af alle værdierne i skabelonen. Hvis en af de andre forespørgsler bruges, er det nødvendigt med yderligere arbejde for at hente dataene og konvertere dem til dette 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": "..." } } }
Elementforespørgsel uden "expand
" - manglende elementfelter, der refereres til "starter-blog-post_author.fields":
/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" } }
SCIM-forespørgsel - manglende stort tekstfelt "starter-blog-post_content", manglende elementfelter, der refereres til "starter-blog-post_author.fields":
/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" } }
For at kunne gengive disse forespørgsler konsekvent skal render.js
fra indholdslayoutet sørge for, at alle de felter, der refereres til, er udvidet, og de store tekstfelter er til stede.
Hvis det ikke er tilfældet, skal den forespørge bagud, rette dataene og derefter gengive de komplette data.
Eksempel på render()
-funktion:
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); } }); }
Valgmulighed 2: Gengive straks og derefter hente manglende data for at udfylde hullerne
Ydeevnen kan forbedres, ved at de elementer, der muligvis ikke er til stede, udskilles og gengives i et andet gennemløb. Det kræver to Mustache-skabeloner, hvor den første foretager den indledende gengivelse, der efterlader "huller", som derefter udfyldes i den anden gengivelse, når dataene er komplette.
Det kræver opsætning af Mustache-skabelonen, så den understøtter flere gennemgange, ved enten at have separate skabeloner til "huller" eller få modellen til at returnere skabelonmakroer i stedet for faktiske værdier. I begge tilfælde skal du "skjule" disse huller, indtil dataene hentes, og derefter udfylde og vise dem med passende animation i brugergrænsefladen for at undgå, at siden "hopper for meget omkring".