Any advice? Things aren't quite working here, and I'm trying to see if that has something to do with it. I can't find any documentation of what "context" is about. Thanks!

Comments

RobLoach’s picture

Status: Active » Fixed

Context isn't needed in most cases. In some parts of Drupal, when they use t(), they pass in context to have different translations depending on the situation. Most of the time, you won't need it. So just leave it blank :-) .

But if it's not working, have a look at the code that's calling t(), and see if there's a 'context' option being passed.

jim_at_miramontes’s picture

Aha. Got it; thanks!

chiddicks’s picture

At first I thought this was a reference to a context, as provided by the Context module. I was excited, since sometimes you don't want to override a string site-wide. Obviously, this is not what it's for, but it's a tantalizing possibility. Anyone have any ideas how selective overrides might be implemented? Integration with Context is actually a pretty good option.

Status: Fixed » Closed (fixed)

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

RobLoach’s picture

Title: What goes in the context field? » Context Module Integration
Version: 7.x-1.0 » 7.x-1.x-dev
Category: support » feature
Status: Closed (fixed) » Active
Issue tags: +context module, +T, +string overrides

Context module integration might actually be a really good idea, chiddicks. If we somehow create grouping of String Overrides, and then allow the Context module to apply those string overrides based on certain criteria, we'd end up with a pretty powerful system that would allow contextual overrides. Great idea.

Mamoun’s picture

Subscribe

btopro’s picture

sub

chiddicks’s picture

The simplest way I can think of is to create a context "reaction" for each string override on the site - since the String Overrides configuration page already has an 'enabled' checkbox, it can function as a 'site-wide enable', as before. A string override could be enabled per-page by adding it as a reaction in a context or contexts, and unchecking the site-wide checkbox. I'm not sure at present the mechanism String Overrides uses to insert its strings, but hopefully there's a simple way to do it conditionally, at page-load.

http://drupalcode.org/project/context.git/blob/refs/heads/7.x-3.x:/API.txt

I'll look at this later this week if I have a chance, if no one else has posted progress.

chiddicks’s picture

I've taken a little time to look at String Overrides works. Rob, please correct me where I am wrong. String Overrides relies on setting locale_custom_strings_[lang] variables, which the t() function conveniently checks before rendering a string. Elegant. As far as I can see, to get a custom string to conditionally show up, we either need to manipulate that locale_custom_strings_[lang] before the page load, and somehow reset it to default afterwards. Or, perhaps taking advantage of the t() function's "caching", wherein it uses a static variable to store the value of locale_custom_strings_[lang] for the duration of the page-load. The question is, can a static variable be manipulated in that way, outside of function scope?

RobLoach’s picture

Correctamongo! In the Context Reaction, it would look something like this...

class context_reaction_stringoverrides extends context_reaction {
  function execute(&$vars) {
    global $conf;
    $group = $vars['group'];
    $lang = $vars['lang'];
    $conf["locale_custom_strings_$lang"] = variable_get("locale_custom_strings_$lang$group", array());
  }
}

The $conf variable is the static variables table, which would allow use to manipulate the overrides without having them permanently override. So what we'd need is the ability to make groups of String Overrides. The setting for the context reaction settings would take the language, and the group to apply when the context's conditions are met. It would then load in the group of string overrides into the static variable, and boom, contextual string overrides.

RobLoach’s picture

Hmmm, maybe use the "Context" column of the String Overrides table? Hmmmmmmmmmmmmmmmmmmmmmmm....

RobLoach’s picture

Not sure why the reaction isn't being executed...

In stringoverrides/stringoverrides.module:

/**
 * Implements hook_context_plugins().
 */
function stringoverrides_context_plugins() {
  $plugins = array();
  $plugins['stringoverrides_reaction'] = array(
    'handler' => array(
      'path' => drupal_get_path('module', 'stringoverrides') .'/plugins',
      'file' => 'context_reaction_stringoverrides.inc',
      'class' => 'context_reaction_stringoverrides',
      'parent' => 'context_reaction',
    ),
  );
  return $plugins;
}

/**
 * Implements hook_context_registry().
 */
