Skip to main content

Add a background image form to a Drupal 7 theme setting form

Recently I needed to have a dynamically changing background image for a Drupal 7 theme I was working on. Allowing the user to change this background image directly from theme's settings page.

How to add a dynamic background image to a Drupal theme

  1. The first step is to add a file named 'theme-settings.php' to your theme.
  2. Next, we need to add our background image form. I came up with the code below based on the standard logo form that is on by default for all themes:

    1. /**
    2.  * Implements hook_form_FORM_ID_alter().
    3.  *
    4.  * @param $form
    5.  *   The form.
    6.  * @param $form_state
    7.  *   The form state.
    8.  */
    9. function MYTHEME_form_system_theme_settings_alter(&$form, &$form_state) {
    10.  
    11.   $form['background_image'] = array(
    12.     '#type' => 'fieldset',
    13.     '#title' => t('Background image'),
    14.   );
    15.  
    16.   $form['background_image']['default_background_image'] = array(
    17.     '#type' => 'checkbox',
    18.     '#title' => t('Use the default background image'),
    19.     '#default_value' => theme_get_setting('default_background_image'),
    20.   );
    21.  
    22.   $form['background_image']['settings'] = array(
    23.     '#type' => 'container',
    24.     '#states' => array(
    25.       // Don't show any extra forms when none is selected.
    26.       'invisible' => array(
    27.         ':input[name="default_background_image"]' => array('checked' => TRUE),
    28.       ),
    29.     ),
    30.   );
    31.  
    32.   $form['background_image']['settings']['background_image_upload'] = array(
    33.     '#type' => 'file',
    34.     '#title' => t('Upload a new background image'),
    35.     '#maxlength' => 40,
    36.     '#description' => t('Upload a new background image for this theme. 1920x1080.') . '<div>' . theme('image', array('path' => image_style_url('thumbnail', theme_get_setting('background_image_path')))) . '</div>',
    37.   );
    38.  
    39.   $form['#validate'][] = 'MYTHEME_form_system_theme_settings_validate';
    40.   $form['#submit'][] = 'MYTHEME_form_system_theme_settings_submit';
    41.  
    42. }

  3. The next step is to handle the file upload with our custom validate and submit function (I borrowed the file handling from the noggin module).

    1. function MYTHEME_form_system_theme_settings_validate($form, &$form_state){
    2.   // Handle file uploads.
    3.   $validators = array('file_validate_is_image' => array());
    4.   // Check for a new uploaded logo.
    5.   $file = file_save_upload('background_image_upload', $validators);
    6.   if (isset($file)) {
    7.     // File upload was attempted.
    8.     if ($file) {
    9.       // Put the temporary file in form_values so we can save it on submit.
    10.       $form_state['values']['background_image_upload'] = $file;
    11.     }
    12.     else {
    13.       // File upload failed.
    14.       form_set_error('background_image_upload', t('The background image could not be uploaded.'));
    15.     }
    16.   }
    17. }
    18.  
    19. function MYTHEME_form_system_theme_settings_submit($form, &$form_state){
    20.   $values = $form_state['values'];
    21.   // If the user uploaded a new header image, save it to a permanent location
    22.   if ($file = $values['background_image_upload']) {
    23.     unset($values['background_image_upload']);
    24.     $filename = file_unmanaged_copy($file->uri);
    25.     $form_state['values']['background_image_path'] = $filename;
    26.   }
    27. }

  4. The last step is to set your new background image as a variable in your tpl files. To do this, we implement theme_preprocess_page() in our template.php file:

    1. function MYTHEME_preprocess_page(&$vars) {
    2.  
    3.     if($bg = theme_get_setting('background_image_path')) {
    4.      $vars['background_image'] = theme('image', array('path' => file_create_url($bg))); 
    5.     } 
    6.     else {
    7.       $vars['background_image'] = theme('image', array('path' => base_path() . drupal_get_path('theme', 'MYTHEME') . '/images/default_background_image.jpg'));
    8.     }
    9. }

Done!


Comments