EN SeedWebs

Template tags ทั้งหมดและวิธีใช้

รายการ template tag ที่ระบบรองรับจริง รวมถึงการฝังวิดีโอและโพสต์โซเชียล พร้อมแอตทริบิวต์ ค่าเริ่มต้น ตัวอย่าง และตารางบอกว่าแท็กไหนใช้ได้ที่ไหน

ปรับปรุงล่าสุด 2026-10-08

Template tag คือข้อความในวงเล็บปีกกาคู่ เช่น {{site_name}} ที่ระบบแทนที่ด้วยข้อมูลจริงตอนสร้างหน้าเว็บ ใช้ในธีม (Header, Footer, Elements, Templates) และในเนื้อหาของ Pages

รายการในเอกสารนี้คือแท็กที่ใช้เขียนเนื้อหาและเทมเพลตหน้าเว็บทั้งหมด แท็กที่ไม่อยู่ในรายการนี้ระบบไม่รู้จัก ผลที่ได้คือถูกพิมพ์ออกหน้าเว็บตามตัวอักษรหรือถูกลบทิ้ง

ข้อยกเว้นเดียวคือ element ในแท็บ Nav ซึ่งมีชุดแท็กภายในของตัวเอง ({{items}}, {{columns}}, {{children}}, {{item.class}}, {{item.href}}, {{column.*}} และอื่น ๆ) ระบบเติมค่าให้เฉพาะตอนสร้างเมนู แท็กชุดนั้นไม่ทำงานที่อื่น และไม่ได้อยู่ในเอกสารนี้ วิธีที่ปลอดภัยคือแก้เฉพาะ class ในโค้ดที่ระบบติดตั้งมาให้ ไม่ต้องเพิ่มแท็กใหม่เอง

แก้ไขแท็กได้ที่ไหน

ไปที่ ตั้งค่า → ธีม (/admin/settings/themes) แล้วเลือกธีม จะพบแท็บ

แท็บใช้ทำอะไร
GeneralHeader HTML, Footer HTML, Global CSS, Global JS, Body class
Navelement ของเมนู (nav-item, nav-submenu, nav-mobile-item ฯลฯ)
Elementsชิ้นส่วนย่อยที่เรียกซ้ำได้ เช่น post-card
Templatesเทมเพลตหน้า เช่น post-list, post-detail, search-results
Emailsเทมเพลตอีเมล (แท็บนี้ปรากฏเฉพาะเว็บที่เปิดใช้ Newsletters)

การแก้ธีมจำกัดที่บทบาท super_admin และ admin (ดู ผู้ใช้และสิทธิ์) รายละเอียดโครงสร้างธีมและลำดับการค้นหาเทมเพลตอยู่ใน ธีมและเทมเพลต

ในหน้าแก้ไขธีม แถบด้านขวามีหัวข้อ ตัวเลือก (Options) → คู่มืออ้างอิงธีม ซึ่งเปิดหน้าต่างสรุปแท็กแบบย่อไว้ให้ดูระหว่างพิมพ์

