สร้างหน้าเว็บแบบกำหนดเองที่มีความยืดหยุ่นด้วย Craft CMS: เรื่องราวของเรา
ที่ Pipedrive เราใช้ Craft CMS ซึ่งเป็น ระบบโอเพ่นซอร์สเพื่อสร้างไซต์ Pipedrive สาธารณะ ของเรา เรามีกลุ่มองค์ประกอบที่เป็นของแข็ง เช่นHero block , Testimonial , Rich text , CTA block , และPricing block ของเรา เป็นต้น ด้วย Craft CMS ผู้จัดการเนื้อหาสามารถซ้อนส่วนประกอบคงที่เหล่านี้เพื่อสร้างเพจได้อย่างง่ายดายในเวลาไม่นาน ตัวอย่างเช่น ด้วยบล็อกฮีโร่ พวกเขาสามารถเลือกรูปภาพ เพิ่มข้อความ — และ voila ก็ดีไป! การตั้งค่านี้ทำงานได้ดี แต่ในไม่ช้าเราก็พบว่าปัญหากำลังก่อตัวขึ้น
ปัญหา
เนื่องจากส่วนประกอบไม่ยืดหยุ่น การปรับเปลี่ยนแม้แต่เล็กน้อยก็อาจใช้เวลานาน สิ่งที่ดูเหมือนง่ายอย่างการย้ายรูปภาพจากซ้ายไปขวาในบล็อกฮีโร่อาจใช้เวลานานกว่าหนึ่งสัปดาห์ บางครั้งก็นานกว่านั้น ขึ้นอยู่กับว่าขั้นตอนการพัฒนายุ่งแค่ไหน เพื่อรองรับเวอร์ชันต่างๆ เรามักจะสร้างส่วนประกอบใหม่ๆ ไม่จำเป็นต้องพูด นี่ไม่ใช่เวิร์กโฟลว์ที่มีประสิทธิภาพ โดยเฉพาะอย่างยิ่งเมื่อบริษัทของเราขยายตัว ไม่เพียงเพิ่มความซับซ้อนและความไร้ประสิทธิภาพ โดยไม่จำเป็นเท่านั้นแต่ยังกำหนดจำนวนคอลัมน์ในตารางเนื้อหาของเราที่พุ่งสูงขึ้นจนเกินขีดจำกัดของความอดทนของ MySQL เป็นที่ชัดเจนว่าอีกไม่นานเราจะไม่สามารถรองรับข้อกำหนดของผู้จัดการเนื้อหาของเราได้ สถานการณ์เหมือนระเบิดเวลาที่พร้อมจะระเบิด
ที่ Pipedrive เรามุ่งมั่นที่จะนำเสนอโซลูชันที่ปรับแต่งได้อย่างสมบูรณ์สำหรับผู้จัดการเนื้อหาของเรา ทำให้พวกเขาสามารถสร้างหน้าเว็บใหม่ได้อย่างรวดเร็วและง่ายดายโดยไม่ต้องพึ่งพาใดๆ ดังนั้นเราจึงเริ่มมองหาทางเลือกอื่นเพื่อเอาชนะข้อจำกัดนี้
เรามีข้อกำหนดที่ชัดเจนสำหรับการตั้งค่าของเรา:
- สามารถรองรับหน้าเว็บที่มีรูปแบบต่างๆเช่น บทความในบล็อก หน้า Landing Page บทความฐานความรู้ และอื่นๆ
- ให้อิสระแก่ผู้จัดการเนื้อหาในการสร้างสรรค์เค้าโครงและการออกแบบที่พวกเขาต้องการ
- ต้องมีวิธีรักษาความสอดคล้องกันของการออกแบบทั้งระบบ
- การแปลไซต์เพื่อรองรับการมีอยู่ทั่วโลกของเรา
- ระบบจะต้องสามารถรวมเข้ากับบริการของบุคคลที่สามได้
- การจัดการสินทรัพย์ที่ปรับแต่งได้ แต่มีคุณลักษณะหลากหลาย และ
- ปรับขนาด ปรับแต่งได้ง่าย และสามารถรองรับปริมาณการใช้งานที่หนาแน่นได้
เราใช้เวลาจำนวนมากในการตรวจสอบระบบ CMS ยอดนิยมต่างๆ พวกเขาทั้งหมดน่าทึ่งและแก้ปัญหาได้มากมาย แต่พวกเขายังคงต้องทำเครื่องหมายในช่องทั้งหมดของเราเกี่ยวกับความยืดหยุ่น การปรับแต่ง ความสะดวกในการใช้งาน และการผสานรวมที่ราบรื่นระหว่างระบบของเรา ความยืดหยุ่นที่ Craft CMS มอบให้นั้นไม่มีใครเทียบได้ ปัจจัยสำคัญอีกประการหนึ่งที่มีอิทธิพลต่อการตัดสินใจของเราคือความคุ้นเคยที่มีอยู่กับ Craft CMS เราจึงกลับไปใช้การตั้งค่าเดิมที่ไม่มีประสิทธิภาพและถามตัวเองว่า: เราตั้งค่าระบบปัจจุบันของเราถูกวิธีหรือไม่ คำตอบจ้องมองมาที่เราในช่วงไม่กี่ปีที่ผ่านมา: ไม่ เป็นเรื่องบังเอิญในช่วงเวลาเดียวกับที่ Craft CMS เปิดตัวเวอร์ชัน 3.5 RC ซึ่งเป็นการยกเครื่องครั้งสำคัญ ท่ามกลางการเปลี่ยนแปลงที่ยอดเยี่ยมอื่นๆ สิ่งที่ดึงดูดความสนใจของเราคือการเปลี่ยนแปลงใหม่ผู้ออกแบบเค้าโครงสนาม
ด้วยเวอร์ชันใหม่นี้ เราเริ่มเจาะลึกลงไปใน Craft CMS มากขึ้น ซึ่งช่วยให้ผู้จัดการเนื้อหาสามารถสร้างและแก้ไขหน้าเว็บได้อย่างง่ายดายโดยไม่ต้องสร้างฟิลด์ที่วกวนที่ยากจะเข้าใจ แม้ว่า Craft CMS จะนำเสนอประเภทฟิลด์ที่มีประสิทธิภาพ แต่เราต้องการบางสิ่งที่มากกว่านี้ นั่นคือตอนที่เราค้นพบปลั๊กอินcraft-neo มันเหมือนกับซูเปอร์ฮีโร่ที่ถลาเข้ามากอบกู้โลกและเปิดโลกใบใหม่แห่งความเป็นไปได้ ณ จุดนี้ เรามั่นใจเกี่ยวกับการสร้างสถาปัตยกรรมเว็บสาธารณะขึ้นใหม่ที่ตรวจสอบข้อกำหนดทั้งหมดของเราและยังใช้งานง่ายอีกด้วย
การปรับปรุง CMS และโครงสร้างของมันจะทำให้คอมโพเนนต์ UI ที่เราสร้างขึ้นเมื่อเวลาผ่านไปใช้ไม่ได้อย่างมีประสิทธิภาพ ดังนั้นเราจึงมองหาการปรับโครงสร้างใหม่ทั้งสแต็ก ไม่ใช่แค่ CMS
แผนการ
เราต้องการชิ้นส่วนเล็กน้อยเพื่อให้ระบบทำงานได้:
- ห้องสมุดการออกแบบ
- การตั้งค่า CMS;
- โพสต์โปรเซสเซอร์: การแปลและการปรับปรุงรายการอื่นๆ เสร็จสิ้นที่นี่ และ
- ตัวเรนเดอร์

