O desenvolvedor de layout de conteúdo precisa padronizar a estrutura de dados que o layout de conteúdo recebe.
Se todos os dados estiverem presentes, o layout de conteúdo simplesmente poderá renderizar o componente. Se nem todos os dados estiverem presentes, o layout de conteúdo poderá precisar fazer consultas adicionais. Em todos os casos, o layout de conteúdo nunca deve assumir um determinado formato de dados e, em vez disso, coagir os dados a um formato que será renderizado.
Assegure-se de que você tenha todos os dados que está esperando. Se os dados não existirem, faça as consultas adicionais. Os seguintes campos possivelmente estarão faltando nos dados:
A entrada "fields
" para campos referenciados
Campos de texto grandes
Como os layouts de conteúdo são projetados para tipos de conteúdo específicos, o desenvolvedor de um layout de conteúdo conhece a lista de campos necessários. Para cada um desses campos, os dados precisam ser extraídos para que o layout de conteúdo possa ser renderizado. Você tem duas opções: extrair dados ausentes e depois renderizar com dados completos ou renderizar imediatamente e depois extrair dados ausentes para preencher os brancos.
Opção 1: Extrair Dados Ausentes e depois Renderizar com Dados Completos
Crie uma Promessa para recuperar os dados exigidos e, em seguida, continuar renderizando quando todas as Promessas forem retornadas.
Por exemplo, temos os seguintes tipos de conteúdo com os campos correspondentes:
starter-blog-author
campos
starter-blog-author_name
- campo de texto
starter-blog-author_bio
- campo de texto
starter-blog-post
campos
starter-blog-post_title
- campo de texto
starter-blog-post_content
- campo de texto grande
starter-blog-post_author
- referência a um item starter-blog-author
O Layout de Conteúdo tem o seguinte modelo para renderizar estes valores de campo esperados:
{{#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}}
O Layout de Conteúdo pode ser chamado com dados das seguintes consultas:
Consulta de item com "expand
" - todos os dados fornecidos
/content/published/api/v1.1/items/{id}?expand=fields.starter-blog-post_author&channelToken=8dd714be0096ffaf0f7eb08f4ce5630f
Este é o formato dos dados que são exigidos para preencher com sucesso todos os valores no modelo. Se qualquer uma das outras consulta for utilizada, um trabalho adicional será necessário para extrair os dados e convertê-los nesse formato.
"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": "..." } } }
Consulta de item, sem "expand
" - campos de itens referenciados ausentes "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" } }
Consulta de SCIM - campo de texto grande ausente "starter-blog-post_content", campos de itens referenciados ausentes "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" } }
Para poder renderizar de forma consistente com qualquer uma dessas consultas, o arquivo render.js
do layout de conteúdo precisa se certificar de que todos os campos referenciados sejam expandidos e que campos de texto grande estejam presentes.
Se esse não for o caso, ele precisará tornar a consultá-los, corrigir os dados e depois renderizar com os dados completos.
Função render()
de amostra:
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); } }); }
Opção 2: Renderizar Imediatamente e depois Extrair Dados Ausentes para Preencher os Brancos
O desempenho pode ser melhorado separando os itens que possam não estar presentes e renderizando-os em uma segunda fase. Isso exigirá dois modelos Mustache, o primeiro para fazer a renderização inicial, deixando "furos" que depois são preenchidos com a segunda renderização após a conclusão dos dados.
Isso exige a configuração do modelo Mustache para suportar diversas fases, tendo modelos distintos para os "furos" ou fazer o exemplar retornar macros de modelo em vez de valores reais. Em qualquer dos dois casos, você precisará "esconder" esses furos até que os dados sejam recuperados e depois preenchê-los e mostrá-los com a animação apropriada da interface do usuário para evitar muitos "pulos" de página.