FusionCMS themes can be configured with a variety of different theme options that may affect the design of the theme or even drive advanced functionality. Option values can be changed and customized through the Theme Customizer, which provides an interface for Admin users to easily change and preview their theme's various options.
Theme options are configured in the theme's theme.json
manifest file. The CMS will use the structure from this file to scaffold option groups and field sets. When you visit the Theme Customizer page it will initially use default field values. Once you start customizing options, new values are saved in a separate values file in the public theme directory. Values in this file will always over-ride default values in the manifest file.
Adding Options
Theme options groups and fields are configured through your theme.json
manifest file under an options
value.
{
"name": "My Theme",
"namespace": "MyTheme",
"description": "My very first theme",
"author": "John Doe",
"version": "1.0.0",
"options": {}
}
When customizing a theme, option groups will appear in the customizer sidebar as accordion sections listing out their associated fields.
In the following example, let's add a "Site Globals" option group. Directly under options
, add a unique handle for your section, in this case site_globals
. Under this identifier, we'll add values for the section display name
, description
and a fields
array.
{
"name": "My Theme",
"namespace": "MyTheme",
"description": "My very first theme",
"author": "John Doe",
"version": "1.0.0",
"options": {
"site_globals": {
"name": "Site Globals",
"description": "Options that appear site wide.",
"fields": {}
}
}
}
Note Please format handles to use all lower case and underscores as a standard best practice.
Each section can store any number of field configurations. Please note that although these fields are nested under unique sections, the field handle must still be unique. Most fields will also require a display name
, fieldtype
, default
and help
value.
{
"name": "My Theme",
"namespace": "MyTheme",
"description": "My very first theme",
"author": "John Doe",
"version": "1.0.0",
"options": {
"site_globals": {
"name": "Site Globals",
"description": "Options that appear site wide.",
"fields": {
"message": {
"name": "Message",
"fieldtype": "input",
"type": "text",
"default": null,
"help": "Enter a message that will appear at the top of the page"
}
}
}
}
}
Note: If you do not wish to provide a default value for a field, set it to
null
.
There may be other field values necessary depending on the field type being used. Please keep in mind not all fields available through FusionCMS may be compatible with theme options at this time. You'll find a complete list of customization fieldtypes and usage at the bottom of this document as well as examples of configuration.
Displaying Options
Theme options can be accessed using the theme_option
helper. Simply pass through the option group handle and field handle.
{{ theme_option('site_globals.message') }}
Conditional checks may also be performed using this helper:
@if (theme_option('site_globals.message'))
<div class="site_global-banner">{{ theme_option('site_globals.message') }}</div>
@endif
Note: If a value for a specific option has not been set or configured before, it will fall back to the
default
value of the field defined in the manifest file.
Customizing Options
You can customize your theme options via the FusionCMS Theme Customizer interface. You can access the Theme Customizer in the sidebar of the CMS admin panel under the Customize link. Any options configured through your manifest file will display in the sidebar of this page. As you change the values of options in the theme customizer sidebar, they will be reflected in the live preview screen.
Once you've customized, click save to retain these newly customized option values. This data will be stored in a seperate JSON file under root > storage > app > themes > {MyTheme}.json
. If theme option values exist here they will override the default values entered in the theme's manifest file.
Field Types
A number of field types are available for use with the Theme Customizer. All field types will have the following settings:
Settings | Description | Format |
---|---|---|
Handle | Developer-friendly identifier. | Slug (lowercase, letters & numbers, underscores) |
Name | User-friendly identifier. | String |
Field Type | Name of the field type you wish to render. | String |
Default | A default value or selection. Set null if no default is desired. | String or Null |
Help | Additional instructions written in small print next to the field. | String |
There may be other settings or special circumstances for individual field types. Those will be made note of per field type listed below.
Address
Generate an address field for storing location data. This field has multiple option values that can be accessed and accounted for. The option values return as either null
or a string with the exception of lat
and lng
which will return as a number. Currently a default cannot be set on this field.
JSON
// Example: Location
"location": {
"name": "Location",
"fieldtype": "address",
"default": null,
"help": "Please fill out an address for this location"
}
Option Values
"address1": null,
"address2": null,
"city": null,
"state": null,
"zip": null,
"country": null,
"lat": null,
"lng": null,
"formatted_address": null
Note: Latitude
lat
, Longitudelng
and Formatted Addressformatted_addresss
are only available if a Google Maps API key is provided to fetch this data upon address entry.
Theme Usage
// Basic Address
@if (theme_option('group.location.address1'))
<div class="address">
{{ theme_option('group.location.address1') }}<br>
@if (theme_option('group.location.address2')){{ theme_option('group.location.address2') }}<br> @endif
{{ theme_option('group.location.city') ? theme_option('group.location.city') . ', ' : null }}
{{ theme_option('group.location.state') }}
{{ theme_option('group.location.zip') }}
{{ theme_option('group.location.country') }}
</div>
@endif
// Formatted Address Conditional
@if (theme_option('group.location.formatted_address'))
<div class="address">
{{ theme_option('group.location.formatted_address') }}
</div>
@else
<div class="address">
{{ theme_option('group.location.address1') }}<br>
@if (theme_option('group.location.address2')){{ theme_option('group.location.address2') }}<br> @endif
{{ theme_option('group.location.city') ? theme_option('group.location.city') . ', ' : null }}
{{ theme_option('group.location.state') }}
{{ theme_option('group.location.zip') }}
{{ theme_option('group.location.country') }}
</div>
@endif
// Latitude and Longitude in JS
@if (theme_option('group.location.lat') and theme_option('group.location.lng'))
<script>
var window.latitude = theme_option('group.location.lat');
var window.longitude = theme_option('group.location.lng');
</script>
@endif
Color Picker
Generate an color picker field for assigning hex or rgba color values to elements. The option value returns as either null
or a string.
JSON
// Example: Background Color
"background": {
"name": "Backgrond Color",
"fieldtype": "color-picker",
"default": "#ffffff",
"help": "Choose a color for the body background"
},
Theme Usage
// Inline CSS
<body @if(theme_option('group.background'))style="background-color: {{ theme_option('group.background') }}"@endif>
</body>
// Internal CSS
<style>
body {
background-color: {{ theme_option('group.background') ?? '#ffffff' }};
}
</style>
A more dynamic way of setting up color picker for customizable design branding would be to set color values to CSS variables and reference those variables in your external style sheets. These can then be overridden with internal CSS values on the page.
// External CSS (overridden with internal CSS)
// Assuming you have a --body-background CSS variable you're referencing in your external style sheet
<head>
<link rel="stylesheet" href="/theme/css/theme.css" media="screen">
<style>
:root {
--body-background: {{ theme_option('group.background') }};
}
</style>
</head>
Input
Generate an input field for simple text content. The option value returns as either null
or a string.
JSON
// Example: Name input
"name": {
"name": "Name",
"fieldtype": "input",
"default": "Enter text here",
"help": "Please provide a name using the space above"
},
Theme Usage
Hello, my name is {{ theme_option('group.name') }}.
// Conditional
@if (theme_option('group.name')
Hello, my name is {{ theme_option('group.name') }}.
@endif
Markdown
Generate a markdown editor field for rich text content. The option value returns as either null
or a string.
JSON
// Example: Content Area
"content": {
"name": "Page Content",
"fieldtype": "markdown",
"default": null,
"help": "Use markdown to add page content"
},
Theme Usage
<div class="content">
{!! render_markdown(theme_option('group.content')) !!}
</div>
// Conditional
@if (theme_option('group.content')
<div class="content">
{!! render_markdown(theme_option('group.content')) !!}
</div>
@endif
Note: Use Fusion's
render_markdown
helper in addition to Blade's U\unescaped brackets{!! !!}
in order to properly render the markdown on your page.
Redactor
Generate a redactor WYSIWYG field for rich text content. The option value returns as either null
or a string.
JSON
// Example: Alert Banner
"alert": {
"name": "Alert Banner",
"fieldtype": "redactor",
"default": null,
"help": "Add text to display an alert banner"
},
Theme Usage
<div class="alert">
{!! theme_option('group.alert') !!}
</div>
// Conditional
@if (theme_option('group.alert')
<div class="alert">
{!! theme_option('group.alert') !!}
</div>
@endif
Textarea
Generate a textarea field for extended text content. The option value returns as either null
or a string.
JSON
// Example: Message text
"message": {
"name": "Message",
"fieldtype": "textarea",
"default": "Enter extended text here",
"help": "Add some text to display a message on the page"
},
Theme Usage
<p>{{ theme_option('group.message') }}</p>
// Conditional
@if (theme_option('group.message')
<p>{{ theme_option('group.message') }}</p>
@endif
FAQs
Is it possible to access the options JSON structure in the theme.json
manifest file instead of only returning the option value?
Yes. Instead of using the theme_options
helper, use the theme
. This helper function directly returns values set in the manifest file, so you will need to call the full option path. Example:
// Get the theme option value, whether default or customized
theme_option('site_globals.message');
// Get literal values directly from the manifest
theme('options.site_globals.fields.message.default');
My options are not showing up in the theme customizer or the theme customizer is returning an error, how can I fix this?
This issue most commonly occures when you have a syntax error in the JSON of your theme.json
manifest file. There are likely to be other errors occurring on the front end of your site if this is the case.
You may be using a reserved keyword as the handle of an option group or field. Compare your field handle to the list of reserved keywords or try a different handle to see if this may be the issue.
If all else fails, try clearing out your old theme options storage file. All theme options are stored in a seperate JSON file under root > storage > app > themes > {MyTheme}.json
. Once deleted, simply visit the frontend of your site to re-generate and try the customizer again.
Can I set up validation rules for my theme option fields?
Unfortunately we are unable to enforce the validation rules during live preview. To avoid confusion we do not enforce strict validation on these fields since it would allow you to enter and preview something invalid yet not be allowed to save that value. All theme options should be assumed "optional". You can assign a default per field in cases where something should always be set and anticipated yet may not be provided.