0

I am creating a drupal module (my first) and I wish to simply store some variables.

I previousely did this by adding some form elements to the theme-settings.php file but now I want to have my own module.

I created my module and form and menu elements and that all seems to be fine. Problem is that nothing seems to be saving to the database. Or maybe is is saving but not retreiving.

This is what I have so far:

my_module.module:

/**
 * @file
 * My Module Settings.
 */

/**
 * Implements hook_help().
 */
function mynewmodule_settings_help($path, $arg) {
  /* INFO:
   * The help hook is for displaying helpful messages at the top of pages indicated
   * by $section to further explain how they work. Adding certain "keywords" to the end of 
   * a given path (like admin/modules#description) will cause this text to display elsewhere
   * in the page as well (in this case, in the description section for the given module).
   */
  switch ($path) {
    case 'admin/help#mynewmodule_settings':
      return t("TODO: Create admin help text for My Module.");
    case 'admin/config/system/mynewmodule':
      return t('My Module help text will go here.');
  }
}

/**
 * Implements hook_permission().
 */ 
function mynewmodule_settings_permission() {
  return array(
    'administer my module' => array(
      'title' => t('Administer My Module Settings'),
    )
  );
}

/**
 * Implements hook_menu().
 */
function mynewmodule_settings_menu() {
  $items = array();
  $items['admin/config/system/mynewmodule'] = array(
    'title' => 'My Module Settings',
    'description' => 'Administer My Module Settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('mynewmodule_admin_settings'),
    'access arguments' => array('administer my module'),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'mynewmodule_settings.admin.inc',
  );
  return $items;
}

And here is my form (mynewmodule_settings.admin.inc):

// $Id$
/**
 * @file
 * My Module Settings
 *
 * @author Cybercampbell
 */

/**
 * Admin configuration form
 */
