function ds_extras_field_template_settings_form(array &$form, array &$form_state, array $context) {
  $functions = module_invoke_all('ds_field_theme_functions_info');
...

First line in the function allows us to add templates, but we cannot provide our own settings for the template (at least from what I can tell). I am not sure where best to place the hook, either before or after DS's settings are setup, but can we add in something like:

$form = module_invoke_all('ds_field_theme_functions_settings', $form, $form_state, $context);

We would then be able to inject our own settings into the form. Thanks

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

nicholas.alipaz’s picture

Attached is a patch and below what implementation in my custom module looks like:

// Constants
define('MYMODULE_PATH', drupal_get_path('module', 'mymodule'));

/**
 * Implementation of hook_ds_field_theme_functions_info().
 */
function mymodule_ds_field_theme_functions_info() {
  return array('theme_ds_field_mymodule' => t('Mymodule Field'));
}

/**
 * Theme callback for defined template in hook_ds_field_theme_functions_info().
 */
function theme_ds_field_mymodule($variables) {
  $output = '';
  $config = $variables['ds-config'];

  // Render the label, if it's not hidden.
  if (!$variables['label_hidden']) {
    $output .= '<div class="field-label"' . $variables['title_attributes'] . '>' . $variables['label'];
    if (isset($config['gf-lb-col'])) {
      $output .= ':&nbsp;';
    }
    $output .= '</div>';
  }

  // Render the items.
  $output .= '<div class="field-items"' . $variables['content_attributes'] . '>';
  foreach ($variables['items'] as $delta => $item) {
    $classes = 'field-item ' . ($delta % 2 ? 'odd' : 'even');
    $output .= '<div class="' . $classes . '"' . $variables['item_attributes'][$delta] . '>' . drupal_render($item) . '</div>';
  }
  $output .= '</div>';

  // Render the top-level DIV.
  $output = '<div class="' . $variables['classes'] . '"' . $variables['attributes'] . '>' . $output . '</div>';

  return $output;
}

/**
 * Implementation of hook_ds_field_theme_functions_settings().
 */
function mymodule_ds_field_theme_functions_settings($form, $field_settings) {
  $form['ft']['gf-lb-col'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show colon'),
    '#default_value' => isset($field_settings['gf-lb-col']) ? $field_settings['gf-lb-col'] : FALSE,
    '#attributes' => array(
      'class' => array('gf-colon-checkbox'),
    ),
  );
  return $form;
}

/**
 * Alter Manage display screen to add some JS.
 */
function mymodule_form_field_ui_display_overview_form_alter(&$form, &$form_state) {
  // Attach js.
  $form['#attached']['js'][] = MYMODULE_PATH . '/mymodule.admin.js';
}

And the corresponding mymodule.admin.js file:

(function ($) {
  Drupal.behaviors.mymoduleSettingsToggle = {
    attach: function (context) {
      // Bind on click.
      $('.field-formatter-settings-edit-form', context).once('gf-ds-ft', function() {
        var fieldTemplate = $(this);

        // Bind on field template select button.
        fieldTemplate.find('.ds-extras-field-template').change(function() {
          mymodule_show_settings(fieldTemplate);
        });

        mymodule_show_settings(fieldTemplate);

      });

      // Show / hide settings on field template form.
      function mymodule_show_settings(element, open) {
        field = element;
        ft = $('.ds-extras-field-template', field).val();
        // GF Colon.
        if (ft != 'theme_ds_field_mymodule') {
          $('.gf-colon-checkbox', field).parent().hide();
        }
        else if ($('.lb .form-item:nth-child(1)', field).is(':visible')) {
          $('.gf-colon-checkbox', field).parent().show();
          $('.colon-checkbox', field).parent().hide(); // Hide the default label setting.
        }
      }
    }
  };
})(jQuery);

nicholas.alipaz’s picture

Status: Active » Needs review

BTW, the implementation in my module simply makes the colon default to off and you must explicitely turn it on.

swentel’s picture

Status: Needs review » Fixed

Thanks, committed and pushed!

swentel’s picture

Status: Fixed » Needs work

Had to rework this one, forms where completelely broken.

nicholas.alipaz’s picture

Hmmm, I hadn't experience any issue on my sites. What are you seeing that is broken?

swentel’s picture

There form is just completely empty, will debug this weekend on it.

nicholas.alipaz’s picture

perhaps if no modules are invoking then it would be empty? I can try that with a default install. We likely need to check if any modules invoke first.

swentel’s picture

Maybe it's a better a idea to use an alter hook instead of module_invoke_all as well ? That way, the receiving function needs to take the form parameter by ref and we're always safe as well.

Nicolas Bouteille’s picture

Hi,

Is there any news on this ?

I created a custom field template using hook_ds_field_theme_functions_info() but I can't figure out how to add custom settings for this template the same way the 'Expert' template has.

I am going to try the solution above but the post is quite old, so if someone has more updated info I would appreciate it!

Thanks !

Nicolas Bouteille’s picture

How would you add an alter hook for example ?

Nicolas Bouteille’s picture

How about this ? Could it be pushed in next version ? Sorry I don't know how to create a patch yet.

  // Let other modules make modifications to the settings form as needed.
  $altered_form = module_invoke_all('ds_field_theme_functions_settings', $form, $field_settings);
  //$altered_form is empty if no module invoke hook
  if( !empty($altered_form)) { 
    $form = $altered_form;
  }
aspilicious’s picture

To be honest, the field template stuff in D7 is not really extendable for various reasons.
For the D8 versions I'm rewriting this.

So I'm not sure I can do anything for you.
I can add an alter but It would not behave correctly in every situation.
I prefer no solution than a half baked one.

Unless you can proove I'm wrong :) (I hope I'm wrong)

