Theme Options Guide
This guide explains how to implement and use theme options in FearlessCMS, allowing users to customize themes through the admin panel.
Overview
Theme options allow you to make your themes configurable without requiring users to edit code. Users can customize colors, upload images, toggle features, and more through a user-friendly interface.
Creating Theme Options
1. Define Options in config.json
Create a config.json
file in your theme directory to define available options:
json
{
"options": {
"logo": {
"type": "image",
"label": "Logo Image",
"description": "Upload your site logo (recommended: 200x60px)"
},
"herobanner": {
"type": "image",
"label": "Hero Banner",
"description": "Hero banner image for homepage"
},
"primaryColor": {
"type": "select",
"label": "Primary Color",
"description": "Choose your theme's primary color",
"options": [
{"value": "blue", "label": "Blue"},
{"value": "green", "label": "Green"},
{"value": "purple", "label": "Purple"},
{"value": "orange", "label": "Orange"}
],
"default": "blue"
},
"showSidebar": {
"type": "checkbox",
"label": "Show Sidebar",
"description": "Display sidebar on all pages",
"default": true
},
"footerText": {
"type": "text",
"label": "Footer Text",
"description": "Custom text to display in footer",
"default": "© 2024 My Site"
},
"socialLinks": {
"type": "array",
"label": "Social Links",
"description": "Add social media links",
"fields": {
"name": {"type": "text", "label": "Name"},
"url": {"type": "text", "label": "URL"},
"icon": {"type": "text", "label": "Icon Class"}
}
}
}
}
Breadcrumb Options
json
{
"showBreadcrumbs": {
"type": "checkbox",
"label": "Show Breadcrumbs",
"description": "Display breadcrumb navigation on pages",
"default": true
},
"breadcrumbStyle": {
"type": "select",
"label": "Breadcrumb Style",
"description": "Choose breadcrumb appearance",
"options": [
{"value": "minimal", "label": "Minimal (Home > Page)"},
{"value": "full", "label": "Full Path (Home > Section > Page)"},
{"value": "custom", "label": "Custom Separator"}
],
"default": "minimal"
},
"breadcrumbSeparator": {
"type": "text",
"label": "Breadcrumb Separator",
"description": "Character to separate breadcrumb levels",
"default": ">"
}
}
2. Option Types
FearlessCMS supports several option types:
#### Image Upload
json
{
"logo": {
"type": "image",
"label": "Logo",
"description": "Upload your logo"
}
}
#### Text Input
json
{
"siteTitle": {
"type": "text",
"label": "Site Title",
"description": "Your site title",
"default": "My Site"
}
}
#### Textarea
json
{
"footerText": {
"type": "textarea",
"label": "Footer Text",
"description": "Custom text to display in the footer",
"rows": 3
}
}
#### Select Dropdown
json
{
"layout": {
"type": "select",
"label": "Layout Style",
"options": [
{"value": "wide", "label": "Wide Layout"},
{"value": "narrow", "label": "Narrow Layout"},
{"value": "sidebar", "label": "With Sidebar"}
],
"default": "wide"
}
}
#### Checkbox
json
{
"showSearch": {
"type": "checkbox",
"label": "Show Search",
"description": "Display search box in header",
"default": true
}
}
#### Color Picker
json
{
"accentColor": {
"type": "color",
"label": "Accent Color",
"description": "Choose accent color",
"default": "#007bff"
}
}
#### Array/Repeater
json
{
"socialLinks": {
"type": "array",
"label": "Social Links",
"fields": {
"platform": {
"type": "select",
"label": "Platform",
"options": [
{"value": "facebook", "label": "Facebook"},
{"value": "twitter", "label": "Twitter"},
{"value": "instagram", "label": "Instagram"}
]
},
"url": {
"type": "text",
"label": "URL"
},
"icon": {
"type": "text",
"label": "Icon Class"
}
}
}
}
Using Theme Options in Templates
Basic Usage
Access theme options using the {{themeOptions.key}}
syntax:
html
{{#if themeOptions.logo}}
{{/if}}
{{#if themeOptions.showSidebar}}
{{/if}}
Using Theme Options with Modular Templates
When using modular templates, theme options work seamlessly across all modules:
Main template (page.html):
html
{{module=head.html}}
{{module=header.html}}
{{module=hero-banner.html}}
{{module=sidebar.html}}
{{module=footer.html}}
Header module (header.html):
html
{{#if themeOptions.logo}}
{{else}}
{{siteName}}
{{/if}}
{{#if themeOptions.showSearch}}
{{/if}}
Sidebar module (sidebar.html):
html
{{#if themeOptions.showSidebar}}
{{/if}}
{{#if themeOptions.showBreadcrumbs}}
{{/if}}
Footer module (footer.html):
html
This approach allows you to:
- Organize theme options by component (header options in header.html)
- Maintain consistency across all templates
- Simplify maintenance by keeping related code together
- Reuse components with different theme option configurations
CSS Integration
Using CSS Custom Properties
css
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
--accent-color: #28a745;
}/ Override with theme options /
.theme-blue {
--primary-color: #007bff;
--accent-color: #0056b3;
}
.theme-green {
--primary-color: #28a745;
--accent-color: #1e7e34;
}
.theme-purple {
--primary-color: #6f42c1;
--accent-color: #5a2d91;
}
Dynamic CSS with Theme Options
html
Complete Example: Blog Theme
config.json
json
{
"options": {
"logo": {
"type": "image",
"label": "Logo",
"description": "Upload your site logo"
},
"herobanner": {
"type": "image",
"label": "Hero Banner",
"description": "Hero banner for homepage"
},
"colorScheme": {
"type": "select",
"label": "Color Scheme",
"options": [
{"value": "light", "label": "Light"},
{"value": "dark", "label": "Dark"},
{"value": "auto", "label": "Auto (follows system)"}
],
"default": "light"
},
"primaryColor": {
"type": "color",
"label": "Primary Color",
"default": "#007bff"
},
"showSidebar": {
"type": "checkbox",
"label": "Show Sidebar",
"default": true
},
"sidebarPosition": {
"type": "select",
"label": "Sidebar Position",
"options": [
{"value": "left", "label": "Left"},
{"value": "right", "label": "Right"}
],
"default": "right"
},
"showSearch": {
"type": "checkbox",
"label": "Show Search",
"default": true
},
"footerText": {
"type": "text",
"label": "Footer Text",
"default": "© 2024 My Blog"
},
"socialLinks": {
"type": "array",
"label": "Social Links",
"fields": {
"name": {"type": "text", "label": "Name"},
"url": {"type": "text", "label": "URL"},
"icon": {"type": "text", "label": "Icon Class"}
}
},
"footerText": {
"type": "textarea",
"label": "Footer Text",
"description": "Custom text to display in the footer",
"rows": 3
}
}
}
Template Usage
html
{{title}} - {{siteName}}
{{#if themeOptions.logo}}
{{else}}
{{siteName}}
{{/if}}
{{#if themeOptions.showSearch}}
{{/if}}
CSS with Theme Options
css
:root {
--primary-color: #007bff;
--text-color: #333;
--bg-color: #fff;
--border-color: #e9ecef;
}/ Dark theme /
.theme-dark {
--text-color: #fff;
--bg-color: #1a1a1a;
--border-color: #333;
}
/ Layout variations /
.layout.with-sidebar {
display: grid;
gap: 2rem;
}
.layout.with-sidebar.sidebar-left {
grid-template-columns: 300px 1fr;
}
.layout.with-sidebar.sidebar-right {
grid-template-columns: 1fr 300px;
}
/ Hero banner /
.hero-banner {
background-size: cover;
background-position: center;
padding: 4rem 0;
color: white;
text-align: center;
}
/ Responsive /
@media (max-width: 768px) {
.layout.with-sidebar {
grid-template-columns: 1fr;
}
}
Best Practices
1. Provide Sensible Defaults
Always provide default values for your options:
json
{
"primaryColor": {
"type": "color",
"label": "Primary Color",
"default": "#007bff"
}
}
2. Use Descriptive Labels
Make option labels clear and user-friendly:
json
{
"showSidebar": {
"type": "checkbox",
"label": "Display Sidebar on All Pages",
"description": "Show the sidebar navigation on every page"
}
}
3. Group Related Options
Organize related options together in your config:
json
{
"options": {
"header": {
"logo": { "type": "image", "label": "Logo" },
"showSearch": { "type": "checkbox", "label": "Show Search" }
},
"layout": {
"showSidebar": { "type": "checkbox", "label": "Show Sidebar" },
"sidebarPosition": { "type": "select", "label": "Sidebar Position" }
}
}
}
4. Validate User Input
Always check if options exist before using them:
html
{{#if themeOptions.logo}}
{{/if}}
5. Provide Fallbacks
Use fallback values when options aren't set:
html
Troubleshooting
Common Issues
config.json
Debug Tips
config/theme_options.json
file for saved values