FusionCMS is currently in an open beta state and under heavy active development.

Theme Options

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, Longitude lng and Formatted Address formatted_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.

Have questions?

We're always happy to help with code or other questions you might have. Contact support or chat live with us on Discord.

Last edited on Friday, July 10, 2020 (4 years ago)