Configuration Files Reference

Unfold CMS templates use three JSON configuration files to declare metadata, settings UI, and homepage sections. This page documents the complete schema for each file.

template.json

Required. Defines the template's identity, menu locations, and ad zones. Located at the template root directory.

Example

{
    "name": "Default Template",
    "version": "1.0.0",
    "author": "Unfold CMS",
    "description": "The default template for Unfold CMS",
    "screenshot": "screenshot.png",
    "menu_locations": {
        "header": {
            "name": "Header Navigation",
            "description": "Main navigation shown in the site header"
        },
        "footer": {
            "name": "Footer Navigation",
            "description": "Footer columns — top-level items become column headers, children become links"
        }
    },
    "zones": {
        "header_leaderboard": {
            "name": "Header Leaderboard",
            "description": "Top of the page leaderboard banner",
            "size": "728x90",
            "type": "banner"
        },
        "sidebar_top": {
            "name": "Sidebar Top",
            "size": "300x250",
            "type": "sidebar"
        }
    }
}

Fields

Field Type Required Description
name string Yes Human-readable template name
version string No Semantic version string
author string No Template author name
description string No Short description
screenshot string No Preview image filename (relative to template root)
menu_locations object No Menu slots the template supports. Falls back to default header and footer if omitted.
zones object Yes Ad zone definitions. Use {} if no ad zones are needed.
Field Type Description
name string Display name in admin
description string Help text for admins

Zone Object

Field Type Description
name string Display name in admin
description string Help text
size string Dimensions (e.g., 728x90, 300x250)
type string Zone type: banner, sidebar, popup, footer

options.json

Optional. Defines the template settings UI rendered in Admin > Appearance > Template Settings. Located at config/options.json within the template directory.

Example

{
    "options": [
        {
            "type": "divider",
            "label": "Homepage"
        },
        {
            "key": "hero.enabled",
            "type": "boolean",
            "label": "Show Hero Section",
            "description": "Display the hero banner on the homepage",
            "defaultValue": true,
            "col": 2,
            "children": [
                {
                    "key": "hero.title",
                    "type": "text",
                    "label": "Hero Title",
                    "defaultValue": "Welcome to Our Blog"
                },
                {
                    "key": "hero.subtitle",
                    "type": "textarea",
                    "label": "Hero Subtitle",
                    "defaultValue": "Discover stories and expertise.",
                    "rows": 3
                }
            ]
        },
        {
            "key": "blog.posts_per_page",
            "type": "integer",
            "label": "Posts Per Page",
            "defaultValue": 12,
            "min": 4,
            "max": 48
        },
        {
            "key": "appearance.default_theme",
            "type": "radio",
            "label": "Default Theme",
            "options": [
                { "value": "system", "label": "System" },
                { "value": "light", "label": "Light" },
                { "value": "dark", "label": "Dark" }
            ],
            "defaultValue": "system",
            "col": 2
        }
    ]
}

Field Types

Type Description Extra Properties
text Single-line text input placeholder
textarea Multi-line text input placeholder, rows
integer Number input min, max
boolean Toggle switch children, bordered
select Dropdown options: [{value, label}]
radio Radio button group options: [{value, label, description}], inline
color Color picker
url URL input placeholder
file File upload file: {accept, maxSize, preview}
slider Range slider slider: {min, max, step, unit}
divider Section heading (no key) label, action: {label, href}

Common Properties

Property Type Description
key string Setting key (stored as template.{name}.{key})
type string Field type (see table above)
label string Display label
description string Help text shown below the field
defaultValue mixed Default value
col number Columns to span (1 or 2)
bordered boolean Show border around field (default: true)

Boolean Children

Boolean fields can have children — nested fields that appear when the toggle is enabled:

{
    "key": "sidebar.enabled",
    "type": "boolean",
    "label": "Show Sidebar",
    "defaultValue": true,
    "children": [
        {
            "key": "sidebar.position",
            "type": "radio",
            "label": "Position",
            "options": [
                { "value": "left", "label": "Left" },
                { "value": "right", "label": "Right" }
            ],
            "defaultValue": "right"
        }
    ]
}

Reading Options in Templates

{{-- Escaped output --}}
@option('hero.title')

{{-- With default --}}
@templateOption('blog.posts_per_page', 12)

{{-- In PHP logic --}}
@php
    $postsPerPage = template_option('blog.posts_per_page', 12);
@endphp

sections.json

Optional. Defines page sections that admins can populate with content items or settings. Located at config/sections.json within the template directory.

Example

{
    "sections": {
        "homepage.stats": {
            "name": "Stats",
            "description": "Key numbers and statistics",
            "block_type": "stat",
            "max": 6,
            "page": "homepage",
            "title_label": "Value",
            "body_label": "Label",
            "supports_featured_image": false,
            "fields": []
        },
        "homepage.features": {
            "name": "Features",
            "description": "Feature highlights on the homepage",
            "block_type": "feature",
            "max": 12,
            "page": "homepage",
            "title_label": "Heading",
            "body_label": "Description",
            "supports_featured_image": false,
            "fields": [
                {
                    "key": "icon",
                    "type": "icon_picker",
                    "label": "Icon",
                    "placeholder": "Search icons..."
                },
                {
                    "key": "link_url",
                    "type": "url",
                    "label": "Link URL",
                    "placeholder": "/features/security"
                }
            ]
        },
        "homepage.testimonials": {
            "name": "Testimonials",
            "description": "Customer testimonials",
            "block_type": "testimonial",
            "max": 12,
            "page": "homepage",
            "title_label": "Quote",
            "body_label": "Full Testimonial",
            "supports_featured_image": true,
            "fields": [
                {
                    "key": "author_name",
                    "type": "text",
                    "label": "Author Name",
                    "validation": { "required": true }
                },
                {
                    "key": "author_role",
                    "type": "text",
                    "label": "Author Role"
                },
                {
                    "key": "rating",
                    "type": "select",
                    "label": "Rating",
                    "options": [
                        { "value": "5", "label": "5 Stars" },
                        { "value": "4", "label": "4 Stars" }
                    ]
                }
            ]
        }
    }
}

Section Properties

Field Type Required Description
name string Yes Display name in admin
description string No Help text for admins
block_type string Yes Block type identifier
max integer No Maximum number of items
page string Yes Which page this section belongs to
title_label string No Custom label for the title field
body_label string No Custom label for the body field
supports_featured_image boolean No Allow image upload per item
settings_only boolean No Section stores settings, not items
fields array No Custom extra fields

Custom Fields

Each field in the fields array:

Property Type Description
key string Field key (stored in extra_attributes)
type string Field type (text, textarea, url, select, icon_picker, etc.)
label string Display label
placeholder string Input placeholder
options array For select type: [{value, label}]
validation object Validation rules (e.g., {required: true})

Settings-Only Sections

Sections with settings_only: true store data in the settings table instead of creating content items. Used for sections like Hero, About, and CTA where only a single set of values is needed:

{
    "homepage.about": {
        "name": "About",
        "settings_only": true,
        "page": "homepage",
        "fields": [],
        "settings": [
            { "key": "heading", "type": "text", "label": "Heading" },
            { "key": "body", "type": "textarea", "label": "Content" },
            { "key": "image", "type": "file", "label": "Image" }
        ]
    }
}

Settings fields support the same types as item fields, plus boolean with children for conditional nested fields (e.g., a button toggle with label and URL children), file uploads, slider, and color pickers.

Read settings-only values with:

$heading = section_setting('homepage.about', 'heading');

File Locations

File Path Purpose
template.json resources/views/templates/{name}/template.json Template identity
options.json resources/views/templates/{name}/config/options.json Admin settings UI
sections.json resources/views/templates/{name}/config/sections.json Page sections