การผสานรวมที่ราบรื่นแต่เหนียวแน่นระหว่าง CMS, ตัวเรนเดอร์ และไลบรารีการออกแบบเป็นสิ่งสำคัญ ในระหว่างขั้นตอนการวิจัย เราพิจารณาอย่างจริงจังว่าจะใช้วิธีการออกแบบปรมาณู ทั้งหมด ซึ่งเป็นแนวทางการออกแบบที่สร้างสรรค์ซึ่งได้รับแรงบันดาลใจจากเคมี แต่ท้ายที่สุดโมเดลองค์ประกอบแบบโมดูลาร์ทำให้สามารถควบคุมส่วนประกอบแต่ละชิ้นได้อย่างละเอียดยิ่งขึ้น ทำให้การผสมและจับคู่ส่วนประกอบเหล่านั้นง่ายขึ้นในการสร้างอินเทอร์เฟซแบบกำหนดเอง ควบคู่กับ Craft CMS ทำให้เรามีการปรับแต่งในระดับสูง นอกจากนี้ ไลบรารีคอมโพเนนต์แบบโมดูลาร์ยังมีประสิทธิภาพมากกว่าในแง่ของเวลาในการพัฒนาและการบำรุงรักษา
ข้อเสียอย่างหนึ่งของแนวทางนี้คือใช้เวลานานและต้องมีการวางแผนล่วงหน้าอย่างมาก ซึ่งอาจไม่เหมาะกับโครงการขนาดเล็ก โชคดีที่มันไม่ได้มีผลกับเรา
หลังจากการค้นคว้าและวางแผนอย่างละเอียด เราได้แบ่งการออกแบบออกเป็นชิ้นเล็กๆ เมื่อเรามีแผนมั่นคงแล้ว เราก็พับแขนเสื้อและสร้างส่วนประกอบเหล่านี้ เราเลือกสร้างด้วย React.js ด้วยเหตุผลสองสามข้อ ประการแรก React ถูกใช้อย่างกว้างขวางและแนะนำใน Pipedrive นอกจากนี้ ฟรอนต์เอนด์เฟรมเวิร์กที่เราเลือก Next.js นั้นสร้างขึ้นบน React ทำให้เหมาะกับโปรเจกต์ของเราโดยธรรมชาติ
เราได้แยกส่วนต่างๆ ของไลบรารีออกเป็นห้าส่วนหลัก:
- แกนหลัก:รากฐานของทุกสิ่งที่สร้างขึ้นในเว็บสาธารณะของเรา นี่เป็นสิ่งจำเป็นในการสร้างส่วนประกอบอื่นๆ
- องค์ประกอบ:แบบอย่างง่ายสำหรับเว็บ สิ่งเหล่านี้เป็นการดำเนินการของแกนหลักหรือการรวมกันขององค์ประกอบอื่น ๆ
- ส่วนประกอบ:หน่วยการสร้างที่ต้องการสิ่งห่อหุ้มรอบตัวและมีความหมาย สิ่งเหล่านี้อาจประกอบด้วยแกน องค์ประกอบ และส่วนประกอบอื่นๆ และ
- รูปแบบ:บล็อกขนาดใหญ่ที่จัดเรียงหรือเชื่อมต่อในลักษณะเฉพาะ