Nicolas Bouteille’s picture

Ok so far the code above is working for me except one major problem : the value of the setting is not saved into the database. When I click Update on the field settings form it gets saved as long as I stay on the Manage Display page. But if I click Save at the end of the manage display page the value is not saved into the database. Is there any _submit function I should alter too in order to save my values ?

aspilicious’s picture

Thats the whole problem. :)
Thats why it isn't working properly and why I'm rewriting it for D8.

Nicolas Bouteille’s picture

Alright I finally figured it out!

For the data to be saved, one must implement hook_ds_field_settings_alter()
To understand what must be done, one can have a look at the implementation inside ds_extra.module arround line 800

function ds_extras_ds_field_settings_alter(&$field_settings, $form, &$form_state) {

in my case I wrote the following :

function MYMODULE_ds_field_settings_alter(&$field_settings, $form, $form_state) {
  
  $fields = $form_state['values']['fields'];
  
  foreach ($fields as $key => $field) {

    $values = isset($form_state['formatter_settings'][$key]['ft']) ? $form_state['formatter_settings'][$key]['ft'] : array();
    
    if(isset($values['MY_CUSTOM_SETTING_FIELD']) && $values['MY_CUSTOM_SETTING_FIELD'] != MY_CONSTANT_DEFAULT_VALUE) {
      $field_settings[$key]['formatter_settings']['ft']['MY_CUSTOM_SETTING_FIELD'] = $values['MY_CUSTOM_SETTING_FIELD'];
    }
  }
}

Be careful that in ds_extra implementation, the $field_settings[$key]['formatter_settings']['ft'] array gets re-initialized!

$field_settings[$key]['formatter_settings']['ft'] = array();

So one must make sure its custom module is called after DS Extra. From what I read, hook_alter implementations are called in order of the module's weight. Because DS Extra's weight is 2, I had to set the weight of my module to be 3 at least.

Ok so in the end the only core modification I had to do is the one mentioned above so if you could add it to the next 7.x version that would be awesome :) Here it is again...

// Let other modules make modifications to the settings form as needed.
  $altered_form = module_invoke_all('ds_field_theme_functions_settings', $form, $field_settings);
  //$altered_form is empty if no module invoke hook
  if( !empty($altered_form)) { 
    $form = $altered_form;
  }
aspilicious’s picture

I'll look at it somewhere this week.

Nicolas Bouteille’s picture

great thx!

aspilicious’s picture

Issue summary: View changes
Status: Needs work » Needs review
FileSize
1.3 KB

Can you try the attached patch?

Nicolas Bouteille’s picture

Big rush last week before leaving in holidays right now. Will not be able to test before feb. 3rd but will do! Thx a lot.

aspilicious’s picture

Status: Needs review » Closed (fixed)

This is already in ds for months :D