กฎการเขียนแท็ก

  • รูปแบบคือ {{ชื่อแท็ก}} หรือ {{ชื่อแท็ก attr="ค่า"}} เขียนชื่อแท็กตัวพิมพ์เล็กตามที่ระบุในเอกสารนี้
  • ค่าแอตทริบิวต์ต้องอยู่ในเครื่องหมายคำพูดคู่ " เสมอ ยกเว้น limit และ offset ใน {{#each}} ที่ต้องเป็นตัวเลขล้วนไม่มีคำพูด (limit="12" ระบบจะไม่อ่านค่าและใช้ค่าเริ่มต้นแทน) ส่วน chars และ words ของ {{item.excerpt}} ใส่คำพูดหรือไม่ใส่ก็ได้
  • ใน {{#each}} ค่าแอตทริบิวต์ต้องไม่มีช่องว่าง ให้ใช้ slug เช่น category="how-to" ไม่ใช่ชื่อที่มีเว้นวรรค
  • แท็กที่ระบบไม่รู้จัก ถ้าอยู่ในเนื้อหา Page แบบชื่อเดียวโดด ๆ ({{foo}}) จะถูกลบทิ้ง แต่ถ้าอยู่ในธีมจะถูกพิมพ์ออกหน้าเว็บตามตัวอักษร
  • หลังบันทึกธีม หน้าเว็บสาธารณะมีแคช ปกติเห็นผลภายในประมาณหนึ่งนาที ถ้าอยากเร่ง กด ล้างแคช / รีบิลด์เว็บ ที่ ตั้งค่า → ทั่วไป (/admin/settings/general)

แท็กระดับเว็บไซต์

ใช้ใน Header และ Footer ของธีม

แท็กผลลัพธ์
{{site_name}}ชื่อเว็บจาก ตั้งค่า → ทั่วไป (แยกตามภาษา)
{{tag_line}}คำโปรยของเว็บ
{{year}}ปี ค.ศ. ปัจจุบัน เช่น 2026
{{locale}}รหัสภาษาของหน้านั้น เช่น en, th
{{locale_home}}ลิงก์หน้าแรกของภาษานั้น (/ หรือ /th/)
{{site_logo}}แท็ก <img> ของโลโก้ ถ้าไม่ได้ตั้งโลโก้จะได้ค่าว่าง
{{site_logo class="h-10" alt="ชื่อเว็บ"}}โลโก้พร้อมกำหนด class และ alt (ถ้าไม่ใส่ alt จะใช้ชื่อเว็บ)
{{site_logo_url}}URL ของไฟล์โลโก้อย่างเดียว
{{language_switcher}}ตัวสลับภาษาแบบ dropdown (ภาษาที่ใช้อยู่เป็นปุ่ม ภาษาอื่นเปิดลงมาเมื่อชี้เมาส์)
{{language_switcher class="..." activeClass="..."}}ตัวสลับภาษาแบบลิงก์เรียงกันธรรมดา ค่าเริ่มต้นของ activeClass คือ active

{{language_switcher}} แสดงผลเฉพาะเมื่อเว็บเปิดใช้มากกว่าหนึ่งภาษา ถ้ามีภาษาเดียวจะได้ค่าว่าง

{{site_name}}, {{tag_line}} และ {{year}} ใช้ในเนื้อหา Page ได้ด้วย

เงื่อนไขระดับเว็บไซต์

ใน Header และ Footer เขียนเงื่อนไขได้จากค่าเหล่านี้: site_logo, site_name, tag_line, favicon และ locale_<รหัสภาษา>

{{#if site_logo}}
  {{site_logo class="h-10"}}
{{else}}
  <span class="font-bold">{{site_name}}</span>
{{/if}}

{{#if locale_th}}ภาษาไทย{{else}}English{{/if}}

เมนู {{nav}}

ดึงลิงก์จากเมนูที่ตั้งใน ตั้งค่า → เมนู (/admin/settings/menus) ถ้ายังไม่ได้สร้างเมนู ระบบจะใช้ Page ที่เผยแพร่ระดับบนสุดบวกลิงก์ของ content type ที่เปิดใช้แทน

แอตทริบิวต์ผลลัพธ์
classclass ของ <ul> ที่ครอบ รวมกับค่าตั้งต้น flex items-center gap-1
itemClassclass ของลิงก์ <a> แต่ละอัน
activeClassclass ที่รวมทับ itemClass เมื่อลิงก์ตรงกับหน้าที่เปิดอยู่
location="mobile"เปลี่ยนเป็นเมนูแฮมเบอร์เกอร์แบบ drawer พร้อมเมนูย่อยแบบพับได้
menu="footer"เมนูที่มี slug นั้นแทนเมนูส่วนหัว (แท็บส่วนท้ายใน ตั้งค่า → เมนู พิมพ์แท็กพร้อม slug ไว้ให้) ระหว่างที่เมนูนั้นไม่มีอยู่ ยังเป็นฉบับร่าง หรือยังไม่มีรายการ จะแสดงเมนูส่วนหัวแทน
start, endแสดงเฉพาะรายการชั้นบนสุดตั้งแต่ลำดับที่ start ถึงลำดับที่ end นับจาก 1 เมนูย่อยไปกับรายการของมัน
{{nav class="flex items-center gap-2" itemClass="px-3 py-2 text-sm text-gray-600 hover:text-gray-900" activeClass="font-semibold text-gray-900"}}

{{nav location="mobile" itemClass="block px-4 py-3 text-base border-b border-gray-100"}}

location รับแค่ mobile ค่าอื่นทั้งหมด รวมถึง footer ไม่ได้ใช้เลือกเมนู แต่แสดงเมนูส่วนหัวเหมือนที่เคยเป็นมาตลอด ธีมที่เขียน {{nav location="footer"}} ไว้อยู่แล้วจึงแสดงผลเหมือนเดิม ถ้าจะวางเมนูอื่น ให้ระบุชื่อเมนู เช่น {{nav menu="footer"}} ส่วน {{nav mobile="true" menu="footer"}} คือเมนูนั้นแบบลิ้นชัก

start กับ end ใช้แบ่งเมนูชุดเดียว สำหรับส่วนหัวที่มีโลโก้อยู่ตรงกลาง

{{nav end="3"}} {{site_logo class="h-12"}} {{nav start="4"}}

ไม่ใส่ start แปลว่าเริ่มจากรายการแรก ไม่ใส่ end แปลว่าไปจนรายการสุดท้าย ช่วงที่เกินท้ายเมนูจะได้รายการว่าง ใช้คู่กับ menu="…" ได้ด้วย อ่านเพิ่มที่ เมนูและการนำทาง รวมถึงวิธีให้รายการโผล่เฉพาะบางภาษา

การรวม class ใช้ tailwind-merge จึงระบุเฉพาะส่วนที่ต่างได้ utility ที่ชนกันจะถูกแทนที่ให้เอง

แท็กเนื้อหา {{item.*}}

ใช้ใน Elements และ Templates ของธีม ทั้งในการ์ดที่อยู่ใน {{#each}} และในเทมเพลตหน้ารายละเอียด

ทุกคอลัมน์ของแถวข้อมูลเรียกได้ตรง ๆ เช่น {{item.title}}, {{item.slug}}, {{item.body}}, {{item.id}}, {{item.locale}}, {{item.view_count}}, {{item.seo_description}}

{{item.body}} และชื่อฟิลด์ที่ลงท้าย _html ถูกใส่ลงหน้าเป็น HTML ส่วนฟิลด์อื่นถูก escape ให้ปลอดภัย

ฟิลด์ที่ระบบคำนวณเพิ่มให้

แท็กผลลัพธ์
{{item.url}}ลิงก์สาธารณะของรายการ ใช้ได้ใน {{#each}} ของ posts, events, products, tours, books, staffs
{{item.excerpt}}ข้อความสรุปจาก body ตัดที่ราว 200 ตัวอักษร ถ้าเนื้อหามี <!--more--> จะตัดที่จุดนั้น
{{item.excerpt chars=120}}กำหนดความยาวเป็นจำนวนตัวอักษร เหมาะกับภาษาไทย
{{item.excerpt words=30}}กำหนดความยาวเป็นจำนวนคำ เหมาะกับภาษาอังกฤษ
{{item.date}}วันที่สร้าง เดือนแบบเต็ม ตามภาษาของเนื้อหา เช่น 8 มิถุนายน 2569
{{item.date_short}}วันที่สร้าง เดือนแบบย่อ เช่น 8 มิ.ย. 2569
{{item.date locale="th" style="short" order="dmy"}}บังคับภาษา (th, en), รูปเดือน (long ค่าเริ่มต้น, short), ลำดับ (dmy ค่าเริ่มต้น, mdy)
{{item.created_at_formatted}}เหมือน {{item.date}} เขียนชื่อเต็ม
{{item.created_at_formatted_short}}เหมือน {{item.date_short}}
{{item.updated_at_formatted}}ทุกคอลัมน์ที่ลงท้าย _at จะมีคู่ _formatted และ _formatted_short
{{item.read_time}}เวลาอ่านโดยประมาณ เป็นตัวเลขนาที
{{item.read_time_label}}ข้อความพร้อมใช้ เช่น อ่าน 5 นาที หรือ 5 min read
{{item.views_short}}ยอดวิวแบบย่อ เช่น 1.2K
{{item.views_formatted}}ยอดวิวแบบเต็มมีตัวคั่นหลักพัน เช่น 1,234
{{item.price_formatted}}ราคาที่จัดรูปแบบแล้ว เช่น ฿1,234 ตามสกุลเงินที่ตั้งไว้ในหน้าตั้งค่าร้านค้าแท็บ General (มีคู่ sale_price_formatted, amount_formatted)
{{item.in_stock}}เฉพาะสินค้า ค่าจะว่างเมื่อสินค้าถูกทำเครื่องหมายว่าหมด ใช้ {{#if item.in_stock}} แสดงปุ่มสั่งซื้อ และ {{#unless item.in_stock}} แสดงป้ายสินค้าหมด
{{item.stock_label}}เฉพาะสินค้า ว่างเมื่อสินค้าปกติ นอกนั้นเป็น out_of_stock หรือ on_backorder เอาไปทำ CSS class ได้
{{item.display_name}}ชื่อที่แสดง สร้างจาก first_name และ last_name เมื่อยังไม่มีค่า
{{item.initial}}อักษรตัวแรกของชื่อที่แสดง ใช้ทำ avatar ตัวอักษร

ทัวร์มีเพิ่ม {{item.adult_price_formatted}}, {{item.child_price_formatted}} (ใช้สกุลเงินของทัวร์นั้น) และ {{item.includes_html}}, {{item.excludes_html}} ที่แปลงรายการเป็น <ul> ให้แล้ว

รูปภาพและตัวแปรอัตโนมัติ

ฟิลด์ใดที่เก็บ URL รูป (.webp, .jpg, .jpeg, .png, .avif) จะได้แท็กเพิ่มสองตัวอัตโนมัติ

แท็กผลลัพธ์
{{item.featured_image}}URL รูปหลัก
{{item.featured_image_mobile}}ไฟล์ -sm ของรูปนั้น ถ้าไม่มีจะได้ URL รูปหลักเดิม
{{item.featured_image_srcset}}URL 1200w, URL-sm 768w ใช้กับแอตทริบิวต์ srcset — ถ้ารูปไม่มีไฟล์ -sm จะเหลือแค่ URL 1200w
<img src="{{item.featured_image}}" srcset="{{item.featured_image_srcset}}" alt="{{item.title}}" loading="lazy" />

ค่านี้สร้างจากการต่อชื่อไฟล์ ระบบไม่ได้ตรวจว่าไฟล์ -sm มีจริง ถ้ารูปนั้นไม่มีเวอร์ชันมือถือใน Media ลิงก์จะชี้ไปไฟล์ที่ไม่มีอยู่

Custom field

ฟิลด์ที่คุณสร้างเองเรียกด้วย {{item.field.<คีย์>}} และมีตัวแปรรูปเช่นเดียวกัน

{{#if item.field.brochure_image}}
  <img src="{{item.field.brochure_image}}" srcset="{{item.field.brochure_image_srcset}}" alt="" />
{{/if}}

{{item.field.xxx}} แยกช่องกับฟิลด์ปกติ ถ้าคุณมี custom field ชื่อ url ค่านั้นอยู่ที่ {{item.field.url}} ส่วน {{item.url}} ยังเป็นลิงก์ของรายการ

เรียกฟิลด์ที่ประกาศไว้ทั้งชุด — {{#each item.fields}}

ในหน้าบุคลากร ฟิลด์ทุกตัวที่ประกาศไว้ในหมวดของคนนั้น — รวมถึงหมวดแม่ของมัน — ถูกส่งมาเป็นลิสต์เดียว พร้อมป้ายชื่อและเรียงตามลำดับที่ประกาศไว้ เหมาะกับไดเรกทอรีที่มีฟิลด์สิบยี่สิบตัว ซึ่งการพิมพ์ {{item.field.x}} ทีละตัวทุกหมวดไม่ใช่การทำเทมเพลตอีกต่อไป

{{#if item.fields}}
  <dl>
    {{#each item.fields}}
      <div><dt>{{item.label}}</dt><dd>{{item.value}}</dd></div>
    {{/each}}
  </dl>
{{/if}}

ในลูป {{item.label}} คือป้ายชื่อจากที่ประกาศไว้ {{item.value}} คือค่าของคนนั้น {{item.key}} คือชื่อคีย์ และ {{item.group}} เป็น main หรือ sidebar ส่วน {{item.fields_main_label}} กับ {{item.fields_sidebar_label}} คือหัวข้อของสองกลุ่ม

ฟิลด์ที่ไม่มีค่าจะไม่อยู่ในลิสต์ ป้ายชื่อจึงไม่โผล่มาลอย ๆ โดยไม่มีค่าตามหลัง ฟิลด์ที่ปิด Public ไว้จะไม่ออกสู่หน้าเว็บเลย ส่วน repeater ไม่รวมอยู่ในลิสต์นี้ — ให้เขียนเองด้วย {{item.field.<คีย์>}} และ {{#each item.field.<คีย์>}}

การสืบทอดคือสิ่งที่ทำให้ใช้ได้กับหมวดแบบต้นไม้: ประกาศ Department ไว้ที่ Lecturer ครั้งเดียว คนที่อยู่ใต้ Bangkok หรือ Graduate ก็ได้ฟิลด์นั้นทั้งหมด หมวดลูกประกาศฟิลด์เดิมซ้ำเพื่อเปลี่ยน ป้ายชื่อได้ และยังคงอยู่ตำแหน่งเดิมตามที่หมวดแม่กำหนด

ลูปเดียวกันนี้ใช้ในการ์ดที่อยู่ใน {{#each staffs}} ได้ด้วย หน้าไดเรกทอรีจึงแสดงหน่วยงานใต้ชื่อคนได้

ประกาศฟิลด์ให้ตรงกับคอลัมน์ที่มีอยู่แล้วของบุคลากรก็ได้ — position, email, phone, display_name, first_name, last_name — แล้วมันจะอยู่ในลิสต์พร้อมป้ายชื่อเหมือนฟิลด์อื่น ส่วน notes ยังเป็นข้อมูลภายในไม่ออกหน้าเว็บ และประวัติให้ใช้ {{item.body}}

บันทึกภายใน (notes) ใช้บนหน้าเว็บสาธารณะไม่ได้เลย — ทั้งผ่านการประกาศฟิลด์ และทั้งเขียน {{item.notes}} ในเทมเพลตบุคลากรหรือในการ์ด เป็นคอลัมน์เดียวของบุคลากรที่เก็บไว้ให้ฝั่งแอดมินเท่านั้น

หน้าบุคลากรยังมีลำดับหมวดของคนนั้นตั้งแต่หมวดบนสุดลงมาถึงหมวดของตัวเอง พอสำหรับทำ breadcrumb ตามโครงหมวดที่วางไว้

<nav>
  <a href="{{locale_prefix}}/staffs">ทีมงาน</a>
  {{#each item.category_ancestors}}
    / <a href="{{locale_prefix}}/staff-categories/{{item.slug}}">{{item.name}}</a>
  {{/each}}
</nav>

{{item.category.slug}} กับ {{item.category.name}} คือหมวดของคนนั้นเดี่ยว ๆ

เทมเพลต Staff Detail ของธีม Default ทำให้แล้ว เว็บที่มีหมวดบุคลากรเป็นชั้น ๆ จึงได้ breadcrumb เลย ไม่ต้องแก้อะไร ส่วนหมวด Default ที่เป็นถังกลางจะไม่ถูกนับเป็นชั้นหนึ่ง — มันหมายถึง “ยังไม่จัดหมวด” เว็บที่ไม่ได้สร้างหมวดบุคลากรจึงยังเห็น Home / Team / <ชื่อ> เหมือนเดิม

หนึ่งคนอยู่ได้หลายหมวด (Staff ▸ แก้ไข ▸ อยู่ในหมวดเพิ่มเติม) จะโผล่ในหน้าหมวดเหล่านั้นทุกหน้า ส่วน breadcrumb ตามแค่หมวดหลัก (อันที่เลือกใน dropdown Category) เพราะ breadcrumb ต้องบอกเส้นทางเดียว

ผู้เขียน หมวดหมู่ แท็ก (โพสต์)

ในเทมเพลต post-detail และในการ์ดที่อยู่ใน {{#each posts}} มีข้อมูลเชื่อมโยงให้ใช้

{{#if item.author}}
  <a href="{{locale_prefix}}/authors/{{item.author.slug}}">
    <img src="{{item.author.avatar_url}}" alt="" />
    {{item.author.display_name}}
  </a>
{{/if}}

{{#each item.categories}}<span>{{item.name}}</span>{{/each}}
{{#each item.tags}}<span>#{{item.name}}</span>{{/each}}

{{#each item.coauthors}} ใช้ได้ในเทมเพลตหน้ารายละเอียดของโพสต์ ข้างในเรียก {{item.display_name}}, {{item.slug}}, {{item.avatar_url}} ได้เหมือนผู้เขียนหลัก

บนเว็บที่เปิด experimental {{#each item.tags}} เรียงแท็กของบทความตามลำดับที่ใส่ให้บทความนั้น ส่วนเว็บอื่นเรียงตามลำดับที่สร้างแท็ก

ที่อยู่หมวดหมู่แบบซ้อน เมื่อตั้ง Settings ▸ General ▸ Content URLs ▸ หมวดหมู่บทความ เป็น example.com/category/parent/child ให้ลิงก์หมวดหมู่ของโพสต์ด้วย {{item.url}} แทนการต่อ /category/{{item.slug}} เอง — {{item.url}} คือที่อยู่เต็มของหมวดในภาษาที่ผู้อ่านเปิดอยู่ ส่วนลิงก์ที่ต่อเองจะต้อง redirect ทุกครั้งที่คลิก และโพสต์ยังมีลำดับหมวดของหมวดแรกตั้งแต่หมวดบนสุดลงมา ไว้ทำ breadcrumb

{{#each item.categories}}<a href="{{item.url}}">{{item.name}}</a>{{/each}}

<nav>
  {{#each item.category_ancestors}}
    / <a href="{{item.url}}">{{item.name}}</a>
  {{/each}}
</nav>

ถ้าตั้งไว้แบบค่าเริ่มต้น (example.com/category/child) จะไม่มี item.category_ancestors และ {{item.url}} ของหมวดหมู่

หมวดหมู่และแท็กแยกตามภาษา (เว็บที่ย้ายมาจาก WordPress ที่ใช้ WPML) เมื่อตั้ง Settings ▸ General ▸ ภาษา ▸ หมวดหมู่และแท็ก เป็น แยกตามภาษา แท็กของโพสต์จะมี {{item.url}} ด้วย คือที่อยู่ของแท็กในภาษาที่ผู้อ่านเปิดอยู่ (/en/tag/video-streaming-2 สำหรับแท็กที่ที่อยู่ภาษาไทยคือ /tag/ding-yuxi) หรือที่อยู่ในภาษาของตัวเองถ้าแท็กนั้นไม่มีในภาษาที่เปิดอยู่ ให้ลิงก์แท็กด้วย {{item.url}} แทน /tag/{{item.slug}} ซึ่งเป็นที่อยู่ภาษาไทยเท่านั้น

{{#each item.tags}}<a href="{{item.url}}">#{{item.name}}</a>{{/each}}

เงื่อนไข {{#if}} และ {{#unless}}

{{#if item.featured_image}}<img src="{{item.featured_image}}" alt="" />{{/if}}

{{#if item.excerpt}}<p>{{item.excerpt}}</p>{{else}}<p>ยังไม่มีคำอธิบาย</p>{{/if}}

{{#unless item.avatar_url}}<div class="placeholder">{{item.initial}}</div>{{/unless}}

ค่าที่ถือว่าเป็นเท็จคือ ว่าง, ไม่มีค่า, false และ 0 {{#unless}} ไม่รองรับ {{else}}

ห้ามซ้อน {{#if}} ไว้ในอีก {{#if}} เพราะตัวแปลอ่าน {{/if}} ตัวแรกเป็นจุดปิด ถ้าต้องการเงื่อนไขซ้อน ให้แยกเป็น element แล้วเรียกด้วย {{> ...}}

ตอนบันทึก ระบบจะตรวจเงื่อนไขให้ ถ้าเทมเพลตที่กำลังบันทึกมี {{#if}} หรือ {{#unless}} ที่ประเมินไม่ได้ ระบบจะไม่ยอมบันทึก และบอกบรรทัดกับแท็กนั้น เช่น ชื่อสะกดผิด ({{#if categroy_body}} พร้อมคำแนะนำชื่อที่ถูก), ชื่อที่ใช้ได้เฉพาะที่อื่น ({{#if site_logo}} นอก header/footer), {{#unless}} ใน header, footer หรือ element เมนู, เงื่อนไขใดๆ ในเทมเพลตอีเมล, {{else if}} หรือบล็อกที่ไม่มีตัวปิด ถ้าไม่ตรวจ บล็อกแบบนี้จะแสดงบนหน้าเว็บเป็นตัวหนังสือ และเนื้อหาข้างในจะแสดงเสมอ ส่วนปัญหาที่มีอยู่แล้วในเวอร์ชันที่บันทึกไว้จะไม่ขวางการบันทึก ระบบจะแสดงเป็นคำเตือนแทน ให้แก้เมื่อสะดวก

วนซ้ำเนื้อหา {{#each}}

{{#each posts limit=12}}
  {{> post-card}}
{{/each}}

ชนิดที่ดึงข้อมูลได้: posts, events, products, tours, books, staffs ชื่ออื่นจะได้ผลว่าง

ในหกชนิดนี้ มีเพียง posts ที่ทุกเว็บใช้ได้ทันที products ต้องใช้แพ็กเกจ Pro หรือ Business (ดู แพ็กเกจและการชำระเงิน) ส่วน events, books, staffs, tours ต้องให้ทีมงานเปิดแฟล็ก experimental ให้เว็บของคุณก่อน (ดู สิ่งที่ยังไม่มีให้ใช้) ถ้ายังไม่ได้เปิดชนิดนั้นที่ ตั้งค่า → ทั่วไป → เมนูแอดมิน (Admin Menu) ลูปจะไม่แสดงอะไรเลยไม่ว่าจะเขียนไว้ที่ไหน และหน้ารายการกับหน้ารายละเอียดของชนิดนั้นจะตอบ 404 ส่วนลูป products เป็นไปตามสวิตช์ร้านค้า

แอตทริบิวต์ค่าเริ่มต้นใช้ได้กับ
limit=126ทุกชนิด
offset=30ทุกชนิด (ข้ามรายการแรก ๆ เช่นทำ featured แยก)
order="views"ตามชนิดค่าที่รับ: latest, oldest, title, title desc, views, price, price desc — price ใช้ได้กับ products เท่านั้น ชนิดที่ไม่มีราคาจะเรียงตามลำดับปกติของชนิดนั้น
category="news"ไม่กรองposts (รวมหมวดย่อย), products, tours, books
tag="featured"ไม่กรองposts
author="somchai"ไม่กรองposts
since="3m"ไม่กรองposts, events, products, tours
category="tech,business"—posts บนเว็บที่เปิด experimental: บทความในหมวดใดก็ได้ที่ระบุ (รวมหมวดย่อย) · เว็บอื่นถือว่าจุลภาคเป็นส่วนหนึ่งของชื่อหมวดเดียว
category="current"—posts ในเทมเพลตบทความ บนเว็บ experimental: บทความในหมวดใดก็ได้ของบทความที่กำลังแสดง (รวมหมวดย่อย) — แถว “บทความที่เกี่ยวข้อง” · ใส่ exclude="current" เพื่อตัดบทความตัวเองออก · บทความที่ไม่อยู่ในหมวดใด และในเนื้อหา Page หรือเทมเพลตของชนิดอื่น จะไม่กรองหมวด · เทมเพลตหน้ารวม (รายการบทความ หมวดหมู่ แท็ก ผู้เขียน และหน้ารวมตามวันที่) และเว็บอื่นถือว่า current เป็นชื่อหมวด
exclude_category="pr"ไม่กรองposts บนเว็บ experimental: ตัดบทความที่อยู่ในหมวดเหล่านี้ออก (คั่นด้วยจุลภาค · เฉพาะหมวดนั้น ไม่รวมหมวดย่อย)
exclude="current"ปิดposts ในเทมเพลตบทความ บนเว็บ experimental: ตัดบทความที่กำลังแสดงออก — แถว “บทความที่เกี่ยวข้อง” ที่ไม่มีบทความตัวเอง
page_param="query-7f09590f-page"ปิดposts ในเนื้อหา Page โหมด HTML บนเว็บ experimental: ลูปแสดงหน้าที่พารามิเตอร์ในที่อยู่นั้นขอ (?query-7f09590f-page=2) และ {{pagination}} ในเนื้อหาเดียวกันพิมพ์ลิงก์หน้าของลูปนี้ — ดู หน้าถัดไป ด้านล่าง
paginate="true"ปิดทุกชนิด — กำหนดว่าให้ {{pagination}} นับจำนวนหน้าจากลูปนี้

since รับรูปแบบ ตัวเลข + หน่วย โดยหน่วยคือ d (วัน), m (เดือน), y (ปี) เช่น 7d, 1m, 3m, 6m, 1y หน่วยสัปดาห์ไม่รองรับ

ลำดับเริ่มต้นเมื่อไม่ใส่ order: posts, products, tours เรียงใหม่สุดก่อน events เรียงตามวันเริ่มงานล่าสุดก่อน books เรียงตาม sort_order แล้วต่อด้วยใหม่สุด staffs เรียงตาม sort_order

การวนซ้ำดึงเฉพาะรายการที่สถานะ published (staffs ใช้ active) และเฉพาะภาษาของหน้าที่กำลังแสดง

ตัวอย่างที่ใช้จริงบ่อย

<div class="grid gap-6 sm:grid-cols-2 lg:grid-cols-3">
  {{#each posts limit=6 category="how-to" order="views" since="3m"}}
    {{> post-card}}
  {{/each}}
</div>

{{#each posts limit=1}}<article class="hero">{{item.title}}</article>{{/each}}
{{#each posts limit=6 offset=1}}{{> post-card}}{{/each}}

วนซ้ำที่ใช้ได้เฉพาะบางหน้า

แท็กใช้ในเทมเพลตหมายเหตุ
{{#each search}}search-resultsผลค้นหา ข้างในมี {{item.url}}, {{item.type}}, {{item.type_label}}, {{item.title}}, {{item.excerpt}}, {{item.featured_image}} โดย {{item.type}} เป็นคีย์ตายตัว (posts, products) เหมาะใช้กับ {{#if}} ส่วน {{item.type_label}} คือชื่อที่คุณตั้งให้ประเภทนั้นใน ตั้งค่า → ทั่วไป → เมนูแอดมิน ตามภาษาของหน้า ถ้าไม่ได้ตั้งไว้จะแสดงคีย์เดียวกับ {{item.type}}
{{#each authors}}author-listรายชื่อผู้เขียน 50 รายต่อหน้า เรียงตามชื่อที่แสดง แอตทริบิวต์ต่าง ๆ ไม่มีผลกับลูปนี้

เรียกชิ้นส่วนอื่น {{> slug}}

{{> post-card}} แทรก element หรือ template ที่ slug ตรงกัน โดยส่งข้อมูล item ชุดเดียวกันเข้าไปด้วย ถ้า slug ไม่มีอยู่จะได้ค่าว่าง

ซ้อนได้ชั้นเดียว ถ้าใน element ที่ถูกเรียกมี {{> ...}} อีกชั้น แท็กชั้นในจะไม่ถูกแทนที่

ในเทมเพลตหน้า Page เรียก {{header}} และ {{footer}} เพื่อวาง Header และ Footer ของธีมลงตรงจุดที่ต้องการ เทมเพลต page ที่ระบบติดตั้งมาใช้สองแท็กนี้อยู่แล้ว เมื่อเทมเพลตมีแท็กนี้ ระบบจะไม่ครอบ Header/Footer ให้อีกชั้น จึงไม่แสดงซ้ำ ในเทมเพลต landing ทั้งสองแท็กให้ค่าว่างเสมอ เพราะหน้าประเภทนั้นตั้งใจไม่มี Header/Footer

หน้าถัดไป {{pagination}}

{{pagination}}
{{pagination class="px-3 py-2 text-sm text-gray-500" activeClass="px-3 py-2 text-sm font-semibold bg-primary text-white"}}

ใช้ในเทมเพลตหน้ารายการทุกชนิด (post-list, event-list, product-list, book-list, staff-list, tour-list, author-list), เทมเพลตหน้าหมวดหมู่และแท็ก (category, tag, product-category, product-brand, tour-category, book-category) และ search-results ถ้าผลลัพธ์มีหน้าเดียวจะได้ค่าว่าง

ต้องเขียน class ก่อน activeClass ถ้าสลับลำดับ ระบบจะไม่รู้จักแท็กและพิมพ์ออกหน้าเว็บตามตัวอักษร

เลขหน้ามาจากลูปของรายการนั้นเอง — {{#each products}} ในหน้าสินค้า {{#each posts}} ในหน้าหมวดหมู่บทความ ลูปอื่นในเทมเพลตเดียวกัน เช่นบล็อกบทความด้านข้าง จึงไม่มีผลกับเลขหน้า ถ้าเทมเพลตวนรายการชนิดเดียวกันสองรอบด้วย limit= ต่างกัน ระบบจะยึดลูปที่แบ่งหน้าละน้อยกว่า เพราะเป็นลูปที่ผู้ใช้กดไล่ดูจริง ถ้าต้องการกำหนดเอง ใส่ paginate="true" ในลูปที่ต้องการให้เลขหน้าอ้างอิง

ในเนื้อหา Page (เว็บที่เปิดแฟล็ก experimental) Page โหมด HTML แบ่งหน้ากริดบทความได้แบบเดียวกับหน้า WordPress ที่สร้างด้วย GenerateBlocks คือใช้พารามิเตอร์ในที่อยู่ของตัวเอง

{{#each posts category="technology" limit=15 offset=5 page_param="query-7f09590f-page"}}
  {{> post-card}}
{{/each}}
{{pagination}}

/technology?query-7f09590f-page=2 แสดงบทความ 15 เรื่องถัดไป และ {{pagination}} (วางเหนือหรือใต้ลูปก็ได้) ลิงก์แต่ละหน้าเป็นที่อยู่ของ Page นั้นต่อด้วย ?query-7f09590f-page=N — หน้า 1 คือที่อยู่เปล่า ๆ ซึ่งเป็น canonical ของหน้าด้วย offset ยังข้ามบทความแรก ๆ ในทุกหน้า หน้าที่เกินหน้าสุดท้ายจะได้กริดว่าง ถ้าเนื้อหามีลูปแบบนี้มากกว่าหนึ่งลูป ใช้ {{pagination param="query-7f09590f-page"}} ระบุว่าลิงก์เป็นของลูปไหน และในกรณีนี้ class กับ activeClass เรียงลำดับใดก็ได้ เว็บอื่น หรือ Page โหมด Article แอตทริบิวต์นี้ไม่มีผล และ {{pagination}} เปล่า ๆ ในเนื้อหา Page จะไม่แสดงอะไร

จำนวนรายการทั้งหมด {{total}}

<p>สินค้าทั้งหมด {{total}} รายการ</p>

แสดงจำนวนรายการทั้งหมดของลิสต์นั้น ไม่ใช่จำนวนที่แสดงในหน้านั้น — หมวดที่มีสินค้า 3,755 ชิ้น จะพิมพ์ 3755 เหมือนกันทุกหน้า ซึ่งเป็นตัวเลขที่บรรทัดแบบ “กำลังแสดง 17–32 จาก 3,755 รายการ” ต้องใช้

ตัวเลขมาจากลูปเดียวกับที่ {{pagination}} ใช้นับหน้า ทั้งสองจึงตรงกันเสมอ คือลูป {{#each}} ของลิสต์นั้นเอง หรือลูปที่คุณกำกับ paginate="true" ไว้ ลูปอื่นในเทมเพลตเดียวกัน เช่น แถบบทความด้านข้าง ไม่มีผล

ใช้ได้ในทุกเทมเพลตลิสต์ ในเทมเพลตหมวดหมู่ แท็ก แบรนด์ ผู้เขียน และในหน้าผลการค้นหา — ซึ่ง {{result_count}} ที่ใช้ได้เฉพาะหน้าค้นหา พิมพ์ตัวเลขเดียวกัน

ถ้าเทมเพลตนั้นไม่มีลูปลิสต์เลย จะพิมพ์ 0

เรียงลำดับรายการจาก URL ด้วย ?orderby=

ผู้เข้าชมเรียงลำดับหน้ารายการได้จากพารามิเตอร์สองตัวบน URL

/product-categories/sound-system?orderby=price&order=asc
/product-categories/sound-system?orderby=price&order=desc
/products?orderby=title&order=asc

orderby รับ latest, oldest, title, price, views และ order รับ asc หรือ desc เขียนรวมเป็น ?orderby=price_desc ก็ได้ การเรียงเกิดขึ้นในฐานข้อมูลก่อนตัดหน้า ดังนั้นหน้า 2 จะต่อจากลำดับเดิม และลิงก์ทุกหน้าจะพาค่าการเรียงไปด้วย เมนู “เรียงตามราคา” จึงทำเป็นลิงก์ธรรมดาได้ ธีมไม่ต้องโหลดสินค้าทั้งหมวดมาเรียงเอง

price เรียงตามราคาที่การ์ดแสดง (ถ้ามีราคาลดจะใช้ราคาลด) สินค้าที่ไม่ได้กรอกราคาจะอยู่ท้ายสุดทั้งสองทิศทาง ถ้าสั่งเรียงด้วยฟิลด์ที่ชนิดนั้นไม่มี รายการจะคงลำดับปกติไว้

วิดเจ็ตพร้อมใช้

แท็กแอตทริบิวต์ค่าเริ่มต้นและหมายเหตุ
{{search_form}}class, placeholder, inputClass, buttonClassฟอร์มค้นหาส่งไปหน้า /search ของภาษานั้น ปุ่มมีไอคอนแว่นขยายที่รับสีจากข้อความรอบข้าง placeholder เริ่มต้น Search…
{{search_overlay}}buttonClass, iconColor, placeholder, theme, hint, hotkeyปุ่มแว่นขยายที่เปิดช่องค้นหาเต็มจอ theme รับ light (เริ่มต้น) หรือ dark hotkey="true" เปิด ⌘K / Ctrl+K แทรกครั้งเดียวแม้ใส่หลายที่
{{add_to_cart}}variant, class, product_id, title, price, urlในเทมเพลตสินค้า: กล่องสั่งซื้อ — ราคา ตัวเลือกสินค้า จำนวน และปุ่มหยิบใส่ตะกร้า ในการ์ดสินค้าใส่ variant="button" เป็นปุ่มหยิบทีเดียว (สินค้าที่มีตัวเลือกจะลิงก์ไปหน้าสินค้าแทน) อ่านสินค้าที่กำลังเรนเดอร์อยู่เอง จึงไม่ต้องใส่แอตทริบิวต์ตรงนั้น จะไม่แสดงอะไรเลยจนกว่าจะเปิดร้าน: ตั้งค่าร้าน → เปิดชำระเงิน และตั้งค่าช่องทางชำระเงินอย่างน้อยหนึ่งช่องทาง
{{mini_cart}}class, iconColor, href, drawerไอคอนตะกร้าพร้อมตัวเลขจำนวน สำหรับส่วนหัวเว็บ ลิงก์ไป /cart ใส่ drawer="true" เพื่อเปิดลิ้นชักตะกร้าแทน ตัวเลขถูกเติมในเบราว์เซอร์ จำนวนจึงไม่เคยถูกแคชติดไปกับหน้า
{{cart_drawer}}position, themeลิ้นชักตะกร้าที่เลื่อนออกด้านข้าง: รายการ ปุ่มเพิ่มลดจำนวน ยอดรวม ปุ่มดูตะกร้า / ชำระเงิน position รับ right (เริ่มต้น) หรือ left theme รับ light หรือ dark แทรกครั้งเดียว ถ้าเปิดร้านแล้วแต่ธีมไม่มีแท็กนี้ ระบบจะเติมให้เองก่อน </body>
{{floating_cart}}positionปุ่มตะกร้าทรงกลม (มุมล่างซ้ายเป็นค่าเริ่มต้น ใส่ position="bottom-right" เพื่อย้าย) ซ่อนเมื่อว่าง กดแล้วเปิดลิ้นชัก ตั้งค่าร้าน → ปุ่มตะกร้าลอย: auto แสดงเฉพาะเมื่อส่วนหัวไม่มี {{mini_cart}}, on แสดงเสมอ, off ไม่แสดง
{{cart_page}}—หน้าตะกร้าทั้งหน้า: รายการจากเบราว์เซอร์ของผู้ชม ปรับจำนวน ช่องโค้ดส่วนลด และยอดรวมที่ดึงจากร้านเป็นตัวจริง อยู่ในเทมเพลต cart ซึ่งเป็นสิ่งที่ /cart แสดง จะใส่อะไรล้อมรอบก็ได้
{{checkout_page}}—หน้าชำระเงินทั้งหน้า: ข้อมูลติดต่อ ที่อยู่จัดส่ง วิธีจัดส่ง (จากโซนจัดส่งของคุณ) วิธีชำระเงิน (จากช่องทางที่ตั้งค่าไว้) และปุ่มยืนยันคำสั่งซื้อ อยู่ในเทมเพลต checkout ซึ่งเป็นสิ่งที่ /checkout แสดง
{{subscribe_form}}class, interestsฟอร์มรับอีเมล ใส่ interests="posts,events" เพื่อผูกผู้สมัครกับความสนใจที่กำหนด
{{social_share}}networks, class, buttonClass, iconColornetworks รับ copy, facebook, x คั่นด้วยคอมมา ค่าเริ่มต้นคือทั้งสามอัน iconColor="primary" ใช้สีหลักของเว็บ ปุ่มคัดลอกจะโชว์ข้อความยืนยัน 2 วินาที
{{gallery}}cols, gap, lightbox, class, groupแกลเลอรีจากรูปที่แนบใน Page หรือ Post ค่าเริ่มต้นคือ 3 คอลัมน์ ระยะห่าง 3 และเปิด lightbox ปิดด้วย lightbox="false" แท็กนี้อ่านค่าที่อยู่ในคำพูดคู่เท่านั้น ให้เขียน cols="4" ไม่ใช่ cols=4
{{slider slug="hero"}}slug (ต้องมี) และคีย์ตั้งค่าใด ๆสไลด์จาก สไลเดอร์ (/admin/sliders) เขียนทับค่าที่ตั้งไว้ได้ เช่น autoplay="false", loop, arrows, dots, effect, speed, perView, gap, autoplaySpeed ระหว่างที่ปิดสไลเดอร์ไว้ที่ตั้งค่า → ทั่วไป → เมนูแอดมิน (Admin Menu) จะไม่แสดงอะไร และสไลเดอร์ที่ดึงบทความ สินค้า อีเวนต์ หนังสือ หรือทีมงาน จะไม่มีสไลด์ระหว่างที่ปิดชนิดนั้นไว้
{{ad slot="home-ads-1"}}slot (ต้องมี), class, imgClass, wrapClass, device, breakpoint, loading, limitโฆษณาที่กำลังลงในช่องนั้นจาก โฆษณา (/admin/ads): ลิงก์ครอบรูปที่สลับเป็นรูปมือถือที่จอ 767px (ย้ายจุดสลับได้ด้วย breakpoint="1023") · device="desktop" หรือ "mobile" แสดงรูปเดียว · wrapClass ครอบด้วย <div> เฉพาะตอนมีโฆษณา ช่องว่างจึงไม่ทิ้งที่ว่าง · ใช้ได้เฉพาะเว็บที่เปิด content type โฆษณา
{{form slug="contact"}}slug หรือ name, class, submitฟอร์มติดต่อจาก Forms (/admin/forms) ปุ่มส่งเริ่มต้นคำว่า Submit ถ้า slug ไม่มีอยู่หรือสถานะเป็น inactive จะได้ค่าว่าง และทุกฟอร์มจะได้ค่าว่างเช่นกันระหว่างที่ปิด Forms ไว้ที่ตั้งค่า → ทั่วไป → เมนูแอดมิน (Admin Menu)
{{chat_widget}}position, theme, welcomeปุ่มแชต AI แสดงเฉพาะเมื่อเปิด AI Features และใส่คีย์แล้วใน ตั้งค่า → ทั่วไป position รับ bottom-right (เริ่มต้น) หรือ bottom-left
{{cookie_consent}}ไม่มีแถบคุกกี้ แสดงเฉพาะเมื่อเปิดใช้ที่ ตั้งค่า → คุกกี้ (/admin/settings/cookies)
{{youtube}}url หรือ id (ต้องมี), modeวิดีโอ YouTube url รับที่อยู่แบบ watch, youtu.be, shorts, embed หรือ live ส่วน id คือรหัสวิดีโอ 11 ตัวอักษร mode="embed" (ค่าเริ่มต้น) แสดงภาพของวิดีโอ แล้วโหลดตัวเล่น (จาก youtube-nocookie.com) เมื่อกดเท่านั้น mode="link" เป็นการ์ดพร้อมภาพเล็กของวิดีโอที่เปิด YouTube ในแท็บใหม่ ทั้งสองแบบ ภาพของวิดีโอโหลดจากเซิร์ฟเวอร์รูปของ YouTube พร้อมหน้าเว็บก่อนผู้ชมกด ปุ่ม YouTube บนแถบเครื่องมือของตัวแก้ไขแบบ Article เขียนแท็กนี้ให้ ดูหัวข้อ วิดีโอและโพสต์โซเชียล ด้านล่าง
{{instagram}}, {{facebook}}, {{tiktok}}url (ต้องมี ส่วน {{tiktok}} ใช้ id แทนได้), mode, size, thumb, labelโพสต์หรือวิดีโอที่คุณเลือกทีละรายการ mode="link" (ค่าเริ่มต้น) เป็นการ์ดที่เปิดโพสต์ในแท็บใหม่ mode="embed" เป็นภาพปกที่โหลดตัวเล่นของเครือข่ายเมื่อกด size="fill" ให้กว้างเต็มคอลัมน์ ดูหัวข้อ วิดีโอและโพสต์โซเชียล ด้านล่าง
{{tiktok_profile}}user (ต้องมี), labelวิดีโอล่าสุดของบัญชี TikTok โหลดเมื่อกด และมีลิงก์ไปหน้าโปรไฟล์อยู่ด้านล่าง ดูหัวข้อ วิดีโอและโพสต์โซเชียล ด้านล่าง
{{map}}url (ต้องมี), labelแผนที่ Google url คือที่อยู่ใน src="…" ของโค้ดที่ Google Maps ให้มาจาก แชร์ → ฝังแผนที่ (ขึ้นต้นด้วย https://www.google.com/maps/embed?pb=) แผนที่โหลดจาก Google เมื่อกดเท่านั้น บล็อก Google Map ใน เพิ่มบล็อก → Contact มีแท็กนี้ให้แล้ว ดูหัวข้อ แผนที่ ด้านล่าง
{{social_feed}}source, limit, columns, gap, aspect, link, follow, follow_label, partเฉพาะเว็บที่อยู่ในเบต้าโซเชียลมีเดีย: โพสต์ที่ดึงมาล่าสุดเป็นกริดรูป ดูหัวข้อ กริดโพสต์ที่ดึงมาจากโซเชียล ด้านล่าง
{{pdf_button}}url (ต้องมี), label, modeปุ่มไปไฟล์ PDF mode="download" (ค่าเริ่มต้น) ดาวน์โหลดไฟล์ mode="view" เปิดในแท็บใหม่ ข้อความบนปุ่มเริ่มต้นเป็นภาษาไทยทุกหน้า (ดาวน์โหลด PDF, ดูเอกสาร PDF) หน้าภาษาอังกฤษจึงควรใส่ label

{{gallery}} มีพฤติกรรมพิเศษ: เมื่อเปิดสวิตช์แสดงแกลเลอรีในหน้าแก้ไข Page หรือ Post และในเนื้อหายังไม่มีแท็กนี้ ระบบจะต่อ {{gallery}} ท้ายเนื้อหาให้เอง ถ้าอยากคุมตำแหน่ง ให้พิมพ์แท็กเองกลางเนื้อหา

{{subscribe_form}} มีสองรูปแบบตามที่วาง ถ้าอยู่ใน Header หรือ Footer จะได้ฟอร์มที่ส่งแบบไม่รีเฟรชหน้า และเติม checkbox ความสนใจจากที่ตั้งไว้ให้เมื่อไม่ระบุ interests ถ้าอยู่ในเนื้อหา Page จะได้ฟอร์มส่งแบบปกติที่โหลดหน้าใหม่

ฟอร์มนี้จะแสดงและรับสมัครได้เฉพาะเมื่อเปิด จดหมายข่าว ไว้ที่ ตั้งค่า → ทั่วไป → เมนูแอดมิน (Admin Menu) ซึ่งเป็นสวิตช์เดียวกับที่เปิดหน้าจัดการ ผู้ติดตาม และ จดหมายข่าว ฟีเจอร์นี้จำกัดตามแพ็กเกจและต้องเปิดแฟล็ก experimental (ดู แพ็กเกจและการชำระเงิน) ถ้าปิดจดหมายข่าวไว้ แท็กนี้จะไม่แสดงอะไร จึงไม่มีการเก็บอีเมลที่คุณเปิดดูไม่ได้

{{chat_widget}} และ {{cookie_consent}} ถูกแทรกอัตโนมัติเมื่อเปิดใช้งานอยู่แล้วและธีมไม่มีแท็กนี้ จึงไม่จำเป็นต้องใส่ นอกจากต้องการกำหนดตำแหน่งหรือธีมสีเอง (ของแชตมีสวิตช์แยกสำหรับปิดการแทรกอัตโนมัติ ถ้าปิดไว้ต้องเขียนแท็กเอง)

ป้องกันบอทในฟอร์มและช่องสมัครรับข่าว

บอทกรอกฟอร์มได้โดยไม่ต้องเปิดหน้าเว็บของคุณเลย และส่งข้อมูลเดิมซ้ำเป็นร้อยครั้งจากหลายที่อยู่ IP ป้องกันบอท กันส่วนใหญ่ของสิ่งนี้ได้ เปิดได้ที่การ์ด ป้องกันบอท ด้านบนของหน้า ฟอร์ม → ฟอร์มทั้งหมด (/admin/forms) หรือหน้า จดหมายข่าว → ผู้ติดตาม ทั้งสองที่คือค่าเดียวกัน การ์ดนี้เห็นเฉพาะ Super Admin และ Admin และทุกเว็บปิดไว้จนกว่าคุณจะเปิดเอง

เมื่อเปิดแล้ว:

  • ผู้เข้าชมไม่เห็นอะไรเปลี่ยน ตอนที่มีคนเริ่มกรอกฟอร์ม หน้าเว็บจะขอบัตรผ่านแบบใช้ครั้งเดียวของฟอร์มนั้นไว้เงียบ ๆ ข้อมูลที่ส่งมาโดยไม่มีบัตรผ่านที่ถูกต้อง เช่นจากบอทที่ไม่เคยเปิดหน้าเว็บ หรือบอทที่ใช้บัตรผ่านซ้ำ จะได้คำตอบเหมือนส่งสำเร็จ แต่จะไม่ถูกบันทึก ไม่มีอีเมล และไม่ส่งต่อไป form webhook ส่วนช่องสมัครรับข่าวก็ยังพากลับไปหน้าเดิมพร้อม subscribed=1 ตามปกติ
  • จำนวนวินาทีขั้นต่ำ (1–30 ค่าเริ่มต้น 3) คือเวลาน้อยที่สุดตั้งแต่เริ่มกรอกจนถึงตอนส่ง ถ้าคนจริงกรอกเร็วกว่านั้นจะไม่ถูกปฏิเสธ ระบบจะรอให้ครบเวลาก่อนแล้วค่อยส่งให้
  • ถ้าส่งคำตอบเดิมเข้าฟอร์มเดิมซ้ำภายใน 24 ชั่วโมง จะบันทึกไว้ครั้งเดียว กดปุ่มส่งสองครั้งก็ไม่เกิดรายการซ้ำ
  • ใช้ได้กับ {{form}} {{subscribe_form}} และฟอร์มที่คุณเขียนเองในธีม ขอแค่ส่งไปที่ /api/public/forms/… หรือ /api/public/subscribe
  • ใช้ได้เฉพาะบนหน้าเว็บของคุณเอง สคริปต์หรือเว็บอื่นที่ส่งข้อมูลตรงไปยังที่อยู่เหล่านั้น ต้องขอบัตรผ่านจาก /api/public/form-token?k=subscribe ก่อน (หรือ ?k= ตามด้วย slug ของฟอร์ม) รออย่างน้อยตามจำนวนวินาทีขั้นต่ำ แล้วส่ง token ที่ได้มาในช่องชื่อ _bt บัตรผ่านหนึ่งใบใช้ส่งได้ครั้งเดียว

มีขีดจำกัดเสริมอีกสองค่าที่นับรวมผู้เข้าชมทุกคน ไว้รับมือบอทที่เปลี่ยนที่อยู่ IP ไปเรื่อย ๆ เว้นว่างไว้ถ้าไม่ต้องการจำกัด ทั้งสองค่ามีผลแม้ปิดสวิตช์ป้องกันบอทไว้ และเมื่อถึงขีดจำกัดแล้ว คนจริงก็จะถูกปฏิเสธด้วย จนถึงชั่วโมงถัดไป ตั้งเฉพาะเมื่อจำเป็น เพราะฟอร์มลงทะเบียนงานอีเวนต์อาจมีคนส่งพร้อมกันเยอะจริง ๆ:

  • จำกัดรวมทุกคน (ต่อชั่วโมง) ในการตั้งค่าของแต่ละฟอร์ม หัวข้อ ไฟล์แนบและขอบเขต ข้างช่องจำกัดต่อ IP เมื่อเกินแล้วฟอร์มจะตอบว่ามีคนส่งมากเกินไป
  • จำนวนการสมัครรับข่าวต่อชั่วโมง (รวมทุกคน) ในการ์ดป้องกันบอท สำหรับช่องสมัครรับข่าว

สไลเดอร์ที่ดึงบทความมาแสดง

สไลเดอร์ที่ตั้ง Source เป็น Posts (สไลเดอร์ → แก้ไขสไลเดอร์) จะสร้างหนึ่งสไลด์ต่อบทความหนึ่งเรื่อง ใต้การตั้งค่า source มีสองอย่างที่เพิ่มเข้ามาในเดือนตุลาคม 2026 สไลเดอร์ที่บันทึกไว้ก่อนหน้านั้นจะยังไม่ได้เปิดทั้งสองอย่าง และแสดงผลเหมือนเดิมทุกอย่างจนกว่าคุณจะแก้

เลือกบทความ มีรายการหมวดหมู่สองชุด

  • เฉพาะหมวดหมู่เหล่านี้ — บทความที่อยู่ในหมวดใดก็ได้ที่ติ๊กไว้ รวมหมวดย่อยด้วย ถ้าไม่ติ๊กเลยจะแสดงบทความทั้งหมด
  • ไม่รวมหมวดหมู่เหล่านี้ — ตัดบทความที่อยู่ในหมวดที่ติ๊กไว้ออก (เฉพาะหมวดนั้น ไม่รวมหมวดย่อย)

Limit และ Order ยังใช้ได้ตามเดิม และสไลเดอร์จะแสดงบทความภาษาเดียวกับหน้าที่วางสไลเดอร์ไว้เสมอ ถ้าสไลเดอร์มีค่าที่เคยพิมพ์ไว้ในช่อง “Category slug” แบบเดิม จะแสดงไว้เหนือรายการเป็นค่าเดิม ค่านี้ไม่เคยกรองสไลเดอร์และตอนนี้ก็ยังไม่กรอง ให้ลบออก หรือติ๊กหมวดที่ต้องการแทน

เติมข้อมูลสไลด์แบบการ์ดใน posts loop ถ้าติ๊กไว้ (สไลเดอร์ใหม่และ template Posts carousel ติ๊กให้แล้ว) Item template จะเขียนแบบเดียวกับการ์ดใน {{#each posts}} ใช้แท็กชุดเดียวกัน

<a href="{{item.url}}">
  <img src="{{item.featured_image}}" srcset="{{item.featured_image_srcset}}" alt="{{item.title}}">
  {{#if item.categories}}<span>{{item.categories.0.name}}</span>{{/if}}
  <h2>{{item.title}}</h2>
  <p>{{item.excerpt}}</p>
</a>

{{item.url}} คือที่อยู่ของบทความ {{item.featured_image}} และ {{item.featured_image_srcset}} คือรูปปก {{item.excerpt}} คือคำโปรยที่เขียนไว้ (ถ้าไม่ได้เขียนจะตัดจากเนื้อหาให้) {{item.date}} คือวันที่ของบทความ {{item.categories.0.name}} คือหมวดหลักของบทความ ส่วน {{#each item.categories}}{{item.name}}{{/each}} แสดงทุกหมวด ถ้าไม่ได้ติ๊ก สไลด์จะได้ข้อมูลบทความตามที่เก็บไว้ {{item.featured_image}} เป็นตัวเลข ไม่ใช่ที่อยู่รูป และไม่มีคำโปรยหรือวันที่ สไลเดอร์ที่ source เป็น Products, Events, Books หรือ Staff ก็ทำงานแบบนี้เช่นกัน

ฟอร์มจองทัวร์

{{book_tour_form}} ใช้ได้เฉพาะในเทมเพลตหน้ารายละเอียดทัวร์ (tour-detail-page หรือ tour-detail) ต้องส่ง tour_id ถ้าไม่มีจะได้ค่าว่าง เทมเพลตที่ระบบติดตั้งมาเขียนไว้แล้วแบบนี้

{{book_tour_form tour_id="{{item.id}}" tour_slug="{{item.slug}}" tour_title="{{item.title}}" currency="{{item.currency}}" adult_price="{{item.adult_price}}" child_price="{{item.child_price}}"}}

ถ้ายังไม่ได้ตั้งช่องทางชำระเงิน วิดเจ็ตจะแสดงข้อความแจ้งแทนฟอร์ม ทัวร์เป็นฟีเจอร์ที่เปิดเฉพาะเว็บที่ทีมงานเปิดแฟล็ก experimental ให้ (ดู สิ่งที่ยังไม่มีให้ใช้)

ข่าวประชาสัมพันธ์จากฟีดภายนอก {{external_feed}}

เว็บที่ทีม SeedWebs เปิดฟีเจอร์ทดลองและตั้งฟีดไว้ให้แล้ว (ตั้งค่า ▸ ทั่วไป ▸ ฟีดภายนอก) ใส่ {{external_feed feed="dataxet_pr" lang="th" limit="50"}} ในเนื้อหาหน้า จะแสดงข่าวประชาสัมพันธ์ล่าสุดจากฟีดนั้น ระบบดึงจากผู้ให้บริการทุกครั้งที่สร้างหน้า และเก็บไว้ไม่กี่นาที (ค่าเริ่มต้น 5 นาที) ข่าวใหม่จึงขึ้นเองโดยไม่ต้องมีใครแก้เว็บ แอตทริบิวต์: feed (ต้องมี ชื่อฟีด), lang (th หรือ en ค่าเริ่มต้นคือภาษาของหน้า), limit (1–50 ค่าเริ่มต้น 10), columns (1–3 ค่าเริ่มต้น 1) และ part / empty / error สำหรับใช้ Element ของคุณเองแทนหน้าตาที่ระบบมีให้ (part="pr-list-th" จะหา pr-list-th-empty และ pr-list-th-error ให้ด้วย) Element ของคุณได้รายการเป็น {{#each item.items}}…{{/each}} ข่าวแต่ละชิ้นมี {{item.headline}}, {{item.url}}, {{item.excerpt}}, {{item.date}} (และ date_th, date_en), {{item.display_time}} และ {{item.doc_id}} ข่าวแต่ละชิ้นยังมีหน้าของตัวเองตามที่อยู่ของฟีด เช่น /pr-th/<id>/ เว็บอื่น และฟีดที่ปิดสวิตช์อยู่ จะเห็นแท็กนี้ตามที่พิมพ์ไว้

วิดีโอและโพสต์โซเชียล

{{youtube}}, {{instagram}}, {{facebook}} และ {{tiktok}} แสดงวิดีโอหรือโพสต์ที่คุณเลือกทีละรายการ ส่วน {{tiktok_profile}} แสดงวิดีโอล่าสุดของบัญชี TikTok ใช้ได้ทุกเว็บ ไม่ต้องเชื่อมบัญชี บล็อกสำเร็จรูปหมวด Social ใน เพิ่มบล็อก (Add Block) ของ HTML Builder คือกริดสำเร็จรูปของแท็กเหล่านี้ และมีบล็อก YouTube video สำหรับวิดีโอหนึ่งคลิปด้วย (ดู เชื่อมโซเชียลมีเดีย) ในตัวแก้ไขแบบ Article แค่วางที่อยู่ไว้บรรทัดว่างก็ได้ (ดูหัวข้อ วางที่อยู่ในตัวแก้ไขแบบ Article ด้านล่าง)

{{instagram url="https://www.instagram.com/reel/AbC123/" mode="embed" size="fill"}}
{{facebook url="https://www.facebook.com/yourpage/posts/123" label="Our Songkran sale"}}
{{tiktok url="https://www.tiktok.com/@yourshop/video/7291234567890123456" mode="embed"}}
{{tiktok_profile user="yourshop"}}
{{youtube url="https://www.youtube.com/watch?v=dQw4w9WgXcQ"}}
  • url คือที่อยู่ของโพสต์บน instagram.com (ที่อยู่แบบ /p/, /reel/ หรือ /tv/), facebook.com หรือ fb.watch หรือ tiktok.com (ที่อยู่ที่มี /video/) ที่อยู่บนเว็บอื่นจะไม่แสดงอะไร ที่อยู่ Instagram หรือ TikTok ที่ไม่ใช่โพสต์ เช่น หน้าโปรไฟล์หรือหน้าค้นหา ก็ไม่แสดงอะไรเช่นกัน ลิงก์สั้น vt.tiktok.com จากแอป TikTok ก็ไม่แสดงอะไร ให้เปิดลิงก์นั้นในเบราว์เซอร์ก่อนแล้วคัดลอกที่อยู่ที่ขึ้นมา {{tiktok}} ใส่แค่เลขวิดีโอใน id ก็ได้ ถ้าใช้ {{facebook}} กับ mode="embed" ให้ใช้ที่อยู่ของโพสต์จากแถบที่อยู่ของเบราว์เซอร์ (ที่มี /posts/ หรือ /videos/) แทนที่อยู่จาก แชร์ → คัดลอกลิงก์ (ที่มี /share/) ส่วนการ์ดลิงก์ใช้ได้ทั้งสองแบบ
  • สำหรับ {{instagram}}, {{facebook}} และ {{tiktok}} mode="link" (ค่าเริ่มต้น) เป็นการ์ดที่เปิดโพสต์ในแท็บใหม่ และไม่โหลดอะไรจากเครือข่าย mode="embed" เป็นภาพปกที่มีตัวเล่นของเครือข่ายอยู่ข้างหลัง ไม่มีอะไรจาก Instagram, Facebook หรือ TikTok โหลดจนกว่าผู้ชมจะกด และภาพปกบอกไว้ว่าเมื่อกด ระบบจะโหลดเนื้อหาจากเครือข่ายนั้น ซึ่งอาจมีการใช้คุกกี้ หลังกด เครือข่ายจะรู้ด้วยว่าเปิดจากหน้าไหน ถ้ากด Ctrl หรือ ⌘ ค้างไว้ตอนคลิก จะเปิดโพสต์ในแท็บใหม่แทน
  • ตัวเล่นแต่ละแบบมีความกว้างขั้นต่ำ Instagram 326px โพสต์ Facebook 350px และ {{tiktok_profile}} 288px ถ้าจอแคบกว่านั้น การกดภาพปกจะเปิดโพสต์บนเครือข่ายในแท็บใหม่แทน ในกริด ภาพปก Instagram ควรอยู่ในคอลัมน์กว้างอย่างน้อย 340px และให้ใช้ mode="link" กับ Facebook
  • size="fill" ให้การ์ดหรือภาพปกกว้างเต็มคอลัมน์ ใช้กับกริด ถ้าไม่ใส่ การ์ดกว้างไม่เกิน 420px ส่วนภาพปกกว้างไม่เกิน 480px (Instagram), 500px (Facebook) หรือ 340px (TikTok) และอยู่กึ่งกลาง
  • thumb คือภาพปก ใส่ที่อยู่ของรูปในคลังสื่อของคุณเอง เช่น รูปของคุณ หรือภาพจากวิดีโอของคุณเอง ห้ามใช้ภาพแคปหน้าจอโพสต์ของคนอื่น ที่อยู่รูปบน Instagram, Facebook, TikTok หรือ YouTube จะถูกข้าม เพราะจะติดต่อเครือข่ายก่อนผู้ชมกด ถ้าไม่ใส่ thumb ภาพปกจะเป็นกรอบสีเทาอ่อนพร้อมข้อความ
  • label คือข้อความบนการ์ด ค่าเริ่มต้นคือ “ดูวิดีโอบน Instagram” สำหรับวิดีโอ (reel, วิดีโอ TikTok, วิดีโอ Facebook) และ “ดูโพสต์บน Instagram” สำหรับโพสต์อื่น เป็นภาษาไทยในหน้าภาษาไทย และเป็นภาษาอังกฤษในหน้าภาษาอื่นทุกภาษา ควรใส่ label ของแต่ละโพสต์เอง เช่น สิ่งที่อยู่ในโพสต์ ไม่อย่างนั้นการ์ดและภาพปกทุกใบในหน้าจะอ่านได้เหมือนกันหมด รวมถึงเมื่อฟังด้วยโปรแกรมอ่านหน้าจอ

{{youtube}} รับแค่ url หรือ id และ mode ค่าเริ่มต้นคือ mode="embed" ซึ่งตัวเล่นจะรอจนกว่าจะกด ทั้งสองแบบ ภาพของวิดีโอโหลดจากเซิร์ฟเวอร์รูปของ YouTube พร้อมหน้าเว็บก่อนผู้ชมกด mode="link" จึงไม่ได้ช่วยให้ไม่ติดต่อ YouTube

{{tiktok_profile user="yourshop"}} แสดงวิดีโอล่าสุดของบัญชีไม่เกิน 10 คลิป (TikTok เป็นคนเลือก) ในกล่องของ TikTok เอง โหลดเมื่อผู้ชมกดภาพปก user คือชื่อผู้ใช้ จะมี @ หรือไม่ก็ได้ หรือใส่ที่อยู่โปรไฟล์ https://www.tiktok.com/@yourshop ก็ได้ ชื่อที่ไม่ใช่ชื่อผู้ใช้ TikTok ที่ถูกต้องจะไม่แสดงอะไร ควรวางเต็มความกว้างของหน้า บัญชีส่วนตัว บัญชีอายุต่ำกว่า 18 ปี หรือบัญชีที่ยังไม่ได้ตั้งอายุ จะขึ้นการ์ดส่วนตัวของ TikTok แทน และชื่อที่ TikTok ไม่รู้จักจะขึ้นว่า “Profile not available” ส่วนลิงก์ ดู @yourshop บน TikTok ใต้กล่องใช้ได้เสมอ label ใช้เปลี่ยนข้อความบนภาพปก

เขียนแท็กแต่ละอันไว้บรรทัดของตัวเอง พิมพ์หรือวางแท็กได้ทั้งในตัวแก้ไขแบบ Article ในบทความแบบ Markdown และใน HTML Builder ในลูป {{#each}} ของเนื้อหา Page แท็กใช้ฟิลด์ของการ์ดไม่ได้ url="{{item.field.ig}}" จะไม่แสดงอะไร

พิมพ์เครื่องหมายคำพูดเป็นแบบตรง " ส่วนแบบโค้ง (“ ”) ที่คีย์บอร์ดมือถือมักพิมพ์ให้ ใช้ได้เฉพาะเมื่อเครื่องหมายคำพูดทุกตัวในแท็กเป็นแบบโค้ง ถ้าแท็กมีทั้งสองแบบปนกัน ระบบจะอ่านแค่คู่ที่เป็นแบบตรง ในบทความแบบ Markdown อย่าใส่ * หรือ _ ใน label เพราะ Markdown จะแปลงเป็นตัวหนาหรือตัวเอียง แล้วการ์ดจะแสดงโค้ด HTML เช่น <em> ออกมาด้วย

วางที่อยู่ในตัวแก้ไขแบบ Article

ในตัวแก้ไขแบบ Article ถ้าวางที่อยู่ของวิดีโอ YouTube โพสต์หรือ reel ของ Instagram โพสต์หรือวิดีโอ Facebook วิดีโอ TikTok หรือโปรไฟล์ TikTok ไว้ในบรรทัดว่างโดยไม่มีอย่างอื่น ที่อยู่นั้นจะกลายเป็นแท็กของมัน แบบเดียวกับที่ปุ่ม YouTube บนแถบเครื่องมือเขียนให้ เช่น {{youtube url="…"}} หรือ {{instagram url="…" mode="embed"}} (ที่อยู่ Facebook จาก แชร์ → คัดลอกลิงก์ จะเป็นการ์ดลิงก์ mode="link") แล้วเคอร์เซอร์จะย้ายไปบรรทัดถัดไป ถ้าอยากได้เป็นลิงก์ธรรมดา ให้กด Ctrl+Z (⌘Z บน Mac) หนึ่งครั้ง ที่อยู่ที่วางกลางประโยค ในรายการ (list) หรือในตาราง จะยังเป็นลิงก์ เช่นเดียวกับที่อยู่ที่ไม่มีแท็กใดแสดงได้ เช่น ลิงก์สั้น vt.tiktok.com หรือ maps.app.goo.gl หน้าเพจหรือโปรไฟล์ Facebook หรือเว็บอื่นอย่าง Vimeo การวางในบทความแบบ Markdown หรือใน HTML Builder ไม่แปลงให้ ให้พิมพ์แท็กเอง

แผนที่ {{map}}

{{map url="https://www.google.com/maps/embed?pb=!1m18!1m12…" label="ร้านของเราที่สุขุมวิท"}}

วิธีเอาที่อยู่: เปิดสถานที่ใน Google Maps เลือก แชร์ → ฝังแผนที่ แล้วคัดลอกที่อยู่ระหว่างเครื่องหมายคำพูดของ src="…" ในโค้ดที่ขึ้นมา ซึ่งขึ้นต้นด้วย https://www.google.com/maps/embed?pb= ในตัวแก้ไขแบบ Article จะวางโค้ดทั้งก้อนที่ Google ให้มา (<iframe …></iframe>) ไว้ในบรรทัดว่างแทนก็ได้ ระบบจะแปลงเป็นแท็กให้ ที่อยู่แบบอื่นจะไม่แสดงอะไร เช่น ลิงก์สั้น maps.app.goo.gl ที่อยู่จากแถบที่อยู่ของเบราว์เซอร์ หรือแผนที่ที่สร้างใน Google My Maps

แผนที่กว้างเต็มคอลัมน์ สัดส่วน 16:9 และสูงอย่างน้อย 300px เหมือนภาพปกของโพสต์โซเชียล ไม่มีอะไรโหลดจาก Google จนกว่าผู้ชมจะกด ภาพปกมีหมุด ข้อความจาก label (ค่าเริ่มต้นคือ “ดูแผนที่” ในหน้าภาษาไทย และ “View the map” ในหน้าภาษาอื่น) และข้อความบอกว่าเมื่อกด ระบบจะโหลดเนื้อหาจาก Google Maps ซึ่งอาจมีการใช้คุกกี้ ถ้ากด Ctrl หรือ ⌘ ค้างไว้ตอนคลิก จะเปิดแผนที่ในแท็บใหม่ บล็อก Google Map ใน เพิ่มบล็อก → Contact ของ HTML Builder มีแท็กนี้รอให้ใส่ที่อยู่ ถ้าต้องการให้แผนที่แสดงทันทีโดยไม่ต้องกด ให้วางโค้ดของ Google ลงในหน้าที่ใช้ HTML Builder แทน

บทความที่ย้ายมาจาก WordPress

บทความที่นำเข้าจาก WordPress ยังมีบล็อกฝัง (embed) ของ WordPress อยู่ ซึ่งเก็บไว้แค่ที่อยู่ของวิดีโอหรือโพสต์ ถ้าที่อยู่นั้นเป็นของแท็กข้างต้น (วิดีโอ YouTube โพสต์ Instagram หรือ TikTok โพสต์หรือวิดีโอ Facebook) เว็บจะแสดงตัวเล่นของแท็กนั้นแทน พร้อมคำบรรยายใต้บล็อกเหมือนเดิม ส่วนบล็อกฝังจากเว็บอื่น (Vimeo, X, Spotify ฯลฯ) จะแสดงที่อยู่เหมือนเดิม ระบบไม่ได้แก้เนื้อหาในบทความ

กริดโพสต์ที่ดึงมาจากโซเชียล {{social_feed}}

เว็บที่อยู่ในเบต้าโซเชียลมีเดีย (ดู เชื่อมโซเชียลมีเดีย) ใช้ {{social_feed}} แสดงบทความที่ดึงมาจาก Instagram, Facebook และ TikTok ที่ เผยแพร่อยู่ เป็นกริดรูป เรียงใหม่สุดก่อน โพสต์ที่ดึงมาใหม่จะขึ้นเอง บทความที่เลิกเผยแพร่ ย้ายลงถังขยะ หรือลบ จะหายจากกริด แอตทริบิวต์: source (instagram, facebook, tiktok หรือ all ซึ่งเป็นค่าเริ่มต้น), limit (1–24 ค่าเริ่มต้น 9), columns (1–6 ค่าเริ่มต้น 3 จอแคบจะลดจำนวนคอลัมน์ให้รูปไม่เล็กกว่า 80px), gap (0–24 พิกเซล ค่าเริ่มต้น 4), aspect (square เป็นค่าเริ่มต้น, portrait 4:5, tall 9:16), link (source ค่าเริ่มต้น เปิดโพสต์บนโซเชียลในแท็บใหม่ ส่วน article เปิดบทความบนเว็บ), follow (ที่อยู่โปรไฟล์ของคุณที่ขึ้นต้นด้วย https:// เพื่อแสดงปุ่มใต้กริด) และ follow_label (ข้อความบนปุ่ม ค่าเริ่มต้นเช่น “ติดตามเราบน Instagram” ตามภาษาของหน้า) โพสต์ที่ปักหมุดไว้ใน เครื่องมือ → โซเชียลมีเดีย → Social feed ขึ้นก่อน (ไม่เกิน 6 โพสต์) โพสต์ที่ซ่อนจะไม่ขึ้น และบัญชีที่ปิดสวิตช์ไว้ที่นั่นจะออกจากทุกกริด บัญชีที่ตั้งเป็น แสดงบนเว็บเท่านั้น จะเพิ่มโพสต์ล่าสุดของบัญชีเข้ากริดเดียวกัน เรียงใหม่สุดก่อน โพสต์เหล่านี้เปิดโพสต์บนโซเชียลเสมอ แม้ใส่ link="article" เพราะไม่มีบทความบนเว็บ โพสต์ที่ไม่มีรูปจะแสดงข้อความบนช่องสีเทา และวิดีโอจะมีสัญลักษณ์เล่นเล็ก ๆ รูปทั้งหมดเป็นสำเนาที่ SeedWebs เก็บไว้ (รูปของบทความที่ดึงมาอยู่ในคลังสื่อของเว็บ) จึงไม่มีอะไรโหลดจากโซเชียลก่อนผู้เข้าชมกด part="my-feed" ใช้ Element ของคุณเองแทน โดยได้ {{#each item.items}}…{{/each}} แต่ละโพสต์มี {{item.url}}, {{item.image}}, {{item.title}}, {{item.excerpt}}, {{item.provider_label}}, {{item.is_video}}, {{item.date}} และ {{item.pinned}} (1 สำหรับโพสต์ที่ปักหมุด) พร้อม {{item.follow_url}} กับ {{item.follow_label}} ส่วนกริดแบบสำเร็จรูป ช่องที่ปักหมุดมี data-pinned="1" ให้ใช้กับ CSS ใส่ใน Header หรือ Footer ของธีมก็ได้ จึงวางกริดเดียวไว้ท้ายทุกหน้าได้ ถ้าไม่มีอะไรให้แสดง แท็กจะเหลือแค่คอมเมนต์ HTML ส่วนเว็บที่ไม่ได้อยู่ในเบต้า หรือแพ็กเกจไม่รวมการดึงโพสต์จากโซเชียล แท็กนี้จะไม่แสดงอะไร

แท็กเฉพาะหน้า

หน้า / เทมเพลตแท็กที่ใช้ได้
search-results{{search_query}}, {{result_count}}, {{#if search_query}}...{{else}}...{{/if}}, {{#each search}}, {{search_form}}, {{pagination}}
category{{category_name}}, {{category_slug}}, {{category_description}}, {{category_body}}, {{category_image}}, {{category_icon}}, {{current_q}}, {{current_subcat}}, {{subcategory_list}}, {{category_search_input}}, {{#if category_...}} และ {{#unless category_...}} เมื่อเปิดที่อยู่หมวดหมู่แบบซ้อน มี {{category_url}}, {{category_parent_name}} และ {{category_parent_url}} เพิ่ม
tag{{tag_name}}, {{tag_slug}}
date-archive{{archive_title}} (“พฤษภาคม 2024”, “May 2024” ปีเป็น ค.ศ.), {{#each posts}}, {{total}}, {{pagination}} เฉพาะเว็บที่ย้ายมาจาก WordPress และเปิดหน้ารวมบทความตามวันที่ไว้
product-category, tour-category, staff-category, portfolio-category, program-category, book-category{{category_name}}, {{category_slug}}, {{category_description}}, {{category_body}}, {{category_image}}, {{category_icon}}, {{#if category_...}} และ {{#unless category_...}}
product-brand{{brand_name}}, {{brand_slug}}
not-found{{site_name}} เท่านั้น
tour-thankyou{{booking_number}}, {{locale_prefix}}

{{category_body}} คือหน้าของหมวดนั้นเอง — เนื้อหาที่อยู่เหนือรายการ แก้ได้ในฟอร์มหมวดหัวข้อ Archive Page Content ใส่ลงหน้าเป็น HTML หัวข้อ รายการ รูป ใช้ได้ครบ และถ้าเขียน {{#each}} ไว้ข้างในก็ขยายให้ด้วย จึงทำหน้าหมวดที่มีทั้งเนื้อหาและรายการของตัวเองได้ในที่เดียว ส่วน {{category_description}} คือคำอธิบายสั้นข้าง ๆ ใส่เป็นข้อความล้วนและใช้เป็น meta description ของหน้าด้วย ถ้าเว็บเดิมมีหน้าจริงอยู่ที่ /programs/bachelors/ แล้วต่อด้วยรายการหลักสูตรปริญญาตรี หน้านั้นคือหมวด ให้เก็บไว้ที่นี่ ไม่ต้องสร้างหลักสูตรที่ไม่ใช่หลักสูตรขึ้นมารับ

{{category_description}}, {{category_body}}, {{category_image}} และ {{category_icon}} ถ้าหมวดย่อยไม่ได้กรอกค่าไว้ ระบบใช้ค่าของหมวดแม่แทนให้ — หมวดแม่จึงเขียนคำอธิบายรวมครั้งเดียวได้ {{category_icon}} ใส่ SVG ลงหน้าเป็นโค้ด ให้ใช้ fill="currentColor" ใน SVG เพื่อให้รับสีจากธีม

{{subcategory_list}} รับ outerClass, labelClass, wrapClass, selectClass และแสดงผลเฉพาะเมื่อหมวดนั้นมีหมวดย่อย {{category_search_input}} รับ placeholder และ class พิมพ์แล้วรอ 450 มิลลิวินาทีจึงกรองรายการ

ทั้งสองแท็กทำงานคู่กับการโหลดรายการแบบไม่รีเฟรชหน้า ซึ่งต้องมี id="sw-posts-grid" ครอบกริดการ์ด และ id="sw-pagination" ครอบหน้าถัดไปในเทมเพลต category

แท็กใช้ได้ที่ไหน

จุดที่สับสนบ่อยที่สุดคือแท็กเดียวกันไม่ได้ทำงานทุกที่ ตารางนี้สรุปตามโค้ดจริง

แท็กHeader / FooterElements / Templatesเนื้อหา Pageเนื้อหา Post, Product, Event
{{site_name}}, {{tag_line}}, {{year}}ได้ไม่ได้ได้ไม่ได้
{{nav}}, {{site_logo}}, {{language_switcher}}, {{locale_home}}ได้ไม่ได้ไม่ได้ไม่ได้
{{search_overlay}}, {{chat_widget}}, {{cookie_consent}}ได้ไม่ได้ไม่ได้ไม่ได้
{{mini_cart}}, {{cart_drawer}}, {{floating_cart}}ได้ได้ได้ไม่ได้
{{add_to_cart}}ไม่ได้เทมเพลตและการ์ดสินค้าในลูป {{#each products}}ไม่ได้
{{cart_page}}, {{checkout_page}}ไม่ได้เทมเพลต cart / checkoutได้ไม่ได้
{{search_form}}ได้ทุกเทมเพลตได้ไม่ได้
{{item.*}}, {{#if item.*}}, {{> partial}}ไม่ได้ได้ไม่ได้ไม่ได้
{{#each posts}} และชนิดอื่นไม่ได้ได้ได้ไม่ได้
{{slider}}เฉพาะหน้า Page และหน้าแรกได้ได้ไม่ได้
{{form}}ไม่ได้ได้ได้ไม่ได้
{{ad}}ได้ได้ได้ได้
{{subscribe_form}}ได้ไม่ได้ได้ไม่ได้
{{social_share}}ได้ได้ได้ได้
{{gallery}}ไม่ได้ได้ได้ได้
{{youtube}}, {{instagram}}, {{facebook}}, {{tiktok}}, {{tiktok_profile}}, {{map}}, {{pdf_button}}ไม่ได้เทมเพลตหน้า Page และหน้ารายละเอียด ไม่รวมเทมเพลตหน้ารายการ หน้าค้นหา และหน้า 404ได้ได้
{{social_feed}} (เว็บในเบต้า)ได้เทมเพลตหน้า Page และหน้ารายละเอียด ไม่รวมเทมเพลตหน้ารายการและหน้า 404ได้ไม่ได้
{{pagination}}ไม่ได้เฉพาะเทมเพลตหน้ารายการเว็บ experimental ที่มีลูป page_param (โหมด HTML)ไม่ได้

ในเนื้อหา Page ยังมี {{title}}, {{slug}}, {{featured_image}}, {{featured_image_mobile}}, {{seo_title}}, {{seo_description}} และ {{item.field.<คีย์>}} ให้ใช้ (ทำงานทั้งโหมด Article และ HTML Builder) แต่ {{#if}} ใช้ในเนื้อหา Page นอกลูป {{#each}} ไม่ได้ ส่วนในลูป เนื้อหาคือการ์ด: {{#if item.*}}…{{else}}…{{/if}} ใช้ได้ และ {{item.field.<คีย์>}} คือฟิลด์ของการ์ดแต่ละใบ ไม่ใช่ของหน้า

{{locale_prefix}} ใช้ได้ใน Elements, Templates และในเนื้อหา Post ส่วนในเนื้อหา Page ใช้ได้ในลูป {{#each}} และได้ค่าว่างเมื่ออยู่นอกลูป

แท็กวิดีโอ โพสต์โซเชียล แผนที่ และปุ่ม PDF มีข้อยกเว้นอยู่บ้าง ในหน้าแรกที่เขียนด้วยโหมด Article มีแค่แท็กกลุ่มนี้กับ {{social_feed}} ที่ทำงาน แท็กอื่นจะแสดงเป็นตัวอักษรตามที่พิมพ์ ในการ์ดของลูป {{#each}} บนหน้ารายการ ผลการค้นหา หรือในเทมเพลตหน้า Page ของธีม แท็กกลุ่มนี้จะแสดงเป็นตัวอักษรตามที่พิมพ์ ในหน้าโหมด Article ที่อยู่ใต้ที่อยู่ของระบบ เช่น /search/… การกดภาพปกจะเปิดโพสต์หรือแผนที่ในแท็บใหม่แทนการโหลดบนหน้าเว็บ ส่วนในสไลด์ที่เขียนเองในสไลเดอร์ และในแบนเนอร์ (Banners) แท็กกลุ่มนี้จะแสดงเป็นตัวอักษรตามที่พิมพ์ {{pdf_button}} ในบทความที่เขียนแบบ Markdown จะไม่แสดงอะไร ให้เขียนบทความนั้นในตัวแก้ไขแบบ Article แล้วใช้ปุ่ม PDF บนแถบเครื่องมือแทน

ข้อจำกัดที่ควรรู้ก่อนเริ่ม

  1. เนื้อหาของ Post, Product, Event, Book, Doc, Tour รับเฉพาะ {{gallery}}, {{social_share}}, {{locale_prefix}}, {{pdf_button}} และแท็กวิดีโอ โซเชียล และแผนที่ ({{youtube}}, {{instagram}}, {{facebook}}, {{tiktok}}, {{tiktok_profile}}, {{map}}) และ {{ad}} บนเว็บที่เปิดโฆษณา แท็กอย่าง {{#each}}, {{slider}}, {{form}} ที่พิมพ์ในเนื้อหาเหล่านี้จะไม่ทำงาน ถ้าต้องการ ให้ย้ายไปไว้ในเทมเพลตของ content type นั้น หรือใช้หน้า Page แทน
  2. {{item.url}} มีค่าเฉพาะในลูป {{#each}} ในเทมเพลตหน้ารายละเอียดให้ประกอบลิงก์เอง เช่น {{locale_prefix}}/posts/{{item.slug}}
  3. ในเทมเพลตหน้ารายละเอียด ค่าใน {{item.*}} ยังไม่ถูกแทนที่ตอนที่ {{#each}} ทำงาน จึงเขียน {{#each posts category="{{item.slug}}"}} ไม่ได้ ข้อยกเว้นคือ {{book_tour_form}} ที่ระบบจัดการทีหลังจึงรับ {{item.id}} ได้ ส่วนหมวดของบทความเอง เว็บที่เปิด experimental เขียน category="current" ได้ (ดูตารางแอตทริบิวต์)
  4. ในหน้า author-detail ลูป {{#each posts}} จะกรองเฉพาะบทความของผู้เขียนคนนั้นให้เองอยู่แล้ว
  5. {{locale_prefix}} ให้ค่าว่างเมื่อเป็นภาษาหลัก และให้ /th เมื่ออยู่ในภาษาอื่น ใช้กับลิงก์ในธีมทุกที่เพื่อไม่ให้ผู้ใช้หลุดออกจากภาษาที่กำลังอ่าน
  6. ถ้าธีมของคุณไม่มีเทมเพลตของหน้านั้น ระบบจะย้อนไปใช้เทมเพลตของธีมเริ่มต้น รายละเอียดใน ธีมและเทมเพลต

แท็กในเทมเพลตอีเมล

แท็บ Emails มีเทมเพลตหลายชิ้น แต่ระบบส่งจริงสองชิ้น และแต่ละชิ้นเติมค่าให้เฉพาะแท็กเหล่านี้

เทมเพลตแท็กที่เติมค่าให้
email-welcome (ส่งเมื่อมีผู้สมัครรับข่าวใหม่){{site_name}}, {{email}}, {{unsubscribe_url}}
email-newsletter (ส่งจดหมายข่าว){{subject}}, {{body}}, {{site_name}}, {{email}}, {{unsubscribe_url}}

แท็กอื่นที่พบในเทมเพลตอีเมลที่ติดตั้งมาให้ เช่น {{confirm_url}} และ {{resubscribe_url}} ยังไม่มีระบบเติมค่า ถ้าใส่ไว้จะปรากฏเป็นข้อความตามตัวอักษรในอีเมล

จดหมายข่าวและรายชื่อผู้สมัครเป็นฟีเจอร์ที่จำกัดตามแพ็กเกจและต้องเปิดแฟล็ก experimental ให้ก่อน (ดู แพ็กเกจและการชำระเงิน)

เริ่มจากตัวอย่างที่มีอยู่

วิธีที่เร็วที่สุดคือเปิด element หรือ template ที่ระบบติดตั้งมาให้ แล้วดูว่าใช้แท็กอะไร เช่น post-card ที่รวมเกือบทุกเทคนิคในเอกสารนี้ไว้ในไฟล์เดียว

<a href="{{item.url}}" class="group block rounded-lg border">
  {{#if item.featured_image}}
    <img src="{{item.featured_image}}" srcset="{{item.featured_image_srcset}}" alt="{{item.title}}" loading="lazy" />
  {{/if}}
  <div class="p-4">
    {{#each item.categories}}<span class="text-xs uppercase">{{item.name}}</span>{{/each}}
    <h3 class="mt-2 font-semibold">{{item.title}}</h3>
    {{#if item.excerpt}}<p class="mt-1 text-sm text-gray-500">{{item.excerpt}}</p>{{/if}}
    <div class="mt-3 text-xs text-gray-400">
      {{#if item.created_at_formatted}}<time>{{item.created_at_formatted}}</time>{{/if}}
      {{#if item.read_time_label}}<span>· {{item.read_time_label}}</span>{{/if}}
    </div>
  </div>
</a>

ธีมชื่อ default ลบไม่ได้ และชิ้นส่วนที่ติดตั้งมากับธีมนั้นก็ลบไม่ได้ แต่กด Reset เพื่อคืนค่าโรงงานได้ จึงทดลองแก้ได้โดยไม่เสียของเดิม