ตั้งค่า CMS: มาประดิษฐ์กันเถอะ!
ตลอดกระบวนการพัฒนา เรามุ่งเน้นไปที่ประเด็นสำคัญต่างๆ เช่น เค้าโครงฟิลด์ คอนเทนเนอร์ที่ใช้ซ้ำได้ ตัวแปรส่วนกลาง แท็ก เนื้อหาที่แปลเป็นภาษาท้องถิ่น การแสดงตัวอย่างหน้า จุดสิ้นสุดขององค์ประกอบ API เว็บฮุค การตรวจสอบความสมบูรณ์ ตัวบันทึก และอื่นๆ ต่อไปในบทความนี้ ผมจะเน้นไปที่รูปแบบฟิลด์และรายละเอียดว่าเราจัดการกับมันอย่างไร
หน้า Landing Page ต้องใช้ความพยายามส่วนใหญ่ของเราเนื่องจากไม่สามารถอยู่ในเลย์เอาต์เดียวได้ เราสร้างส่วนที่เรียกว่า "Landing" สำหรับสิ่งนั้น และเลย์เอาต์ของฟิลด์มีลักษณะดังนี้:
- เมตา : อธิบายตนเอง ระดับสูง อธิบายหน้านั้น
- เนื้อหา : รวมความสนุก! ส่วนประกอบถูกสร้างขึ้นที่นี่ และ
- SEO : ลบล้างการตั้งค่า SEO เริ่มต้นและเพิ่มข้อมูลที่เกี่ยวข้องเพิ่มเติม


