You are here

potx.module in Translation template extractor 5.2

Gettext translation template and translation extractor.

This module helps people extract translatable strings from Drupal source code. The user interface allows translators to choose which part of the current Drupal instance to translate. The module also provides an API for other modules (such as l10n_server) to use.

File

potx.module
View source
<?php

/**
 * @file
 *   Gettext translation template and translation extractor.
 *
 *   This module helps people extract translatable strings from Drupal source
 *   code. The user interface allows translators to choose which part of the
 *   current Drupal instance to translate. The module also provides an API for
 *   other modules (such as l10n_server) to use.
 */

/**
 * Implementation of hook_help().
 */
function potx_help($section) {
  switch ($section) {
    case 'admin/settings/locale/potx':
      return '<p>' . t('This page allows you to generate translation templates for module files. Select the module you wish to generate a template file for. A single Gettext Portable Object (Template) file is generated, so you can easily save it and start translation.') . '</p>';
  }
}

/**
 * Implementation of hook_menu().
 */
function potx_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/locale/potx',
      'title' => t('Extract strings'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'potx_select_form',
      ),
      'access' => user_access('administer locales'),
      'weight' => 20,
      'type' => MENU_LOCAL_TASK,
    );
  }
  return $items;
}

/**
 * Module selection interface.
 */
function potx_select_form() {
  $form = array();
  $modules = _potx_module_list();
  _potx_build_module_form($form, $modules);

  // Generate translation file for a specific language if possible.
  $supported = locale_supported_languages();
  $names = $supported['name'];
  if (count($names) > 1 || !isset($names['en'])) {

    // We have more languages, or the single language we have is not English.
    $options = array(
      'n/a' => t('Language independent template'),
    );
    foreach ($names as $langcode => $name) {

      // Skip English, as we should not have translations for this language.
      if ($langcode == 'en') {
        continue;
      }
      $options[$langcode] = t('Template file for !langname translations', array(
        '!langname' => t($name),
      ));
    }
    $form['langcode'] = array(
      '#type' => 'radios',
      '#title' => t('Template language'),
      '#default_value' => 'n/a',
      '#options' => $options,
      '#description' => t('Export a language independent or language dependent (plural forms, language team name, etc.) template.'),
    );
    $form['translations'] = array(
      '#type' => 'checkbox',
      '#title' => t('Include translations'),
      '#description' => t('Include translations of strings in the file generated. Not applicable for language independent templates.'),
    );
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Extract'),
  );
  return $form;
}

/**
 * Validation handler for potx module selection form.
 */
function potx_select_form_validate($form_id, $form) {
  if (empty($form['module'])) {
    form_set_error('', t('You should select a module to export.'));
  }
}

/**
 * Generate translation template or translation file for the requested module.
 */
function potx_select_form_submit($form_id, &$form) {

  // This could take some time.
  @set_time_limit(0);
  include_once drupal_get_path('module', 'potx') . '/potx.inc';

  // Silence status messages.
  _potx_status(POTX_STATUS_MESSAGE);

  // $form['module'] either contains a specific module file name
  // with path, or a directory name for a module or a module suite.
  // Examples:
  //   modules/watchdog
  //   sites/all/modules/potx
  //   sites/all/modules/i18n/i18n.module
  $pathinfo = pathinfo($form['module']);
  $strip_prefix = 0;

  // A specific module file was requested.
  if ($pathinfo['extension'] == 'module') {
    $filename = basename($pathinfo['basename'], '.module');
    $files = _potx_explore_dir($pathinfo['dirname'] . '/', $filename, POTX_API_5);
    $strip_prefix = 1 + strlen($pathinfo['dirname']);
    $outputname = $filename;
  }
  else {
    $files = _potx_explore_dir($form['module'] . '/', '*', POTX_API_5);
    $strip_prefix = 1 + strlen($form['module']);
    $outputname = $pathinfo['basename'];
  }

  // Decide on template or translation file generation.
  $template_langcode = $translation_langcode = NULL;
  if (isset($form['langcode']) && $form['langcode'] != 'n/a') {
    $template_langcode = $form['langcode'];
    $outputname .= '.' . $template_langcode;
    if (!empty($form['translations'])) {
      $translation_langcode = $template_langcode;
      $outputname .= '.po';
    }
    else {
      $outputname .= '.pot';
    }
  }
  else {
    $outputname .= '.pot';
  }

  // Collect every string in affected files. Installer related strings are discared.
  foreach ($files as $file) {
    _potx_process_file($file, $strip_prefix, '_potx_save_string', '_potx_save_version', POTX_API_5);
  }

  // Need to include full parameter list to get to passing the language codes.
  _potx_build_files(POTX_STRING_RUNTIME, POTX_BUILD_SINGLE, 'general', '_potx_save_string', '_potx_save_version', '_potx_get_header', $template_langcode, $translation_langcode, POTX_API_5);
  _potx_write_files($outputname, 'attachment');
  exit;
}

