SiamCafe.net Blog
Technology

WordPress Block Theme Multi-tenant Design

wordpress block theme multi tenant design
WordPress Block Theme Multi-tenant Design | SiamCafe Blog
2026-04-21· อ. บอม — SiamCafe.net· 11,890 คำ

WordPress Block Theme

WordPress Block Theme Multi-tenant Full Site Editing FSE theme.json Block Patterns Multisite Network Global Styles Template Parts Domain Mapping Production

FeatureClassic ThemeBlock ThemeHybrid Theme
TemplatePHP filesHTML + BlocksPHP + Blocks
Stylingstyle.csstheme.jsonBoth
EditingCustomizerSite EditorBoth
PatternsLimitedFull supportFull support
Global Stylesไม่รองรับเต็มรูปแบบบางส่วน
เหมาะกับLegacy sitesNew projectsMigration

theme.json Configuration

# === theme.json for Block Theme ===

# theme.json — Main configuration
# {
#   "$schema": "https://schemas.wp.org/trunk/theme.json",
#   "version": 2,
#   "settings": {
#     "color": {
#       "palette": [
#         { "slug": "primary", "color": "#1e40af", "name": "Primary" },
#         { "slug": "secondary", "color": "#7c3aed", "name": "Secondary" },
#         { "slug": "accent", "color": "#f59e0b", "name": "Accent" },
#         { "slug": "background", "color": "#ffffff", "name": "Background" },
#         { "slug": "foreground", "color": "#1f2937", "name": "Foreground" }
#       ],
#       "gradients": [],
#       "defaultPalette": false
#     },
#     "typography": {
#       "fontFamilies": [
#         {
#           "fontFamily": "Inter, sans-serif",
#           "slug": "inter",
#           "name": "Inter",
#           "fontFace": [{
#             "fontFamily": "Inter",
#             "fontWeight": "400 700",
#             "fontStyle": "normal",
#             "src": ["file:./assets/fonts/inter.woff2"]
#           }]
#         }
#       ],
#       "fontSizes": [
#         { "slug": "small", "size": "0.875rem", "name": "Small" },
#         { "slug": "medium", "size": "1rem", "name": "Medium" },
#         { "slug": "large", "size": "1.5rem", "name": "Large" },
#         { "slug": "x-large", "size": "2.25rem", "name": "Extra Large" }
#       ]
#     },
#     "layout": {
#       "contentSize": "800px",
#       "wideSize": "1200px"
#     },
#     "spacing": {
#       "units": ["px", "rem", "%"],
#       "spacingSizes": [
#         { "slug": "10", "size": "0.5rem", "name": "XS" },
#         { "slug": "20", "size": "1rem", "name": "S" },
#         { "slug": "30", "size": "1.5rem", "name": "M" },
#         { "slug": "40", "size": "2rem", "name": "L" },
#         { "slug": "50", "size": "3rem", "name": "XL" }
#       ]
#     }
#   },
#   "styles": {
#     "color": { "background": "var(--wp--preset--color--background)", "text": "var(--wp--preset--color--foreground)" },
#     "typography": { "fontFamily": "var(--wp--preset--font-family--inter)", "fontSize": "var(--wp--preset--font-size--medium)" },
#     "elements": {
#       "h1": { "typography": { "fontSize": "var(--wp--preset--font-size--x-large)" } },
#       "button": { "color": { "background": "var(--wp--preset--color--primary)", "text": "#ffffff" } },
#       "link": { "color": { "text": "var(--wp--preset--color--primary)" } }
#     }
#   }
# }

from dataclasses import dataclass

@dataclass
class ThemeComponent:
    component: str
    file_path: str
    purpose: str
    required: bool

components = [
    ThemeComponent("theme.json", "theme.json", "Global styles and settings", True),
    ThemeComponent("style.css", "style.css", "Theme metadata (name, version)", True),
    ThemeComponent("Index Template", "templates/index.html", "Main fallback template", True),
    ThemeComponent("Header Part", "parts/header.html", "Site header with nav", True),
    ThemeComponent("Footer Part", "parts/footer.html", "Site footer", True),
    ThemeComponent("Single Template", "templates/single.html", "Single post template", False),
    ThemeComponent("Page Template", "templates/page.html", "Page template", False),
    ThemeComponent("Patterns", "patterns/*.php", "Reusable block patterns", False),
]

print("=== Block Theme Structure ===")
for c in components:
    req = "Required" if c.required else "Optional"
    print(f"  [{req}] {c.component}")
    print(f"    Path: {c.file_path} | Purpose: {c.purpose}")

Multisite Multi-tenant

# === WordPress Multisite Setup ===

# wp-config.php — Enable Multisite
# define('WP_ALLOW_MULTISITE', true);
# // After network setup:
# define('MULTISITE', true);
# define('SUBDOMAIN_INSTALL', true);
# define('DOMAIN_CURRENT_SITE', 'example.com');
# define('PATH_CURRENT_SITE', '/');
# define('SITE_ID_CURRENT_SITE', 1);
# define('BLOG_ID_CURRENT_SITE', 1);

# .htaccess for Multisite
# RewriteEngine On
# RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# RewriteBase /
# RewriteRule ^index\.php$ - [L]
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule . /index.php [L]

# WP-CLI — Manage Multisite
# wp site create --slug=tenant-a --title="Tenant A" --email=admin@tenant-a.com
# wp site create --slug=tenant-b --title="Tenant B" --email=admin@tenant-b.com
# wp site list
# wp theme enable my-block-theme --network
# wp plugin activate woocommerce --url=tenant-a.example.com

