İçerik Yerleşimleri için Veri Yapısını Standartlaştırma

İçerik yerleşimi geliştiricisinin, içerik yerleşiminin aldığı verilerin yapısını standartlaştırması gerekir.

Tüm veriler mevcutsa içerik yerleşimi bileşeni görüntüleyebilir. Tüm veriler mevcut değilse içerik yerleşiminin ek sorgular yapması gerekebilir. Her durumda, içerik yerleşimi hiçbir zaman belirli bir veri formatı farz etmemelidir ve bunun yerine verileri görüntülenecek bir formata zorunlu kılmalıdır.

Beklediğiniz tüm verilere sahip olduğunuza emin olmanız gerekir. Veriler mevcut değilse ek sorgular yapmanız gerekir. Aşağıdaki alanlar potansiyel olarak verilerde olmayacaktır:

  • Başvuruda bulunulan alanlar için "fields" girişi

  • Büyük metin alanları

İçerik yerleşimleri belirli içerik tipleri için tasarlandığından, bir içerik yerleşiminin geliştiricisi gerekli alanların listesini bilir. İçerik yerleşiminin görüntüleyebilmesi amacıyla bu alanların her biri için verilerin getirilmesi gerekir. İki seçeneğiniz vardır: Eksik verileri getirip ardından verilerin tamamıyla görüntüleme veya hemen görüntüleyip ardından eksik verileri getirerek boşlukları doldurma.

Seçenek 1: Eksik Verileri Getirip Ardından Verilerin Tamamıyla Görüntüleme

Gerekli verileri almak için bir Taahhüt oluşturun ve tüm Taahhütler döndürüldüğünde görüntülemeye devam edin.

Örneğin, ilgili alanları içeren şu içerik tipleri var:

  • starter-blog-author

    • alanlar

      • starter-blog-author_name - metin alanı

      • starter-blog-author_bio - metin alanı

  • starter-blog-post

    • alanlar

      • starter-blog-post_title - metin alanı

      • starter-blog-post_content - büyük metin alanı

      • starter-blog-post_author - starter-blog-author öğesinin referansı

İçerik Yerleşiminde, şu beklenen alan değerlerini görüntülemek için aşağıdaki şablon bulunur:

{{#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}}

İçerik Yerleşimi, şu sorgulardaki verilerle çağrılabilir:

  • "expand" ile öğe sorgusu - tüm verileri sağlanır

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

    • Bu, şablondaki tüm değerleri başarıyla doldurmak için gerekli veri formatıdır. Diğer sorgulardan biri kullanılırsa verileri getirip bu formata dönüştürmek için ek çalışma gerekir.

    • "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": "..."
              }
          }
      }
  • "expand" içermeyen öğe sorgusu - referans alınan "starter-blog-post_author.fields" öğe alanları eksik:

    • /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"
          }
      }
  • Etki Alanları Arası Kimlik Yönetimi sorgusu - "starter-blog-post_content" büyük metin alanı eksik, referans alınan "starter-blog-post_author.fields" öğe alanları eksik:

    • /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"
          }
      }

Bu sorguların herhangi biriyle tutarlı olarak görüntüleyebilmek amacıyla, içerik yerleşimindeki render.js dosyasının tüm referans alınan alanların genişletildiğinden ve büyük metin alanlarının mevcut olduğuna emin olması gerekir.

Aksi takdirde bunları tekrar sorgulaması, verileri düzeltmesi ve ardından verilerin tamamıyla görüntülemesi gerekir.

Örnek render() fonksiyonu:

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

Seçenek 2: Hemen Görüntüleyip Ardından Eksik Verileri Getirerek Boşlukları Doldurma

Mevcut olmayabilecek öğeler ayrılarak ve ikinci geçiş görüntülenerek performans artırılabilir. Bu, iki Mustache şablonu gerektirir; birincisi ilk görüntülemeyi yapar ve veriler tamamlandıktan sonra ikinci görüntüleme ile doldurulan "boşlukları" bırakır.

Bu, Mustache şablonunun "boşluklar" için ayrı şablonlar içererek veya modelin fiili değerler yerine şablon makrolar döndürmesini sağlayarak birden fazla geçişi desteklemek için ayarlanmasını gerektirir. Her iki durumda da veriler alınana kadar bu boşlukları "gizlemeniz", ardından bunları doldurmanız ve sayfanın çok fazla "zıplamasından" kaçınmak için bunları uygun kullanıcı arayüzü animasyonu ile göstermeniz gerekir.