Sections
Unfold CMS includes a section builder for creating dynamic page content. Sections are defined by the active template and populated through the admin panel. Each section type has its own layout, fields, and settings.
Overview
The section system works on three levels:
- Template declares section types and page groupings in
config/sections.json - Admin populates section content through the manage page
- Template renders sections using Blade partials
This separation means administrators can update content without touching code, while template developers control the layout and design. Since all section configuration — including page labels — lives inside the template folder, templates are fully portable: copy the folder and everything works.
Available Sections
The default template includes section types across two pages:
Homepage
| Section | Key | Type | Max Items | Description |
|---|---|---|---|---|
| Hero | homepage.hero |
Settings-only | — | Hero banner with title, buttons, and background overlay |
| Stats | homepage.stats |
Item-based | 6 | Key numbers and statistics counters |
| About | homepage.about |
Settings-only | — | About section with image and CTA |
| Features | homepage.features |
Item-based | 12 | Feature cards grid |
| Testimonials | homepage.testimonials |
Item-based | 12 | Customer quotes carousel |
| FAQ | homepage.faq |
Item-based | 20 | Accordion Q&A |
| Integrations | homepage.integrations |
Item-based | 16 | Technology logos grid |
| Platform | homepage.tabs |
Item-based | 8 | Tabbed showcase |
| Call to Action | homepage.cta |
Settings-only | — | Bottom CTA banner |
Contact Page
| Section | Key | Type | Max Items | Description |
|---|---|---|---|---|
| Contact Info | contact.contact_info |
Settings-only | — | Hero section with heading, description, and contact details |
| Contact FAQ | contact.contact_faq |
Item-based | 20 | Frequently asked questions for the contact page |
| Map | contact.contact_map |
Settings-only | — | OpenStreetMap embed showing your location |
Section Types
Item-Based Sections
Most sections are item-based — they contain a list of items that administrators can create, edit, reorder, and delete. Each item has standard fields (title, body, featured image) plus custom fields defined by the section.
Settings-Only Sections
Sections marked with "settings_only": true have no items. Instead, they store all their data as key-value settings. These are ideal for single-instance content like a Hero banner, About section, or CTA banner. In the admin panel, settings-only sections show a settings form instead of an item list.
Managing Sections
Admin Interface
Navigate to Sections in the admin panel. The index page shows all sections grouped by page, with:
- Section name and description
- Item count (for item-based sections) or "Settings" badge (for settings-only)
- Quick link to manage each section
Managing Items
Click on an item-based section to manage its items:
- Add items using the form at the top
- Edit items by clicking on them in the list
- Reorder items with drag-and-drop
- Delete items with confirmation
- Toggle visibility for individual items
Section Settings
Each section can have global settings (heading, subtitle, badge text, etc.) that appear alongside the items. For settings-only sections, this is the only interface.
Section Configuration Schema
Sections are defined in config/sections.json. The file has two top-level keys: pages (page labels for the admin UI) and sections (the section definitions).
Page Labels
The pages key defines how each page group is displayed in the admin panel. Without this, the admin would show the raw page key (e.g., "homepage") as a heading.
{
"pages": {
"homepage": {
"label": "Homepage",
"description": "Sections displayed on your site's homepage"
},
"about": {
"label": "About Page",
"description": "Sections displayed on the about page"
}
},
"sections": { ... }
}
| Key | Type | Required | Description |
|---|---|---|---|
label |
string | Yes | Human-readable page name shown in admin |
description |
string | No | Help text shown below the page heading |
Page labels are passed from the template to the admin frontend automatically — no React code changes needed when adding new pages.
Section Definitions
{
"sections": {
"homepage.features": {
"name": "Features",
"description": "Feature cards grid",
"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"
},
{
"key": "link_url",
"type": "url",
"label": "Link URL"
}
],
"settings": [
{
"key": "badge",
"type": "text",
"label": "Badge"
},
{
"key": "title",
"type": "text",
"label": "Title"
},
{
"key": "subtitle",
"type": "text",
"label": "Subtitle",
"col": 2
}
]
}
}
}
Configuration Keys
| Key | Type | Description |
|---|---|---|
name |
string | Display name in admin |
description |
string | Help text shown in admin |
block_type |
string | Internal type identifier |
max |
int | Maximum number of items |
page |
string | Which page this section belongs to |
settings_only |
bool | If true, no items — settings form only |
title_label |
string | Label for the item title field |
body_label |
string | Label for the item body field |
supports_featured_image |
bool | Whether items can have images |
fields |
array | Custom fields for each item |
settings |
array | Section-level settings |
Field Types
Fields and settings support the following types:
| Type | Description | Extra Properties |
|---|---|---|
text |
Single-line text input | placeholder |
textarea |
Multi-line text input | placeholder, rows |
url |
URL input with validation | placeholder |
email |
Email input | placeholder |
integer |
Number input | min, max |
boolean |
Toggle switch | children (nested fields shown when true), bordered |
select |
Dropdown | options: [{value, label}] |
radio |
Radio buttons | options: [{value, label, description}], inline |
color |
Color picker | defaultValue (hex) |
file |
File upload | file: {accept, maxSize, preview} |
slider |
Range slider | slider: {min, max, step, unit} |
icon_picker |
Icon selector (Lucide icons) | placeholder |
Boolean fields with children: Boolean fields can contain nested children fields that are shown only when the toggle is on. This is useful for grouping related options — for example, a "Primary Button" toggle with label and URL children:
{
"key": "button_primary",
"type": "boolean",
"label": "Primary Button",
"defaultValue": true,
"children": [
{ "key": "button_primary_label", "type": "text", "label": "Label" },
{ "key": "button_primary_url", "type": "url", "label": "Link" }
]
}
Children are stored as flat keys alongside their parent — not nested objects.
Field Options
| Option | Type | Description |
|---|---|---|
key |
string | Unique field identifier |
type |
string | Input type (see above) |
label |
string | Display label |
placeholder |
string | Input placeholder text |
description |
string | Help text below the field |
col |
int | Column span (1 or 2) in the form grid |
validation |
object | Validation rules (e.g., {"required": true}) |
options |
array | Options for select fields |
defaultValue |
mixed | Default value |
children |
array | Nested fields for boolean type |
Section Details
Hero (Settings-Only)
Full-width hero banner with title, subtitle, call-to-action buttons, and background overlay. Supports solid color backgrounds, background images with opacity overlays, and two-color gradients.
Visibility is controlled by the section enable/disable toggle — no separate "enabled" setting needed.
| Setting | Description |
|---|---|
title |
Hero heading |
subtitle |
Hero subheading (textarea) |
button_primary |
Toggle primary button |
button_primary_label |
Primary button text |
button_primary_url |
Primary button link |
button_secondary |
Toggle secondary (outline) button |
button_secondary_label |
Secondary button text |
button_secondary_url |
Secondary button link |
image |
Background image (file upload) |
overlay_color |
Overlay color (color picker) |
overlay_opacity |
Overlay opacity 0-100% (slider, image only) |
overlay_gradient |
Toggle two-color gradient |
overlay_color_end |
Gradient end color |
overlay_gradient_direction |
Gradient direction (select) |
Stats
Displays key numbers as animated counters.
| Item Field | Label | Description |
|---|---|---|
| Title | Value | The number to display (e.g., "10,000+") |
| Body | Label | What the number represents (e.g., "Active Users") |
About (Settings-Only)
About section with image and call-to-action button.
| Setting | Description |
|---|---|
heading |
Section heading |
subtitle |
Section subtitle |
description |
About text (textarea) |
image |
Image URL |
button_text |
CTA button label |
button_url |
CTA button URL |
Features
Feature cards displayed in a responsive grid.
| Item Field | Label | Description |
|---|---|---|
| Title | Heading | Feature name |
| Body | Description | Feature description |
icon |
Icon | Lucide icon name |
link_url |
Link URL | Optional link |
Section settings: Badge, Title, Subtitle
Testimonials
Customer quotes with ratings and author info.
| Item Field | Label | Description |
|---|---|---|
| Title | Quote | Short testimonial quote |
| Body | Full Testimonial | Extended testimonial text |
| Featured Image | Avatar | Author photo |
author_name |
Author Name | Required |
author_role |
Author Role | Job title |
author_company |
Company | Company name |
rating |
Rating | 1-5 stars |
Section settings: Badge, Title, Subtitle
FAQ
Accordion-style frequently asked questions.
| Item Field | Label | Description |
|---|---|---|
| Title | Question | The question |
| Body | Answer | The answer text |
Section settings: Badge, Title, Subtitle
Integrations
Technology or partner logo grid.
| Item Field | Label | Description |
|---|---|---|
| Title | Name | Integration name |
| Body | Description | Integration description |
| Featured Image | Logo | Integration logo |
website_url |
Website URL | Link |
Section settings: Badge, Title, Subtitle
Platform (Tabs)
Tabbed content showcase with images.
| Item Field | Label | Description |
|---|---|---|
| Title | Tab Title | Tab label |
| Body | Content | Tab content |
| Featured Image | Image | Tab image |
icon |
Icon | Tab icon |
Section settings: Badge, Title, Subtitle
Call to Action (Settings-Only)
Bottom-of-page CTA banner.
| Setting | Description |
|---|---|
heading |
CTA heading |
subtitle |
Subtitle text |
description |
CTA description (textarea) |
button_text |
Button label |
button_url |
Button URL |
background_color |
Background color (default: #2563EB) |
Contact Info (Settings-Only)
Hero section with heading, description, and contact details for the contact page.
| Setting | Description |
|---|---|
heading |
Section heading |
subtitle |
Section subtitle |
description |
Description text (textarea) |
email |
Email address |
phone |
Phone number |
address |
Physical address (textarea) |
Contact FAQ
Frequently asked questions for the contact page. Uses the same accordion pattern as the homepage FAQ.
| Item Field | Label | Description |
|---|---|---|
| Title | Question | The question |
| Body | Answer | The answer text |
Section settings: Badge, Title, Subtitle
Map (Settings-Only)
OpenStreetMap embed showing your location.
| Setting | Description |
|---|---|
heading |
Section heading |
theme |
Map style (Standard, CyclOSM, Humanitarian) |
latitude |
Location latitude |
longitude |
Location longitude |
Rendering Sections in Templates
In your Blade templates, use the section_items() helper for item-based sections and section_setting() for settings:
{{-- Item-based section --}}
@php
$features = section_items('homepage.features');
@endphp
@foreach($features as $feature)
<div class="feature-card">
<h3>{{ $feature->title }}</h3>
<p>{{ $feature->body }}</p>
</div>
@endforeach
{{-- Settings-only section --}}
<h2>{{ section_setting('homepage.about', 'heading') }}</h2>
<p>{{ section_setting('homepage.about', 'description') }}</p>
Adding Custom Sections
To add a new section type to your template:
- Define it in
config/sections.jsonunder thesectionskey - Create a Blade partial in
sections/ - Include it in the appropriate page template (e.g.,
home.blade.php) - Add seed data in the seeder (for development)
Adding Sections to Other Pages
Sections are not limited to the homepage. To add sections for other pages:
-
Add a page label in the
pageskey ofsections.json:"pages": { "homepage": { "label": "Homepage", "description": "..." }, "about": { "label": "About Page", "description": "Sections for the about page" } } -
Define sections with the new
pagevalue:"sections": { "about.team": { "name": "Team", "page": "about", "block_type": "team_member", "max": 12, ... } } -
In your Blade template for that page, include the section:
@sectionEnabled('about.team') @include('templates.default.sections.team') @endsectionEnabled
The admin panel automatically groups sections by page and displays the labels you defined. All CRUD, reordering, caching, and toggle functionality works for any page — no additional backend code needed.
See the Template Development Guide for complete instructions.