Setting for custom theme Drupal 9

Sooner or later, for everyone who creates themes for sites, there comes a period when he gets tired of customers' requests to make small changes to the code, for example, the color of the text or the width of the page. Using the example of a custom theme and Drupal 9, we will consider how to add some elements to the theme settings that will later be displayed in styles.

In general, adding settings can be divided into four parts: changes in file themename.info.yml, create a settings file if it does not exist yet theme-settings.php, then in themename.theme, and finally output in styles.

First, we will add a field in the settings in which we will store the width of the page.

In themename.info.yml we add

settings:
  container_width: 1200

in the future, other settings can be added after container_width: 1200.

Then we add in theme-settings.php

<?php

function themename_form_system_theme_settings_alter(&$form, &$form_state) {
	$form['themename_settings']['container_width'] = [
        '#type' => 'number',
        '#title' => t('Container Width'),
        '#default_value' => theme_get_setting('container_width'),
        '#description' => t('Specify the width of the container in pixels.'),
        '#required' => TRUE,
        '#min' => 1,
        '#max' => 9999,
        '#maxlength' => 4,
    ];
}

Here we will immediately make a small protection - it will be possible to enter only a number from 1 to 9999 in the field for the size, so that there is no desire to enter some text.

Then we add in themename.theme

function themename_preprocess_html(&$variables) {
	$container_width = theme_get_setting('container_width');
    $inline_css = ":root { --container_width: {$container_width}px; }";
    $variables['#attached']['html_head'][] = [
		[
			'#tag' => 'style',
            '#value' => $inline_css,
        ],
        'container_width_style',
    ];	
}

As you can see, we register a variable that will output the size of anything in styles, immediately in pixels. If desired, you can change to percentages or other units.

And finally, in the styles, you can derive our value from the settings

.container {
    max-width: var(--container_width);
}

Also, let's add a color picker setting to the theme settings. For example, we want to change the color of paragraphs from the admin.

In info.yml we add 

test_color: '#ff0000'

so, our setting well be like this

settings:
  container_width: 1200
  test_color: '#ff0000'

Then, in setting-themes.php

 $form['themename_settings']['test_color'] = [
        '#type' => 'color',
        '#title' => t('Theme Test Color'),
        '#default_value' => theme_get_setting('test_color'),
        '#description' => t('Choose the main color for the paragraph.'),
    ];

In themename.theme, in our _preprocess_html function

$test_color = theme_get_setting('test_color');
$inline_css = ":root { --test_color: {$test_color}; }";
$variables['#attached']['html_head'][] = [
	[
    	'#tag' => 'style',
        '#value' => $inline_css,
    ],
    'test_color_style',
];

And in css file

p {
    color: var(--test_color);
}

It is worth clarifying that the color type (rgb, hex ...) changes on the theme settings page itself, and as you can see, we do not specify type it in the themename.theme file.

All that remains for us is to clear the cache and admire the changes.

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
The comment language code.