# Domain Mapping (WordPress 4.5+)
# wp site create --slug=tenant-c --title="Tenant C"
# -- In admin: Settings > Domains > Add tenant-c.com

# Nginx Configuration per site
# server {
#     listen 443 ssl http2;
#     server_name tenant-a.com www.tenant-a.com;
#     root /var/www/wordpress;
#     # ... standard WordPress config
# }

@dataclass
class TenantSite:
    tenant: str
    domain: str
    theme_variation: str
    plugins: str
    storage: str
    users: int

tenants = [
    TenantSite("Tenant A", "tenant-a.com", "Blue Corporate", "WooCommerce, Yoast", "5GB", 12),
    TenantSite("Tenant B", "tenant-b.com", "Green Nature", "LearnDash, BuddyPress", "10GB", 45),
    TenantSite("Tenant C", "tenant-c.com", "Purple Creative", "Elementor, WPForms", "3GB", 5),
    TenantSite("Tenant D", "tenant-d.com", "Red Bold", "WooCommerce, Mailchimp", "8GB", 20),
]

print("\n=== Multi-tenant Sites ===")
for t in tenants:
    print(f"  [{t.tenant}] {t.domain}")
    print(f"    Theme: {t.theme_variation} | Users: {t.users}")
    print(f"    Plugins: {t.plugins} | Storage: {t.storage}")

Block Patterns

# === Block Patterns for Multi-tenant ===

# patterns/hero-section.php
# <?php
# /**
#  * Title: Hero Section
#  * Slug: mytheme/hero-section
#  * Categories: featured
#  * Keywords: hero, banner, header
#  */
# ?>
# <!-- wp:cover {"dimRatio":50} -->
# <div class="wp-block-cover">
#   <!-- wp:heading {"level":1} -->
#   <h1>Welcome to Our Site</h1>
#   <!-- /wp:heading -->
#   <!-- wp:paragraph -->
#   <p>Discover our services and solutions</p>
#   <!-- /wp:paragraph -->
#   <!-- wp:buttons -->
#   <div class="wp-block-buttons">
#     <!-- wp:button -->
#     <div class="wp-block-button"><a class="wp-block-button__link">Get Started</a></div>
#     <!-- /wp:button -->
#   </div>
#   <!-- /wp:buttons -->
# </div>
# <!-- /wp:cover -->

@dataclass
class BlockPattern:
    name: str
    slug: str
    category: str
    blocks_used: str
    tenant_customizable: bool

patterns = [
    BlockPattern("Hero Section", "mytheme/hero", "Featured", "Cover Heading Paragraph Buttons", True),
    BlockPattern("Pricing Table", "mytheme/pricing", "Commerce", "Columns Group Heading List Button", True),
    BlockPattern("Testimonials", "mytheme/testimonials", "Social", "Columns Quote Image Paragraph", True),
    BlockPattern("FAQ Accordion", "mytheme/faq", "Content", "Details Summary Paragraph", True),
    BlockPattern("CTA Banner", "mytheme/cta", "Featured", "Group Heading Paragraph Buttons", True),
    BlockPattern("Team Grid", "mytheme/team", "About", "Columns Image Heading Paragraph Social", True),
]

print("Block Patterns:")
for p in patterns:
    custom = "Customizable per tenant" if p.tenant_customizable else "Fixed"
    print(f"  [{p.name}] {p.slug}")
    print(f"    Category: {p.category} | Blocks: {p.blocks_used}")
    print(f"    {custom}")

performance = {
    "Page Cache": "WP Super Cache / Redis Object Cache",
    "CDN": "Cloudflare / BunnyCDN สำหรับ Static Assets",
    "Image": "WebP conversion + Lazy Loading",
    "Database": "Query Monitor + Index Optimization",
    "PHP": "OPcache enabled PHP 8.2+",
    "Cron": "Disable wp-cron ใช้ System Cron แทน",
}

print(f"\n\nPerformance Optimization:")
for k, v in performance.items():
    print(f"  [{k}]: {v}")

เคล็ดลับ

WordPress Block Theme คืออะไร

Full Site Editing FSE Block Editor HTML Template theme.json Block Patterns Global Styles Template Parts WordPress 6.0+ ไม่ต้อง PHP Template

Multi-tenant WordPress ทำอย่างไร

Multisite Network หลาย Site Installation เดียว Domain Mapping Super Admin แชร์ User Plugin Theme Subdomain Subdirectory

theme.json ใช้อย่างไร

Color Palette Typography Spacing Layout Custom Properties Block Style Template Parts Style Variations JSON Format Global Styles Settings

Block Patterns คืออะไร

Template สำเร็จรูป Hero Pricing Testimonial FAQ Block หลายตัว patterns/ folder register Reusable Synced Patterns Update ทุกที่

สรุป

WordPress Block Theme Multi-tenant Full Site Editing theme.json Block Patterns Multisite Network Domain Mapping Style Variations Global Styles Production

📖 บทความที่เกี่ยวข้อง

WordPress Block Theme Home Lab Setupอ่านบทความ → WordPress Block Theme Citizen Developerอ่านบทความ → WordPress Block Theme Chaos Engineeringอ่านบทความ → WordPress Block Theme Community Buildingอ่านบทความ → Netlify Edge Multi-tenant Designอ่านบทความ →

📚 ดูบทความทั้งหมด →