Creating advanced theme settings

Last updated on
31 August 2016

In the Drupal administration section, each theme has its own settings page at admin/appearance/settings/themeName. And this page has a form with standard settings like “Logo image settings” and “Shortcut icon settings.”

In Drupal 8, themes can modify the entire theme settings form by adding a PHP function to either the THEMENAME.theme file or to a theme-settings.php file. In one of those files, a theme should use THEMENAME_form_system_theme_settings_alter(&$form, $form_state) hook function. See the “Form API in Drupal 8” and the complete list of Form and render elements, as well as the hook_form_FORM_ID_alter() docs to learn the full flexibility of Forms API.

Here’s an example if you had a “foo” theme and wanted to add a textfield whose default value was “blue bikeshed”. Add the following to the foo/foo.theme file or to the foo/theme-settings.php file:

function foo_form_system_theme_settings_alter(&$form, \Drupal\Core\Form\FormStateInterface &$form_state, $form_id = NULL) {
  // Work-around for a core bug affecting admin themes. See issue #943212.
  if (isset($form_id)) {
    return;
  }

  $form['foo_example'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Widget'),
    '#default_value' => theme_get_setting('foo_example'),
    '#description'   => t("Place this text in the widget spot on your site."),
  );
}

In order to set the default value for any form element you add, you’ll need to add a config/install/THEME.settings.yml file with a simple line: SETTING_NAME: DEFAULT_VALUE. For our foo theme, you’d need to edit the foo/config/install/foo.settings.yml file and add this line:

foo_example: blue bikeshed

In any of your theme’s PHP files, you can retrieve the value the user set by calling:

$foo_example = theme_get_setting('foo_example');

Note that theme authors can create complex, dynamic forms using advanced Forms API (auto-completion, collapsible fieldsets.)

Getting the settings’ values in your theme files

In order to use a setting in a Twig file, you'll have to add a new variable to the Twig file by adding it with a preprocess function in your THEMENAME.theme file. $variables['varname'] = theme_get_setting('varname')

For example, to add our foo_example setting to the node.html.twig file, add this to the foo.theme file:

<?php
function foo_preprocess_node(&$variables) {
$variables['foo_example'] = theme_get_setting('foo_example');
}

Then in the node.html.twig file, you can access foo_example like any normal Twig variable:

{{ foo_example }}

More information

See the change record for Drupal 8: https://www.drupal.org/node/2382645