เราสร้าง ตัวสร้างเนื้อหาทั้งหมดด้วยฟิลด์ใหม่ ซึ่งช่วยให้คุณสร้างบล็อกด้วยการตั้งค่าฟิลด์แยกต่างหาก บล็อกเหล่านี้สามารถมีลูกได้ ซึ่งเหมาะสำหรับโมเดลองค์ประกอบที่เราพยายามทำให้สำเร็จ
ต่อไปนี้คือตัวอย่างง่ายๆ ของการเพิ่มเค้าโครงสองคอลัมน์ด้วยปุ่มและข้อความ คอนเทนเนอร์ เป็น ส่วนประกอบระดับบนสุดที่เก็บกริด ตารางถูกสร้างขึ้นด้วยองค์ประกอบเค้าโครงสองส่วนที่เรียกว่าแถวและคอลัมน์ ควรเข้าใจได้ง่ายว่าข้อกำหนดการออกแบบส่วนใหญ่สามารถทำได้ด้วยการกำหนดค่าแถวและคอลัมน์

เราเผชิญกับความท้าทายเมื่อแสดงเส้นตารางระหว่างหน้าจอต่างๆ เราแก้ไขปัญหานี้โดยแบ่งวิวพอร์ตออกเป็นจำนวนคอลัมน์สูงสุดสำหรับแต่ละประเภท: เดสก์ท็อปแท็บเล็ตและมือถือ จำนวนคอลัมน์สูงสุดคือ 12, 6 และ 3

