
How to Add Theme Settings for Drupal 7
You know that list of checkboxes on the theme settings page that let you turn on and off parts of the theme like the logo or slogan? Well, you can add your own options to that list really easily in Drupal 7. In D6, this was kind of a pain, because you had to write all sorts of functions to save and load your settings to the database and handle everything properly. In D7, that's all done through the Form API, so the heavy lifting is done for you. All you need to do is tell it to add some form fields, and what the new setting is called!
You'll need to create a theme-settings.php
file in your theme, and add this code to it:
<?php function themename_form_system_theme_settings_alter(&$form, &$form_state) { $form['theme_settings']['your_option'] = array( '#type' => 'checkbox', '#title' => t('Your Option'), '#default_value' => theme_get_setting('your_option'), ); }
['theme_settings']
is the existing fieldset to add your option to. You can leave it off, but by pointing it to thetheme_settings
group, it'll be added to the existing list of checkbox display options for your theme. Handy!['your_option']
is the name of your new option.#type
tells Drupal what kind of form element to create.#title
is the title (or in this case, label) text for the form element.#default_value
tells Drupal where to find the initial setting for the form element.
We set #default_value
to theme_get_setting('your_option')
, which tells Drupal to look for this setting in the database. But here's the brilliant part -- if it can't find that setting in the database, it will check in your theme's .info
file! So add this line:
settings[your_option] = 1
Now your theme will use the default setting unless the admin overrides it on the theme settings page.
You'll want to actually do something with this setting, so here's the PHP call to load it.
theme_get_setting('your_option');
You can call this in from any of your .tpl.php
files. For a simple checkbox option like this, you can build an if()
statement around it, like so:
<?php if (theme_get_setting('your_option')): ?> <!-- Your code here! --> <?php endif; ?>
In this example, we added a checkbox, but you can add just about any form elements you can think of, including radio buttons and text input fields. What sort of options will you add to your theme?
References
- theme_get_setting() and THEME_settings() improvements in Drupal 7
- Drupal 7 form API reference
- Advanced theme settings - this is for D6, but it's still helpful
Comments
Thanks Scott - don't have any immediate need for Drupal, but this is so clear and nicely explained, it has me excited to get a project. :) Cheers
Chris (yakker - drupal.org)
Fri, 11/05/2010 - 16:22
Does this actually work for you? I'm trying to add a text field to a Drupal 7 theme but nothing's coming out on the theme's setting page and I also don't have any output on the site, even though I set a default value in the theme's info file. So the problem is probably in theme-settings.info and I'm not too sure about the syntax there. Yours is different from the one in http://drupal.org/update/theme/6/7#theme-settings, and the one over there has a mistake in it (I think - using caberet instead of foo once). Also not sure about PHP tags - opening and closing, just opening? I have cleared caches btw.
Fri, 11/05/2010 - 20:51
Yeah, it is working for me. Without seeing your source, I couldn't tell you what's wrong - feel free to email me (scott at metaltoad).
One thing to check is make sure the function includes your theme's name, and another is that you're using the same setting name throughout.
We'll be posting a new theme very soon which includes this technique.
As for PHP tags, you only need the opening tag in theme-settings.php, but it won't hurt to add the closing tag. One of our programmers explained why to me once, and I forget the logic, but basically if it's a stright PHP file, you don't need the closing tag.
Sat, 03/05/2011 - 13:45
You want to omit the closing PHP tahs, unless they're needed.
Fri, 11/05/2010 - 23:44
Oh yeah. I was doing everything right. Except I named the file theme-settings.tpl.php instead of theme-settings.php. And that was the only place I didn't check a million times for mistakes :) Thanks!
Thu, 11/11/2010 - 01:06
>In D6, this was kind of a pain, because you had to write all sorts of functions to save and load your settings to the database and handle everything properly.
This is not correct: this work the same in D6. Look in system.admin.inc, line 506.
Thu, 11/11/2010 - 18:20
Sorry if I explained it poorly - I'm not a programmer, so this is all Greek to me. However, this page makes it clear that D7 expands the abilities available to themes: "This gives the same power to themes that modules have if they use hook_form_system_theme_settings_alter()." As it was explained to me, that mostly meant that in D7, the form API automatically handles some things like saving your settings.
Tue, 01/11/2011 - 15:15
I used it successfully in theme-settings.php altering the 3 available groups theme_settings, logo, favicon.
What if I want to create another custom group in the theme settings page? How can I achieve that? add another form under the 3 instead of altering one
Thu, 01/27/2011 - 00:21
When I first started working with Drupal everything was hard. It was much more customizable than any other similar platform but in the same time very basic things would take time to accomplish. In the new version it seems that Drupal, as a blogging platform, has now surpassed the functionality which paid Wordpress themes like Thesis have. It's really cool!
Thu, 02/24/2011 - 12:29
Is there any way you can tell how to add (for example) secondary logo in theme? I cant find anywhere how to do that in Drupal 7.
Thanks.
Mon, 03/28/2011 - 10:02
Fantastic guide! Thanks for the code reference.......... it was useful!
Sun, 04/17/2011 - 12:22
same here.
Tue, 04/19/2011 - 16:20
the noggin modules shows how to handle file uploads for a theme in D7..
Thu, 09/15/2011 - 17:07
Yeah, the noggin did it :D - thanks a lot!
Tue, 06/07/2011 - 09:42
Had no idea you could do this kind of thing. Thanks so much for the writeup!
Sun, 10/30/2011 - 18:29
Hmm, how I can check whether the form was sent before load the page after send?
This code not working :( -->
function themename_settings_submit($form, &$form_state) { $settings = array(); // Check for a new uploaded file, and use that if available. if ($file = file_save_upload('sublogo_upload')) { $parts = pathinfo($file->filename); $destination = 'public://' . $parts['basename']; $file->status = FILE_STATUS_PERMANENT; if (file_copy($file, $destination, FILE_EXISTS_REPLACE)) { $_POST['sublogo_path'] = $form_state['values']['sublogo_path'] = $destination; } } }
Wed, 11/16/2011 - 04:14
True. It is such a hassle when you're not sure what you're doing. Anyway, his is great, more theme options the better. I love to tinker around with Drupal once in a while even though it's a bit more complicated than other platforms. Thanks for sharing your code!
Wed, 01/04/2012 - 21:08
Thanks for sharing.
Thu, 04/26/2012 - 19:02
Sweet, thanks! I was actually looking to do the reverse of this post, which was to REMOVE specific theme settings. This post got me headed in the right direction, and with some $form['theme'] = NULL; statements I was off and running! Thanks folks!
Sun, 07/20/2014 - 18:39
Suppose that we want to add settings for a set of images that should be uploaded from the theme settings:
for ($i = 0; $i < 7; $i++){ $form['best_responsive_settings']['slideshow']['slideimages'][] = array( '#type' => 'managed_file', '#title' => t('Image').' #'.$i, '#upload_location' => file_default_scheme() . '://slides', '#default_value' => theme_get_setting('slideimages','best_responsive'), '#upload_validators' => array( 'file_validate_extensions' => array('gif png jpg jpeg')), ); }
Here the files are uploaded successfully but when trying to reload the theme settings screen or trying to access them from the tpl.php, they could not be accessed:
//page.tpl.php print_r(theme_get_setting('slideimages','best_responsive')); //empty print_r output. it supposed to be an array!
Tue, 08/26/2014 - 20:49
It does not save checkbox statement...
function volkov_form_system_theme_settings_alter(&$form, &$form_state) { $form['theme_settings']['home_slider_autoplay'] = array( '#type' => 'checkbox', '#title' => t('Autoplay Home Slider?'), '#default_value' => theme_get_setting('home_slider_autoplay'), ); }
Tue, 09/30/2014 - 11:51
Is it possible to assign roles / permissions to theme options? If so: how?
Fri, 06/26/2015 - 06:51
You have explained it Very clearly. Understood the whole thing . once again thanks for help. You are awesome!
Fri, 11/05/2010 - 02:06