Advanced Theme Settings

Advanced Theme Settings in Drupal 8

Have you ever altered the appearance settings of a theme and wondered how it gives its very own custom  alternatives?  Wouldn’t it be awesome if you could customize the list in the theme settings?  Well this can be achieved very easily in Drupal 8.

Basic Steps:

1.Add fields to Appearance->Theme Settings.

2.Define variables for those settings.

3.Use those variables in templates.

 1.Create Custom Theme Settings:

These fields appear in /admin/appearance/settings/themename.

Here is the simple use case :

To achieve this, add the settings in theme-settings.php file. If you don’t already have this , add the file in the root of your theme.

Wrap the custom settings in a function:

function themename_form_system_theme_settings_alter(&$form, &$form_state) {

// my code

 a) To add secondary logo:
$form['secondary_logo'] = array( 

    '#type' => 'managed_file', 

    '#title' => t('Secondary Logo'), 

    '#required' => FALSE, 

    '#upload_location' => 'public://', 

    '#default_value' => theme_get_setting('secondary_logo'),  

    '#upload_validators' => array( 

      'file_validate_extensions' => array('gif png jpg jpeg'), 



Code Description:

secondary_logo‘: This is the name of the setting.

#type‘:  It is the type of the field. This uses the Drupal 8 Form API, so there are many options of what kind of field to add. Here we are         using managed_file to upload a image.

#title’ :  It is the label of the field

‘#required’ :  Whether the field is required or not .TRUE implies required and FALSE implies optional.

‘#upload_location’ : The location of the uploaded file.

‘#default_value’:  Tells Drupal where to find the initial setting for the form element.

‘#upload_validators’ : Validates the extensions of the file

b) Create settings for Contact Information:

Create a section:

$form['footer_contact'] = array( 

    '#type'  => 'details', 

    '#title' => t('Contact Information'), 

    '#open' => TRUE, 


Code Description:

‘footer_contact’: Is the name of the group. It can be anything you want to have and use underscores between words.

‘#open’ : A group is collapsible. TRUE makes it open by default. FALSE has it closed by default.

Create Settings for the above group:’footer_contact’.

Each field has its own code block. Place it directly after where you defined the group.

$form['footer_contact']['contact_title'] = array( 

    '#type' => 'textfield', 

    '#title' => t('Contact Title'), 

    '#default_value' => theme_get_setting('contact_title'), 


Similarly you can add other settings to the file.Here is the complete code for the theme-settings.php file


function customTheme_form_system_theme_settings_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id=NULL) {
     if(isset($form_id)) {
//create setting for secondary logo
    $form['secondary_logo'] = array(
    '#type' => 'managed_file',
    '#title' => t('Secondary Logo'),
    '#required' => FALSE,
    '#upload_location' => 'public://',
    '#default_value' => theme_get_setting('secondary_logo'), 
    '#upload_validators' => array(
      'file_validate_extensions' => array('gif png jpg jpeg'),
//creating setting for footer information
   $form['footer_contact'] = array(
    '#type'         => 'details',
    '#title'        => t('Contact Information'),
    '#open'         => TRUE,
   $form['footer_contact']['contact_title'] = array(
    '#type'           => 'textfield',
    '#title'          => t('Contact Title'),
    '#default_value'  => theme_get_setting('contact_title'),
   $form['footer_contact']['address'] = array(
    '#type'           => 'textarea',
    '#title'          => t('Address'),
    '#default_value'  => theme_get_setting('address'),
   $form['footer_contact']['email'] = array(
    '#type'           => 'email',
    '#title'          => t('Email'),
    '#default_value'  => theme_get_setting('email'),
   $form['footer_contact']['phone'] = array(
    '#type'           => 'tel',
    '#title'          => t('Telephone'),
    '#default_value'  => theme_get_setting('phone'),
//creating setting for copyright
  $form['copyright'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Copyright'),
    '#default_value' => theme_get_setting('copyright'),
    '#description'   => t("Copyright text that appears in the footer next to the Copyright symbol and year."),
//Creating settings for social links
  $form['social_icon'] = array(
    '#type'         => 'details',
    '#title'        => t('Social Icons'),
    '#open'         => TRUE,
  $form['social_icon']['facebook_url'] = array(
    '#type' => 'textfield',
    '#title' => t('Facebook URL'),
    '#default_value' => theme_get_setting('facebook_url'),
  $form['social_icon']['twitter_url'] = array(
    '#type' => 'textfield',
    '#title' => t('Twitter URL'),
    '#default_value' => theme_get_setting('twitter_url'),
  $form['social_icon']['linkedin_url'] = array(
    '#type' => 'textfield',
    '#title' => t('LinkedIn URL'),
    '#default_value' => theme_get_setting('linkedin_url'),

2.Create variables from settings:

We define variables in themename.theme .  I will use themename_preprocess_page() function.

* Implements theme_preprocess_page().
function themename_preprocess_page(&$variables) {
 // my code

Get the theme setting values and define variables.  For example,

$variables['address'] = theme_get_setting('address');

1.The first ‘address’ is the name of the variable.

2.The second ‘address’ is the name for the setting that I used in themename-settings.php file.

Here is the complete code for the themename.theme file.


 use Drupal\file\Entity\File; 

 use Drupal\core\Url; 

 function customTheme_preprocess_page(&$variables, $hook) { 
    global $base_url; 
    $fid = theme_get_setting('secondary_logo'); 
      $file = File::load($fid[0]); 
     if(!empty($file)) { 
       $variables['secondarylogo_url'] = $file->url(); 
     else { 
      $variables['secondarylogo_url'] = $base_url . '/' . \Drupal::theme()->getActiveTheme()->getPath() . '/images/drupal8logo.jpg'; 
     $variables['contact_title'] = theme_get_setting('contact_title'); 
     $variables['address'] = theme_get_setting('address'); 
     $variables['email'] = theme_get_setting('email'); 
     $variables['phone'] = theme_get_setting('phone'); 
     $variables['copyright'] = theme_get_setting('copyright'); 
     $variables['facebook_url'] = theme_get_setting('facebook_url'); 
     $variables['twitter_url'] = theme_get_setting('twitter_url'); 
     $variables['linkedin_url'] = theme_get_setting('linkedin_url'); 

3.Use Theme setting variables in Template files

Place the theme setting variables in the .html.twig file like shown below.

<div class="site-footer__bottom">
           <div class = "content">
            {% if copyright %}
              <p>© {{ "now"|date("Y") }},{{ copyright }}</p>
            {% endif %}
            {% if facebook_url%}
            <div class = social-icons>
            <a href = {{ facebook_url }}><i class="fa fa-facebook-square fa-lg"></i></a>
            <a href = {{ twitter_url }}><i class="fa fa-twitter-square fa-lg" ></i></a>
            <a href = {{ linkedin_url }}><i class="fa fa-linkedin-square fa-lg"></i></a>
            {% endif %}

4.Default value for Theme Settings

1.Create themename.settings.yml in themename/config/install.

2.Create a line for each setting.

contact_title: "Contact Information";

email: "";

phone: "123456789";

copyright: "Company";


By leveraging custom theme settings, themers can create a variety of controls to help site builders customize their sites.



About The Author