คุณสมบัติ Size กำหนดความกว้าง (คอลัมน์) ของคอลัมน์ที่สัมพันธ์กับหน้าจอ การเลือกจำนวนสูงสุดหมายความว่าจะใช้พื้นที่เต็มความกว้างของวิวพอร์ตเสมอ
ทุกคอมโพเนนต์ใน CMS มีข้อมูล อย่างน้อยสามส่วนที่แนบมาด้วย: Name , Properties and Children ค่า คุณสมบัติจะถูกส่งผ่านไปยังคอมโพเนนต์ UI ที่คู่กัน ในขณะที่Childrenเป็นคอมโพเนนต์อื่นๆ ที่ครอบคลุม (จำโมเดลการจัดองค์ประกอบที่เราพูดถึงก่อนหน้านี้ได้ไหม)
เมื่อบันทึกรายการแล้ว Craft จะส่งการแจ้งเตือนเว็บฮุคไปยังโปรเซสเซอร์พร้อมข้อมูลด้านล่าง (ฉันได้ตัดส่วนนี้ลงเพื่อให้เข้าใจโครงสร้างได้ง่ายขึ้น) Webhook เรียกใช้โปรแกรมสร้างซีเรียลไลเซอร์แบบกำหนดเองที่ค้นหา Craft และแปลงเป็นรูปแบบ JSON ที่มีโครงสร้างดี ซึ่งระบบอื่นๆ และตัวเรนเดอร์ส่วนหน้าสามารถเข้าใจได้ง่าย
{
"id": 123,
"title": "Test entry title",
"slug": "test-entry-title",
"enabled": true,
"structure": [{
"name": "container",
"properties": {
"theme": "default"
},
"children": [{
"name": "flexRow",
"properties": {
"horizontalAlign": {
"xs": "center",
"s": "center",
"m": "center"
},
"column_verticalAlign": {
"xs": "start",
"s": "start",
"m": "start"
},
"verticalGap": {
"xs": "none",
"s": "none",
"m": "none"
},
"direction": "row"
},
"children": [{
"name": "column",
"properties": {
"size": {
"xs": "3/3",
"s": "6/6",
"m": "12/12"
}
},
"children": [{
"name": "button",
"properties": {
"type": "primary",
"color": "default",
"size": "m",
"width": "auto"
},
"children": [
"Try it free"
]
}]
},
{
"name": "column",
"properties": {
"size": {
"xs": "3/3",
"s": "6/6",
"m": "12/12"
}
},
"children": [{
"name": "text",
"properties": {
"textAlignment": {
"xs": "left",
"s": "left",
"m": "left"
}
},
"children": [
"<p>Create the stages of your sales funnel or use an existing template. Add your deals or import them automatically from a spreadsheet or CRM.</p>"
]
}]
}
]
}]
}]
}
ตัวประมวลผลรายการจะแปล JSON นี้ เรียกใช้ขั้นตอนหลังการประมวลผลบางขั้นตอนด้านบน จากนั้นจัดเก็บไว้ในฐานข้อมูล ถัดไปคือส่วนสุดท้ายของปริศนา: ตัวเรนเดอร์
ตัวเรนเดอร์
เรามาถึงชิ้นส่วนสุดท้ายของปริศนาแล้ว และหน้าที่ของเราคือเชื่อมต่อทุกอย่างเข้าด้วยกัน เราเลือก Next.js สำหรับงาน เครื่องมือและคุณสมบัติที่สร้างไว้ล่วงหน้าของ Next.js นั้นน่าทึ่งมาก การมุ่งเน้นที่ประสิทธิภาพตั้งแต่เริ่มต้นเป็นสิ่งที่น่าสังเกตเป็นพิเศษ และเรายังชื่นชมความสะดวกสบายที่เพิ่มขึ้นในการเข้าถึงคะแนน Vitals ของเว็บหลักตามเวลาจริงผ่าน API
ตัวเรนเดอร์เป็นสะพานเชื่อมระหว่างไลบรารี UI และโครงสร้างคอมโพเนนต์ มันมีองค์ประกอบที่ซับซ้อนบางอย่างที่ไม่เข้ากับปรัชญาของไลบรารีการออกแบบ ส่วนประกอบดังกล่าวเป็นข้อยกเว้น และเราพยายามลดจำนวนส่วนประกอบดังกล่าวให้มากที่สุด
ความท้าทาย
- ยิ่งระดับของการปรับแต่งมากเท่าไหร่ ก็ยิ่งมีความซับซ้อนในการทำความเข้าใจมากขึ้นเท่านั้น มันต้องการความเข้าใจที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับระบบและกำหนดช่วงการเรียนรู้สำหรับผู้จัดการเนื้อหาใหม่ ดังนั้น สิ่งสำคัญคือต้องให้ทีมเนื้อหามีส่วนร่วมอย่างใกล้ชิดในการดำเนินการ รวบรวมความคิดเห็น สาธิต และทำซ้ำกระบวนการ
เพื่อลดความซับซ้อนของกระบวนการ เราได้สร้างส่วนประกอบ คอนเทนเนอร์ และบล็อกที่ใช้ซ้ำได้ ซึ่งสามารถสร้างครั้งเดียวและใช้ในหลายๆ หน้าได้ สิ่งนี้จะช่วยขจัดความยุ่งยากในการสร้างสิ่งเดิมซ้ำๆ - ระบบกลายเป็นขนาดใหญ่และใช้ทรัพยากรอย่างรวดเร็ว เราได้แก้ไขปัญหานี้โดยการปรับขนาดโครงสร้างพื้นฐานของระบบในแนวตั้ง ในขณะเดียวกันก็สำรวจตัวเลือกของการปรับขนาดในแนวนอนผ่านการใช้แคชส่วนกลางและกลไกการจัดเก็บเซสชันที่ Craft รองรับ
- มีจิ๊กซอว์ชิ้นหนึ่งที่ยังรอเราอยู่ นั่นคือเลย์เอาต์ที่ใช้ซ้ำได้ ในขณะที่ Craft CMS ให้ความยืดหยุ่นอย่างมาก เราไม่สามารถค้นหาประเภทฟิลด์มหัศจรรย์ที่จะช่วยให้เราสร้างเลย์เอาต์เพียงครั้งเดียวและใช้ซ้ำได้ในหลายรายการโดยการเลือกส่วนประกอบที่ต้องการ
การค้นหา CMS ที่เหมาะสมเพื่อรองรับความต้องการของธุรกิจของคุณอาจเป็นเรื่องที่ท้าทาย แม้ว่าระบบปัจจุบันอาจไม่สมบูรณ์แบบ แต่กำลังได้รับการแก้ไขและปรับปรุงอย่างต่อเนื่องเพื่อรองรับการออกแบบและความต้องการทางธุรกิจที่เปลี่ยนแปลงตลอดเวลาของเรา การเดินทางเพื่อค้นหาการตั้งค่าที่ถูกต้องสำหรับไซต์สาธารณะได้รับการพิสูจน์แล้วว่าเป็นประสบการณ์การเรียนรู้อันมีค่า และเราหวังว่าประสบการณ์ของเราจะช่วยให้ธุรกิจอื่นๆ ที่เผชิญกับความท้าทายที่คล้ายคลึงกัน