ผู้พัฒนาเลย์เอาต์ของเนื้อหาต้องทำให้โครงสร้างของข้อมูลที่เลย์เอาต์ของเนื้อหาได้รับเป็นมาตรฐาน
หากมีข้อมูลทั้งหมดอยู่ เลย์เอาต์ของเนื้อหาจะสามารถแสดงผลองค์ประกอบได้ หากไม่มีข้อมูลทั้งหมด เลย์เอาต์ของเนื้อหาอาจต้องทำการสืบค้นเพิ่มเติม ในทุกกรณี เลย์เอาต์ของเนื้อหาไม่ควรยอมรับรูปแบบข้อมูลบางอย่างและบังคับให้ข้อมูลใช้รูปแบบที่จะแสดงผลแทน
คุณจะต้องตรวจสอบให้แน่ใจว่าคุณมีข้อมูลทั้งหมดที่ต้องการ หากข้อมูลไม่มีอยู่ คุณจะต้องทำการสืบค้นเพิ่มเติม ฟิลด์ต่อไปนี้อาจขาดหายไปจากข้อมูล:
รายการ "fields" สำหรับฟิลด์ที่อ้างอิง
ฟิลด์ข้อความขนาดใหญ่
เนื่องจากเลย์เอาต์ของเนื้อหาออกแบบมาสำหรับประเภทเนื้อหาเฉพาะ ผู้พัฒนาของเลย์เอาต์ของเนื้อหาต้องรู้ว่าจะใช้ลิสต์ของฟิลด์ใด สำหรับแต่ละฟิลด์เหล่านี้ จำเป็นต้องดึงข้อมูลเพื่อให้เลย์เอาต์ของเนื้อหาสามารถแสดงผลได้ คุณมีสองตัวเลือก: ดึงข้อมูลที่ขาดหายไป จากนั้นแสดงผลด้วยข้อมูลที่สมบูรณ์ หรือแสดงผลทันทีแล้วค่อยดึงข้อมูลที่ขาดหายเพื่อเติมเต็มส่วนที่ว่าง
ตัวเลือก 1: ดึงข้อมูลที่ขาดหายไป แล้วแสดงผลด้วยข้อมูลที่สมบูรณ์
สร้าง Promise เพื่อดึงข้อมูลที่จำเป็น จากนั้นแสดงผลต่อเมื่อ Promise ทั้งหมดแสดงผล
ตัวอย่างเช่น เรามีประเภทเนื้อหาที่มีฟิลด์ที่เกี่ยวข้องต่อไปนี้
starter-blog-author
ฟิลด์
starter-blog-author_name - ฟิลด์ข้อความ
starter-blog-author_bio - ฟิลด์ข้อความ
starter-blog-post
ฟิลด์
starter-blog-post_title - ฟิลด์ข้อความ
starter-blog-post_content - ฟิลด์ข้อความขนาดใหญ่
starter-blog-post_author - อ้างอิงกับรายการ starter-blog-author
เลย์เอาต์เนื้อหามีเทมเพลทต่อไปนี้เพื่อแสดงผลค่าฟิลด์ที่ต้องการเหล่านี้
{{#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}}
สามารถเรียกเลย์เอาต์ของเนื้อหาด้วยข้อมูลจากการสืบค้นต่อไปนี้
การสืบค้นรายการที่มี "expand" - ข้อมูลทั้งหมดที่ระบุ
/content/published/api/v1.1/items/{id}?expand=fields.starter-blog-post_author&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"
"fields": {
"starter-blog-author_bio": "...",
"starter-blog-author_name": "..."
}
}
}การสืบค้นรายการที่ไม่มี "expand" - ไม่มีฟิลด์รายการที่อ้างอิง "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 - ไม่มีฟิลด์ข้อความขนาดใหญ่ "starter-blog-post_content", ไม่มีฟิลด์รายการที่อ้างอิง "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"
}
}เพื่อให้สามารถแสดงผลด้วยการสืบค้นใดๆ เหล่านี้ render.js จากเลย์เอาต์ของเนื้อหาจำเป็นต้องตรวจสอบให้แน่ใจว่ามีการขยายฟิลด์ที่อ้างอิงทั้งหมด และมีฟิลด์ข้อความขนาดใหญ่อยู่
ไม่เช่นนั้น จะต้องสืบค้นรายการเหล่านี้กลับ แก้ไขข้อมูล แล้วแสดงผลด้วยข้อมูลที่สมบูรณ์
ฟังก์ชัน 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);
}
});
}ตัวเลือก 2: แสดงผลทันที แล้วดึงข้อมูลที่ขาดหายไปเพื่อเติมเต็มส่วนที่ว่าง
สามารถปรับปรุงประสิทธิภาพการทำงานด้วยการแยกรายการที่อาจไม่มีอยู่ แล้วแสดงผลในรอบที่สอง การดำเนินการนี้จะต้องมีเทมเพลท Mustache สองรายการ รายการแรกจะทำการแสดงผลเริ่มต้น โดยปล่อย "ช่องว่าง" ที่จะได้รับการเติมเต็มในการแสดงผลครั้งที่สองเมื่อข้อมูลครบถ้วนสมบูรณ์
ซึ่งจำเป็นต้องมีการตั้งค่าเทมเพลท Mustache เพื่อรองรับรอบหลายรอบด้วยการใช้เทมเพลทแยกสำหรับ "ช่องว่าง" หรือใช้มาโครเทมเพลทการแสดงโมเดลแทนที่จะเป็นค่าจริง ในกรณีใดกรณีหนึ่ง คุณจะต้อง "ซ่อน" ช่องว่างเหล่านี้จนกว่าจะมีการดึงข้อมูล จากนั้นป็อปปูเลทและแสดงด้วยภาพเคลื่อนไหวของ UI ที่เหมาะสมเพื่อป้องกันไม่ให้เพจ "ข้ามไปข้ามมา" มากเกินไป