/**
 * Build a chunk of the module selection form.
 *
 * @param $form
 *   Form to populate with fields.
 * @param $modules
 *   Structured array with modules as returned by _potx_module_list().
 * @param $dirname
 *   Name of directory handled.
 */
function _potx_build_module_form(&$form, &$modules, $dirname = '') {

  // Pop off count of modules in this directory.
  if (isset($modules['.modulecount'])) {
    $modules_in_dir = $modules['.modulecount'];
    unset($modules['.modulecount']);
  }
  ksort($modules);
  $dirkeys = array_keys($modules);

  // A directory with one module.
  if (isset($modules_in_dir) && count($modules) == 1) {
    $module_dir = dirname($modules[$dirkeys[0]]->filename);
    $form[_potx_form_id('dir', $module_dir)] = array(
      '#type' => 'radio',
      '#title' => t('Extract from %module_name module, in directory %dir_name', array(
        '%dir_name' => $module_dir,
        '%module_name' => basename($modules[$dirkeys[0]]->basename, '.module'),
      )),
      '#description' => t('Generates output from all files found in this directory.'),
      '#default_value' => 0,
      '#return_value' => $module_dir,
      // Get all radio buttons into the same group.
      '#parents' => array(
        'module',
      ),
    );
    return;
  }

  // A directory with multiple modules in it.
  if (preg_match('!/modules\\b(/.+)?!', $dirname, $pathmatch)) {
    $subst = array(
      '@dir_name' => substr($dirname, 1),
    );
    if (isset($pathmatch[1])) {
      $form[_potx_form_id('dir', $dirname)] = array(
        '#type' => 'radio',
        '#title' => t('Extract from all modules in directory "@dir_name"', $subst),
        '#description' => t('To extract from a single module in this directory, choose the module entry in the fieldset below.'),
        '#default_value' => 0,
        '#return_value' => substr($dirname, 1),
        // Get all radio buttons into the same group.
        '#parents' => array(
          'module',
        ),
      );
    }
    $element = array(
      '#type' => 'fieldset',
      '#title' => t('Modules in "@dir_name"', $subst),
      '#collapsible' => true,
      '#collapsed' => true,
    );
    $form[_potx_form_id('fs', $dirname)] =& $element;
  }
  else {
    $element =& $form;
  }
  foreach ($dirkeys as $entry) {

    // A module in this directory with multiple modules.
    if ($entry[0] == '#') {
      $subst = array(
        '%module_dir' => dirname($modules[$entry]->filename),
        '%module_name' => basename($modules[$entry]->basename, '.module'),
        '%module_pattern' => basename($modules[$entry]->basename, '.module') . '.*',
      );
      $element[_potx_form_id('mod', $modules[$entry]->basename)] = array(
        '#type' => 'radio',
        '#title' => t('Extract from module %module_name', $subst),
        '#description' => t('Extract from files named %module_pattern, in directory %module_dir.', $subst),
        '#default_value' => 0,
        '#return_value' => $modules[$entry]->filename,
        // Get all radio buttons into the same group.
        '#parents' => array(
          'module',
        ),
      );
    }
    else {
      _potx_build_module_form($element, $modules[$entry], "{$dirname}/{$entry}");
    }
  }
  return count($modules);
}

/**
 * Generate a sane form element ID for the current radio button.
 *
 * @param $type
 *   Type of ID generated: 'fs' for fieldset, 'dir' for directory, 'mod' for module
 * @param $path
 *   Path of file we generate an ID for.
 * @return
 *   The generated ID.
 */
function _potx_form_id($type, $path) {
  return 'potx-' . $type . '-' . preg_replace('/[^a-zA-Z0-9]+/', '-', $path);
}

/**
 * Generate a hierarchical structured list of modules.
 */
function _potx_module_list() {

  // Get current list of enabled modules and their file names.
  $files = drupal_system_listing('\\.module$', 'modules', 'name', 0);
  system_get_files_database($files, 'module');
  ksort($files);
  $modules = array();
  foreach ($files as $file) {

    // Skip disabled modules
    if ($file->status != 1) {
      continue;
    }

    // Build directory tree structure.
    $path_parts = explode('/', dirname($file->filename));
    $dir =& $modules;
    foreach ($path_parts as $dirname) {
      if (!isset($dir[$dirname])) {
        $dir[$dirname] = array();
      }
      $dir =& $dir[$dirname];
    }

    // Information about modules in this directory.
    $dir['#' . $file->basename] = $file;
    $dir['.modulecount'] = isset($dir['.modulecount']) ? $dir['.modulecount'] + 1 : 1;
  }
  return $modules;
}

Functions

Namesort descending Description
potx_help Implementation of hook_help().
potx_menu Implementation of hook_menu().
potx_select_form Module selection interface.
potx_select_form_submit Generate translation template or translation file for the requested module.
potx_select_form_validate Validation handler for potx module selection form.
_potx_build_module_form Build a chunk of the module selection form.
_potx_form_id Generate a sane form element ID for the current radio button.
_potx_module_list Generate a hierarchical structured list of modules.