function stringoverrides_context_registry() {
  return array(
    'reactions' => array(
      'stringoverrides' => array(
        'title' => t('String Overrides'),
        'plugin' => 'stringoverrides_reaction',
        'description' => t('Add the given String Override context.'),
      ),
    ),
  );
}

In stringoverrides/plugins/context_reaction_stringoverrides.inc:

<?php

/**
 * Expose String Overrides as context reactions.
 */
class context_reaction_stringoverrides extends context_reaction {
  /**
   * Allow admins to provide a String Overrides context to apply.
   */
  function options_form($context) {
    $values = $this->fetch_from_context($context);

    // Get a list of all available String Overrides contexts.
    global $language;
    $overrides = variable_get("locale_custom_strings_{$language->language}", array());
    $contexts = array('<none>' => t('<none>'));
    foreach ($overrides as $name => $overrides) {
      if (!empty($name)) {
        $contexts[$name] = $name;
      }
    }

    // Allow the user to choose a String Overrides context to apply.
    // @TODO: Should this be a textfield instead as some languages
    // might not have the same contexts?
    $form['context'] = array(
      '#title' => t('String Overrides Context'),
      '#description' => t('The String Overrides context apply when the above conditions are met. Additional contexts can be provided in the context column of the <a href="@stringoverrides">String Overrides administration</a>.', array('@stringoverrides' => url('admin/config/regional/stringoverrides'))),
      '#type' => 'select',
      '#options' => $contexts,
      '#default_value' => isset($values['context']) ? $values['context'] : '<none>',
    );
    return $form;
  }

  /**
   * Add the String Overrides context to the current String Overrides.
   */
  function execute(&$vars) {
    // @TODO: Why is this not executing?
    drupal_set_message('Executing the String Overrides Context Reaction.');
    foreach ($this->get_contexts() as $k => $v) {
      // Apply the String Overrides context to the global $conf["locale_custom_strings_{$language->language}"] array.

      /*if (!empty($v->reactions[$this->plugin]['title']) && !isset($vars['section_title'])) {
        $vars['section_title'] = check_plain(t($v->reactions[$this->plugin]['title']));
      }
      if (!empty($v->reactions[$this->plugin]['subtitle']) && !isset($vars['section_subtitle'])) {
        $vars['section_subtitle'] = check_plain(t($v->reactions[$this->plugin]['subtitle']));
      }*/
      debug($v);
    }
  }
}
RobLoach’s picture

Priority: Normal » Major
Status: Active » Needs work

Hmmmm..........

stringoverrides/plugins/context_reaction_stringoverrides.inc


/**
 * Output context debug information.
 */
class context_reaction_stringoverrides extends context_reaction {
  function options_form($context) {
    $values = $this->fetch_from_context($context);

    // Get a list of all available String Overrides contexts.
    global $language;
    $overrides = variable_get('locale_custom_strings_' . $language->language, array());
    $contexts = array('<none>' => t('<none>'));
    foreach ($overrides as $name => $overrides) {
      if (!empty($name)) {
        $contexts[$name] = $name;
      }
    }

    // Allow the user to choose a String Overrides context to apply.
    // @TODO: Should this be a textfield instead as some languages
    // might not have the same contexts?
    $form['context'] = array(
      '#title' => t('String Overrides Context'),
      '#description' => t('The String Overrides context apply when the above conditions are met. Additional contexts can be provided in the context column of the <a href="@stringoverrides">String Overrides administration</a>.', array('@stringoverrides' => url('admin/config/regional/stringoverrides'))),
      '#type' => 'select',
      '#options' => $contexts,
      '#default_value' => isset($values['context']) ? $values['context'] : '<none>',
    );
    return $form;
  }

  /**
   * Output a list of active contexts.
   */
  function execute() {
    $contexts = context_active_contexts();
    foreach ($contexts as $context) {
      // See if the String Overrides reaction is in use.
      if (!empty($context->reactions['stringoverrides'])) {
        // Make sure the String Overrides contextual group was provided.
        $group = $context->reactions['stringoverrides']['context'];
        if (isset($group) && $group != '<none>') {
          // Retrieve the contextual String Overrides from the variables table.
          global $language;
          $overrides = variable_get('locale_custom_strings_' . $language->language, array());
          if (isset($overrides[$group])) {
            // Make sure the global overrides are available.
            if (!isset($overrides[''])) {
              $overrides[''] = array();
            }
            // Merge the contextual String Overrides into the global String Overrides.
            global $conf;
            $conf['locale_custom_strings_' . $language->language][''] = array_merge($overrides[''], $overrides[$group]);
          }
        }
      }
    }
  }
}

