We use View Reference to provide user modifiable views to various media sites (flicker, youtube, etc.) The client is requesting that I change the text on the Views Reference widget from "Arguments" to more descriptive "Enter Embed Code."

OK - I know how to do this by hacking the View Reference module, but that is bad form and I want to do it the "Drupal Way." But since this text is provided as a process inside of widget it is more difficult than simply overriding the $form array.

From reading (http://drupal.org/node/341628 , http://drupal.org/node/223430), it seems that I
- Need to create a custom theme
- Override the process function within template.php

So far I've been unsuccessful in actually getting it to work though (the site is Drupal 7). The module doesn't seem to provide themeable output for this widget. Can anyone point me to a sample or psudo code on how one would do this in D7?

Thanks in advance,

CommentFileSizeAuthor
#2 viewsreference.png91.99 KBcluther

Comments

danielb’s picture

I've been thinking 'arguments' might be the wrong word to use anyway, I think Views calls it "contextual filter" or something now? I could be wrong.

Since the output is done through the Forms API, it is very easy to change with hook_form_alter().
http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...
or
http://api.drupal.org/api/drupal/modules--system--system.api.php/functio...

The specifics of what the form id is, and where to change the $form would depend on your setup. You can find the form id by implementing hook_form_alter() and making it drupal_set_message($form_id) so you can see what form id's are on the page.
The only catch is if it doesn't work, you might have to attach some sort of callback function through a property like #pre_render to change it later - I know Drupal 6 CCK needed some kind of workaround like that, but you might have to do some research on that.

Theming will not be an appropriate solution.

You can also use the 'string overrides' module to simply to a replace on that word, except it will replace it everywhere it says 'arguments'.

cluther’s picture

StatusFileSize
new91.99 KB

Well actually, not quite. While some of the widget output is modifiable via the $form array, the text that I am looking to change is created by a process unavailable to $form array (see illustration). This was the crux of the question.

So, somewhat answering my own question.....

Hacking the code to change the text would be easy, but bad form as it modifies the Contrib module. So to help those who follow here is my discovery process (information taken from Drupal.org and the Drupal 6 Themes book).

The process which creates the widget text is located at ln 716 in viewreference.module:

 ...
function viewreference_select_process($element, $form_state, $form) {
  $field_name = $element['#parents'][0];
  $language = $element['#parents'][1];
  $field = $form_state['field'][$field_name];
  $instance = $field[$language]['instance'];
  $bundle = $instance['bundle'];
  $settings = $field[$language]['field']['settings'];

  $options = viewreference_get_views($settings['append_id'], $settings['referenceable_views']);
  if (!$instance['required']) {
    $options = array(0 => '<'. t('none') .'>') + $options;
  }

  $element[$element['#columns'][0]] = array(
    '#type' => 'select',
    '#multiple' => 0,
    '#options' => $options,
    '#default_value' => isset($element['#value'][$element['#columns'][0]]) ? $element['#value'][$element['#columns'][0]] : '',
    '#field_name' => $field_name,
    '#delta' => $element['#delta'],
    '#columns' => $element['#columns'],
    '#title' => $instance['label'],
    '#required' => $instance['required'],
    '#description' => isset($element['#description']) ? $element['#description'] : NULL,
  );

  if ($settings['arguments']['dsv_arguments'] || $settings['arguments']['php_arguments']) {
    $element[$element['#columns'][1]] = array(
      '#type' => ($settings['arguments']['rows'] == 1 ? 'textfield' : 'textarea'),
      '#default_value' => isset($element['#value'][$element['#columns'][1]]) ? $element['#value'][$element['#columns'][1]] : '',
      '#title' => $instance['label'] . ' ' . t('arguments'),
      '#rows' => $settings['arguments']['rows'],
      '#language' => $language,
      '#delta' => $element['#delta'],
      '#columns' => $element['#columns'],
      '#required' => $element['#required'],
      '#description' => isset($element['#description']) ? $element['#description'] : NULL,
    );
  }

The Drupal way would be an override, and various approached to overriding styling are:

  • Substituting templates
  • Overriding templates
  • Overriding themable functions with dedicated template files
  • Placing function overrides in the template.php file

Since there is not a themeable function for this widget I'm left to creating a function override in the template.php file. The steps are:

  1. Create a new file named template.php inside your theme directory.
  2. Find the functions you wish to customize.
  3. Copy the original functions and paste them into the template.php file in their entirety.
  4. Rename the function according to naming convention.
  5. Make your changes to the renamed function in the template.php file and save the file.
  6. Clear the Theme Registry

At run time, Drupal is designed to look for overrides to themable functions before applying the default functions. The system does this by looking for files in the following order (assuming the PHPTemplate engine):

  • themename_functionname (e.g., garland_breadcrumb)
  • themeengine_functionname (e.g., phptemplate_breadcrumb)
  • theme_functionname (e.g., theme_breadcrumb)

But, when I create and modify the function mytheme_select_process($element, &$form_state, $form) nothing happens.

danielb’s picture

Like I said, theming is not an appropriate solution, and it is not normal to provide a theme hook or template for a widget. I'm not saying it can't work, but your aim is not to change the style of output, rather the data that is fed into the theme functions.
You have to use the forms API like so:

<?php

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * This affects only the 'page' content type node forms.
 */
function YOURMODULE_form_page_node_form_alter(&$form, &$form_state, $form_id) {
  $form['#after_build'][] = 'change_viewreference_arguments_label';
}

/**
 * After build callback for changing viewreference arguments label.
 */
function change_viewreference_arguments_label($form, &$form_state) {
  // Your field key.
  $field_key = 'field_viewreference';

  // Settings for the field can be found by digging around in 
  // $form_state['field'][$field_key]

  // Change the arguments label for the first delta (0) in the undefined language.
  // (You can come up with a more suitable logic to this part)
  $form[$field_key][LANGUAGE_NONE][0]['arguments']['#title'] = t("Your mum");

  return $form;
}

?>

To affect all viewreferences you can loop through $form_state['field'] and find the keys of all the viewreference fields, which can be identified by the 'type' or 'module' keys.

danielb’s picture

You know I might just make this configurable.

danielb’s picture

Status: Active » Fixed

done, will appear in next dev version (check the date)

cluther’s picture

Thank you! First for taking the time to further explain your answer (and where I was getting off-track) AND for implementing a solution in the module as a configurable option.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.