I'm setting up the quiz module on a multilingual site. I've set up the quiz_name variable to be multilingual. However, there is an issue in quiz_admin_settings():

  $form['quiz_look_feel']['quiz_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Display name'),
    '#default_value' => QUIZ_NAME,
    '#description' => t('Change the name of the quiz type. Do you call it <em>test</em> or <em>assessment</em> instead? Change the display name of the module to something else. Currently, it is called @quiz. By default, it is called <em>Quiz</em>.',
      array('@quiz' => QUIZ_NAME)),
    '#required' => TRUE,
  );

The default value is set using the QUIZ_NAME constant. Looking at the QUIZ_NAME constant, it is set here:

define('QUIZ_NAME', _quiz_get_quiz_name());

With _quiz_get_quiz_name() being as follows:

function _quiz_get_quiz_name() {
  // @todo: remove all the quiz_name stuff? Isn't there better ways to do this?
  return variable_get('quiz_name', 'Quiz');
}

This looks like it should be ok, and it is if you are on a unilingual site. But because you are setting the constant in the open in the .module file, it is executed as soon as the .module file is aggregated, which is before any of the code for the i18n module has been executed. This means that the variable cannot be overwritten with a multilingual variable.

The solution for this is to remove all instances of the constant QUIZ_NAME and replace them with variable_get('quiz_name', 'Quiz').

It says in the docs that the reason for setting the constant was so that variable_get() doesn't have to be called in every function, but its ok to call it in every function, as variables are cached so it does not add any noticeable performance hit.

I'll attach a patch to the next post (I need an issue queue number)

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Jaypan’s picture

Status: Active » Needs review
FileSize
31.24 KB

Attaching patch

Jaypan’s picture

I just realized there was more to this as well. In quiz_menu(), the menu title was being set as follows:

  $items['admin/quiz'] = array(
    'title' => '@quiz',
    'title arguments' => array('@quiz' => QUIZ_NAME),

The problem here is that QUIZ_NAME was being set by a call to variable_get(). And since hook_menu() is cached, the title is then set to be whatever QUIZ_NAME was when the menu cache was last set. Even though it looks like the menu name should be translatable, it isn't, for the reasons I laid out in my last post.

The solution here is to make the menu title dynamic, with a custom callback. So I've changed the above to this:

  $items['admin/quiz'] = array(
    'title callback' => 'quiz_menu_title_callback',
    'title arguments' => array('quiz_admin_page'),

Then I created the callback function quiz_menu_title_callback, which looks like this:

function quiz_menu_title_callback($op) {
  $quiz_name = variable_get('quiz_name', 'Quiz');
  switch($op) {
    case 'quiz_admin_page':
      $title = $quiz_name;
      break;

    case 'quiz_settings_page':
      $title = t('@quiz settings', array('@quiz' => $quiz_name));
      break;

    case 'quiz_config_page':
      $title = t('@quiz configuration', array('@quiz' => $quiz_name));
      break;

    case 'quiz_form_config_page':
      $title = t('@quiz form configuration', array('@quiz' => $quiz_name));
      break;

    case 'quiz_reports_page':
      $title = t('@quiz reports and scoring', array('@quiz' => $quiz_name));
      break;

    case 'quiz_results_page':
      $title = t('@quiz results', array('@quiz' => $quiz_name));
      break;
  }

  return $title;
}

You'll notice the switch function - there is one element for each menu item that had the quiz name embedded into it.

I'm attaching an updated patch that contains all the code from the last patch, as well as this patch. I misnamed the last patch (I thought the post number would be 2, but it was 1), so this patch is named quiz-replace_constant_QUIZ_NAME_with_call_to_variable_get-2190157-2b.patch

Sivaji_Ganesh_Jojodae’s picture

Sounds like a valid issue but I would suggest to use helper function perhaps _quiz_get_quiz_name() instead of variable_get(). This is to be able to change easily later when needed.

Lately we are doing quiz multi-lingual site, if we experience this issue, I will revisit it.

Jaypan’s picture

I'll do it if you are actually going to use the patch, but I don't want to waste my time if you aren't. So please let me know which.

yingtho’s picture

The menu title is per drupal default always multilingual, so you wouldn't need to call a funtion to translation the title name. You can translate the title name in drupal normal translate interface. See https://api.drupal.org/api/drupal/modules%21system%21system.api.php/func... under "Return value" and key '"title": Required. The untranslated title of the menu item.'. So the best option is to do this:

<?php
  $items['admin/quiz'] = array(
    'title' => variable_get('quiz_name', 'Quiz'),
?>
yingtho’s picture

na

djdevin’s picture

Component: Code - other » Code - Quiz core
Status: Needs review » Closed (outdated)