End of stringoverrides.module...

/**
 * Implements hook_context_plugins().
 */
function stringoverrides_context_plugins() {
  $plugins['context_reaction_stringoverrides'] = array(
    'handler' => array(
      'path' => drupal_get_path('module', 'stringoverrides') .'/plugins',
      'file' => 'context_reaction_stringoverrides.inc',
      'class' => 'context_reaction_stringoverrides',
      'parent' => 'context_reaction',
    ),
  );
  return $plugins;
}

/**
 * Implements hook_context_registry().
 */
function stringoverrides_context_registry() {
  $registry['reactions']['stringoverrides'] = array(
    'title' => t('String Overrides'),
    'plugin' => 'context_reaction_stringoverrides',
    'description' => t('Provide contextual String Overrides.'),
  );
  return $registry;
}

/**
 * Implements hook_context_page_reaction().
 */
function stringoverrides_context_page_reaction() {
  if ($plugin = context_get_plugin('reaction', 'stringoverrides')) {
    $plugin->execute();
  }
}
RobLoach’s picture

chiddicks’s picture

Nice work! Rob, I was thinking that each String Override could be listed individually as a Context reaction (or perhaps only the ones that have NOT been enabled site-wide), so the user could enable them as required within the native Context admin UI. However, I expect you've considered all the options in the course of writing this script.

Did you intend to file #1135950: Remove static caching in t() in the 8.x issue queue? Either way, I see no reason why it couldn't be added to 7.x too.

RobLoach’s picture

Nice work! Rob, I was thinking that each String Override could be listed individually as a Context reaction (or perhaps only the ones that have NOT been enabled site-wide), so the user could enable them as required within the native Context admin UI. However, I expect you've considered all the options in the course of writing this script.

You wouldn't want to clutter up the Context UI with all your contextual string overrides though. Would be nice to have a different reaction for each context, but if you had like 100 different contextual String Overrides, then it would get pretty gross in the UI.

With this, you add the "String Overrides" reaction to a Context, it then popped up the options form where you choose which String Overrides context group to apply. The thing missing from the code above is...

            // Merge the contextual String Overrides into the global String Overrides.
            global $conf;
            $conf['locale_custom_strings_' . $language->language][''] = array_merge($overrides[''], $overrides[$group]);
            $custom_strings = &drupal_static('t');
            $custom_strings[''] = $conf['locale_custom_strings_' . $language->language][''];

..... Requires #1135950: Remove static caching in t() :-) . If you had another idea for the UI, that would be cool. Just wanted to keep it as simple as possible ;-).

Did you intend to file #1135950: Use drupal_static() in t() in the 8.x issue queue? Either way, I see no reason why it couldn't be added to 7.x too.

Yup! Patches need to go into 8.x before going into Drupal 7.x though. Webchick won't commit them unless they're in 8.x first... Mind reviewing it and RTBCing it? :-)

chiddicks’s picture

Ok, we're making progress. Did some more testing and RTBC'd the latest patch.

RobLoach’s picture

Status: Needs work » Postponed

Just did some testing with #1135950: Remove static caching in t() and it works with the code in #13. Going to mark this as postponed until the patch gets into both Drupal 7.x and 8.x.

akalata’s picture

subscribe :)

Katrina B’s picture

I am interested in being able to set a String Override for certain places (e.g., one particular Webform) and not for others). Looking forward to seeing this feature implemented.

j0e’s picture

+1 for this feature... i'd hope the patch could be backported to Drupal 6 too!

kenheim’s picture

+1 this would be awesome!

TechNikh’s picture

+1

rolandu’s picture

+1

kingswoodute’s picture

+1 yeah this would be fantastic.

GiorgosK’s picture

issue linked from #18 got stuck long time ago
what a pity

junetellain626’s picture

Updates? :)

paulwdru’s picture

Issue summary: View changes

Hi,

Any update ? Working with Context module is a great idea otherwise this module is not so useful coz many use cases of t() don't specify a context.

Thanks