Estandarización de la estructura de datos de un diseño de contenido

El desarrollador del diseño de contenido debe estandarizar la estructura de datos que recibe el diseño de contenido.

Si están presentes todos los datos, el diseño de contenido puede simplemente representar el componente. Si no están presentes todos los datos, puede que el diseño de contenido necesite realizar consultas adicionales. En todos los casos, el diseño de contenido nunca debe asumir un formato de datos determinado; en su lugar, debe forzar los datos en un formato que se representará.

Debe asegurarse de que tiene todos los datos que esperaba. Si no existen los datos, deberá realizar consultas adicionales. Los siguientes campos podrían faltan en los datos:

  • Entrada "fields" de los campos a los que se hace referencia

  • Campos de texto grandes

Debido a que los diseños de contenido están diseñados para tipos de contenido específicos, el desarrollador de un diseño de contenido conoce la lista de campos necesarios. Para cada uno de estos campos, es necesario recuperar los datos para que se pueda representar el diseño de contenido. Tiene dos opciones: recuperar los datos que faltan y, a continuación, representarlos con los datos completos o representarlos inmediatamente y, a continuación, recuperar los datos que faltan para rellenar los que están en blanco.

Opción 1: recuperar los datos que faltan y, a continuación, representarlos con los datos completos

Cree una promesa para recuperar los datos necesarios y, a continuación, siga representándolos cuando se devuelvan todas las promesas.

Por ejemplo, tenemos los siguientes tipos de contenido con los campos correspondientes:

  • 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: referencia a un elemento starter-blog-author

El diseño de contenido tiene la siguiente plantilla para representar estos 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}}

Se puede llamar al diseño de contenido con datos de las siguientes consultas:

  • Consulta de elemento con "expand": todos los datos proporcionados

    • /content/published/api/v1.1/items/{id}?expand=fields.starter-blog-post_author&channelToken=8dd714be0096ffaf0f7eb08f4ce5630f

    • Este es el formato de los datos necesario para rellenar correctamente todos los valores de la plantilla. Si se utiliza alguna otra consulta, se requerirá un trabajo adicional para recuperar los datos y convertirlos a este 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 elemento sin "expand": faltan los campos de elemento "starter-blog-post_author.fields" a los que se hace referencia:

    • /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 SCIM: falta el campo de texto grande "starter-blog-post_content", faltan los campos de elemento "starter-blog-post_author.fields" a los que se hace referencia:

    • /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 que se pueda representar de forma consistente con cualquiera de estas consultas, render.js del diseño de contenido debe asegurarse de que se amplíen todos los campos a los que se hace referencia y de que estén presentes los campos de texto grandes.

En caso contrario, debe volver a realizar estas consultas, corregir los datos y representarlos a continuación con los datos completos.

Función render() de ejemplo:

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);
        }    
    });
}

Opción 2: representarlos inmediatamente y, a continuación, recuperar los datos que faltan para rellenar los que están en blanco

Se puede mejorar el rendimiento separando los elementos que puede que no estén presentes y representándolos en una segunda pasada. Para ello, serán necesarias dos plantillas de Mustache, la primera para realizar la representación inicial, dejando "huecos" que posteriormente se rellenan con la segunda representación cuando los datos están completos.

Esto requiere que se configure la plantilla de Mustache para que admita varias pasadas, ya sea teniendo plantillas diferentes para los "huecos" o haciendo que el modelo devuelva macros de plantilla en lugar de los valores reales. En cualquiera de los casos, deberá "ocultar" estos huecos hasta que se recuperen los datos y, a continuación, rellenarlos y mostrarlos con la animación de interfaz de usuario adecuada para evitar que la página "salte demasiado".