Drupal 7: Generate and Save Files Programmatically

Drupal 7: Generate and Save Files Programmatically

Generate and save files programmatically

On a couple occasions I found it necessary to generate and save a file from within a module or theme. The last time it was to create a custom stylesheet based on values from theme settings, so I'll use that in my example on how you can do the same. The first thing to do, of course, is to alter the system theme settings form with your custom fields using hook_form_system_theme_settings_alter(). We'll create one field to change the background color of the body and add a custom submit handler to take care generating the custom stylesheet. Create a theme-settings.php file in your theme/module directory, and add the following code. Remember to change "hook" to your theme/module machine name and "_custom_system_theme_settings_submit" to a unique function name.

/**
 * Implements hook_form_system_theme_settings_alter().
 */
function HOOK_form_system_theme_settings_alter(&$form, &$form_state) {
  // Add a textfield to change the background color of the body.
  $form['body_background_color'] = array(
    '#type' => 'textfield',
    '#title' => t('Change body background color'),
    '#default_value' => theme_get_setting('body_background_color'),
    '#description' => t('Enter a valid hex color value. For example: #eee'),
  );
 
  // Add a custom submit handler.
  $form['#submit'][] = '_custom_system_theme_settings_submit';
}
 
/**
 * Process system_theme_settings form submissions.
 */
function _custom_system_theme_settings_submit($form, &$form_state) {
  // Add the body background color value to $data, which will be saved to a
  // file.
  $data = 'body{background-color:';
  $data .= $form_state['values']['body_background_color'];
  $data .= ';}';
 
  // Save the file to the site's public css directory. This will replace the
  // file if it already exists.
  file_save_data($data, 'public://css/custom-styles.css', FILE_EXISTS_REPLACE);
 
  // Change query-strings on css/js files to enforce reload for all users.
  _drupal_flush_css_js();
 
  drupal_clear_css_cache();
  drupal_clear_js_cache();
 
  // Clear the page cache, since cached HTML pages might link to old CSS and
  // JS aggregates.
  cache_clear_all('*', 'cache_page', TRUE);
}

Now that you saved the file, it's time to add it to all pages. We saved it as a managed file, so a record of it is kept in the database. I like to do this in template_preprocess() for simplicity, but this can be done almost anywhere.

/**
 * Implements template_preprocess().
 */
function HOOK_preprocess(&$variables) {
  // Retrieve the generated stylesheet and add it to all pages.
  $filename = 'custom-styles.css';
  $file = db_query('SELECT uri FROM {file_managed} WHERE filename = :file',
    array(':file' => $filename))
    ->fetchField();
 
  drupal_add_css($file, array(
    'group' => CSS_THEME,
    'every_page' => TRUE
  ));
}

Your custom stylesheet will now be added to every page. I would recommend you add some extra code to check if the file exists before adding it to the page, even if only to log it using watchdog(). This would help you track down the problem, especially since drupal_add_css() won't throw off any error messages if the file isn't found.

Comments (0)


Add new comment

The content of this field is kept private and will not be shown publicly.

Plain text

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