function mynewmodule_admin_settings() {

$form = array(
    '#type' => 'fieldset',
    '#title' => t('My Module Settings'),
    '#collapsible' => FALSE,
    '#collapsed' => FALSE,
  );

  $form['breadcrumb'] = array(
    '#type' => 'fieldset',
    '#title' => t('Breadcrumb'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  $form['breadcrumb']['breadcrumb_display'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show breadcrumb'),
    '#description'   => t('Use the checkbox to enable or disable Breadcrumb.'),
    '#default_value' => theme_get_setting('breadcrumb_display','mymodule'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

 /**
 * SOCIAL
 */

  $form['social'] = array(
    '#type' => 'fieldset',
    '#title' => t('Social Settings'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  /**
 * FACEBOOK
 */
 $form['social']['facebook_display'] = array(
    '#type' => 'checkbox',
    '#title' => t('Facebook'),
    '#description'   => t('Use the checkbox to enable or disable the Facebook button.'),
    '#default_value' => theme_get_setting('facebook_display','mymodule'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  $form['social']['facebook_id'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Facebook ID'),
    '#default_value' => theme_get_setting('facebook_id','mymodule'),
    '#size' => 32,
  );

/**
 * TWITTER
 */  
   $form['social']['twitter_display'] = array(
    '#type' => 'checkbox',
    '#title' => t('Twitter'),
    '#description'   => t('Use the checkbox to enable or disable the Twitter button.'),
    '#default_value' => theme_get_setting('twitter_display','mymodule'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  $form['social']['twitter_id'] = array(
    '#type'          => 'textfield',
    '#title'         => t('Twitter ID'),
    '#default_value' => theme_get_setting('twitter_id','mymodule'),
    '#size' => 32,
  );

  /**
 * RSS
 */  
   $form['social']['rss_display'] = array(
    '#type' => 'checkbox',
    '#title' => t('RSS'),
    '#description'   => t('Use the checkbox to enable or disable the RSS button.'),
    '#default_value' => theme_get_setting('rss_display','mymodule'),
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  );

  // Attach custom submit handler to the form
  $form['#submit'][] = 'mymodule_settings_submit';

  $print_footer_text = theme_get_setting('print_footer');
  $form['print_footer'] = array(
    '#type'          => 'text_format',
    '#title'         => t('Footer Text'),
    '#rows'          => 5,
    '#resizable'    => FALSE,
    '#default_value' => !empty($print_footer_text['value']) ? $print_footer_text['value'] : '',
    '#format' => !empty($print_footer_text['format']) ? $print_footer_text['format'] : 'full_html',
  );

  return system_settings_form($form);
}

This code worked fine in the theme.settings.php file. Any ideas where i'm going wrong here?

  • 1
    As side note, there is no need to pass an empty string to t(): An empty string is still an empty string, in any language you translate it. ;) – kiamlaluno Sep 25 '12 at 7:44
3

The values entered in the form are saved, but not in the Drupal variable theme_get_setting() is looking for.

If you look at the code of the function, you will notice the following code:

// Get the saved global settings from the database.
$cache[$theme] = array_merge($cache[$theme], variable_get('theme_settings', array()));

if ($theme) {
  // Get the saved theme-specific settings from the database.
  $cache[$theme] = array_merge($cache[$theme], variable_get('theme_' . $theme . '_settings', array()));

  // If the theme does not support a particular feature, override the global
  // setting and set the value to NULL.
  if (!empty($theme_object->info['features'])) {
    foreach ($features as $feature) {
      if (!in_array($feature, $theme_object->info['features'])) {
        $cache[$theme]['toggle_' . $feature] = NULL;
      }
    }
  }

  // …

}

The Drupal variable used to save the theme settings is theme_$theme_settings (where $theme is the theme name). The form submission handler your code is using doesn't save the form values in that Drupal variable, and theme_get_setting() will not find them.

The other issue with your code is that it is not sharing any setting with the theme; for that to happen, the second parameter for theme_get_setting() should not get any argument. In fact, the second parameter is described as, "The name of a given theme; defaults to the current theme."

If you want to add settings that the currently enabled theme, or any module, would find with theme_get_settings(), you should implement hook_form_system_theme_settings_alter(), which is an implementation of hook_form_FORM_ID_alter() for the form build from system_theme_settings(). The hook is particular because system_theme_settings() will look for the implementation of that hook done from the currently set theme, or the currently set theme engine.

If the settings are just for your module, and it doesn't need to be shared with other modules (or the current theme) via theme_get_setting(), then you can simply use variable_get(). In that case, you don't need to use a form submission handler that is different from the one set by system_settings_form().
See the code used from system_theme_settings(), which contains the following lines.

  $form = system_settings_form($form);
  // We don't want to call system_settings_form_submit(), so change #submit.
  array_pop($form['#submit']);
  $form['#submit'][] = 'system_theme_settings_submit';
  $form['#validate'][] = 'system_theme_settings_validate';
  return $form;  
  • Thanks for th detailed answer. I will admit I'm a little out of my depth here but i'm trying to get my head around it all. I now have the module working. all I did was change this: function mynewmodule_admin_settings() { to this: function mynewmodule_admin_settings($form) { adding the $form variable and them replace all of the theme_get_setting() functions with variable_get(). Is this best practice? These aren't really theme settings... that's just what I was using in the past in the theme-settings.php file which I don't want to do anymore. Thanks. – cybercampbell Sep 25 '12 at 11:13
  • If they are not theme settings, then you should use variable_get()/variable_set(). Also, a form builder function receives a $form argument, which was not passed to the function in Drupal 6. – kiamlaluno Sep 25 '12 at 11:16
  • I see that you have already solved the problem.. Meta: write your .install file to initiate/clean up variables on install/uninstall events. Also, note that storing large data in this way is not memory-friendly (that said, don't store large paragraphs or something like this. These variables are loaded on every page load no matter you called the specific variable or not) – AyeshK Sep 25 '12 at 11:58
2

I think you should add the submit handler function for the mynewmodule_admin_settings() function and there override the theme settings with the values posted in the form.

Btw - it's not the best practice to control theme settings from a module. Do you have any specific reasons for moving this functionality to the module instead of leaving it in the theme?

  • I guess these aren't theme settings but the way I was adding variables in the past was via the theme settings function in the theme-settings.php file. I'n not trying to move away from that. would it be better if I used: variable_get() – cybercampbell Sep 25 '12 at 11:09
  • Yep - for the default_value use variable_get('your_field_id', 'default value') and it should work fine. – Aram Boyajyan Sep 25 '12 at 11:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.