Standardizarea structurii datelor pentru o machetă de conţinut

Dezvoltatorul machetei de conţinut trebuie să standardizeze structura datelor pe care o va primi acea machetă de conţinut.

Dacă există toate datele necesare, macheta de conţinut poate randa componenta. Dacă nu există toate datele necesare, ar putea fi necesar ca macheta de conţinut să efectueze interogări suplimentare. În orice caz, macheta de conţinut nu ar trebui niciodată să presupună existenţa unui anumit format al datelor şi, în schimb, ar trebui să organizeze datele într-un format care să permită randarea.

Va trebui să vă asiguraţi că aveţi toate datele necesare. Dacă nu sunt disponibile toate datele, va trebui să efectuaţi interogări suplimentare. Următoarele câmpuri este posibil să lipsească din cadrul datelor:

  • Intrarea "fields" pentru câmpurile de referinţă

  • Câmpuri de text mari

Deoarece machetele de conţinut sunt create pentru anumite tipuri de conţinut, dezvoltatorul unei machete de conţinut cunoaşte lista câmpurilor necesare. Pentru fiecare dintre aceste câmpuri, datele vor trebui preluate pentru ca macheta de conţinut să asigure randarea. Aveţi două opţiuni: preluaţi datele care lipsesc şi apoi efectuaţi randarea, având datele complete, sau efectuaţi randarea imediat şi apoi preluaţi datele care lipesc pentru a completa informaţiile lipsă.

Opţiunea 1: Preluaţi datele care lipsesc şi efectuaţi randarea cu datele complete

Creaţi o Promisiune de a prelua datele necesare, apoi continuaţi randarea când sunt returnate toate Promisiunile.

De exemplu, avem următoarele tipuri de conţinut şi câmpurile corespondente:

  • starter-blog-author

    • câmpuri

      • starter-blog-author_name -text field

      • starter-blog-author_bio - text field

  • starter-blog-post

    • câmpuri

      • starter-blog-post_title - text field

      • starter-blog-post_content - large text field

      • starter-blog-post_author - reference to a starter-blog-author item

Macheta de conţinut are următorul şablon pentru randarea acestor valori aşteptate ale câmpurilor:

{{#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 pot apela date din macheta de conţinut utilizându-se următoarele interogări:

  • Interogare de articole cu "expand" - sunt furnizate toate datele

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

    • Acesta este formatul necesar pentru date, pentru popularea cu succes a tuturor valorilor în şablon. Dacă se utilizează oricare dintre celelalte interogări, sunt necesare operaţii suplimentare pentru a prelua datele şi a e converti la acest 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": "..."
              }
          }
      }
  • Interogare de articole fără "expand" - lipsesc câmpurile de articole la care se face referire, "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"
          }
      }
  • Interogare SCIM - lipseşte câmpul de text mare "starter-blog-post_content", lipsesc câmpurile de articole la care se face referire, "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"
          }
      }

Pentru a putea efectua o randare consecventă cu oricare dintre aceste interogări, trebuie să vă asiguraţi că în fişierul render.js din macheta de conţinut toate câmpurile la care se face referire sunt expandate şi câmpurile de text mari sunt prezente.

Dacă nu este cazul, fişierul trebuie să efectueze interogări pentru a prelua aceste elemente, să corecteze datele, apoi să efectueze randarea, având datele complete.

Exemplu de funcţie 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);
        }    
    });
}

Opţiunea 2: Efectuaţi randarea imediat şi apoi preluaţi datele care lipsesc pentru a completa informaţiile lipsă

Performanţa poate fi îmbunătăţită prin separarea articolelor care este posibil să nu fie prezente şi randarea acestora într-o a doua încercare. Pentru aceasta, vor fi necesare două şabloane Mustache, primul pentru randarea iniţială, care va lăsa "spaţii libere" ce vor fi completate într-o a doua randare, efectuată după ce datele sunt complete.

Acest lucru presupune configurarea şablonului Mustache să permită mai multe treceri, fie prin existenţa mai multor şabloane pentru completarea "spaţiilor libere", fie prin configurarea modelului să returneze macrocomenzi pentru şablon, nu valori efective. Oricare ar fi cazul, va trebui să "ascundeţi" aceste spaţii libere până când sunt preluate datele şi apoi să le populaţi şi să le afişaţi cu o animaţie corespunzătoare pentru utilizator, pentru a evita "fluctuaţiile" excesive ale conţinutului paginii.