Drupal TVI + i18n

Есть под drupal такой крутой модуль — TVI. Он позволяет для каждого словаря таксономии выбрать вьюху для отображения, ну и показывает стандартную страницу термина в случае если вьюха не выбрана. Отличный модуль если есть больше одного словаря, но есть проблема, он не работает с i18n_taxonomy и если вьюха не выбрана то показывает страницу оригинального термина, а не его перевод.

На самом деле разработчиков плагина скорее всего просто заломало проверять совместимость с самыми популярными и важными модулями, такое тоже бывает. Но исправить на самом деле не сложно.

Так как я не очень люблю делать к модулям патчи, чтобы потом следить за обновлениями и не забывать их применять, я лучше через хуки добьюсь нужного результата, на то они (хуки) и созданы.
Модуль tvi довольно просто, он использует hook_menu_alter чтобы подменить стандартный путь taxonomy/term/%taxonomy_term и вызывает свою функцию — tvi_render_view, вместо стандартной, подтягивает в ней настройки для словаря, и, если указана вьюха то показывает ее, иначе вызывает стандартную функцию из модуля taxonomy. Это не совсем верное решение со стороны разработчика, но об этом после, сейчас покажу фикс в виде отдельного модуля.

В модуле также переопределю путь taxonomy/term/%taxonomy_term и укажу свою функцию которая будет немного повторять оригинальную. Модуль назвал tvi_i18n.

tvi_i18n/tvi_i18n.info

name = TVI: Taxonomy View Integrator (i18n Taxonomy integration)
description = Show i18n taxonomy term page if no views configured
core = 7.x

dependencies[] = views
dependencies[] = taxonomy
dependencies[] = i18n
dependencies[] = i18n_taxonomy

tvi_i18n/tvi_i18n.module


/**
 * @file
 * Module tvi_i18n module file.
 */

/**
 * Implements hook_menu_alter().
 */
function tvi_i18n_menu_alter(&$items) {
  $items['taxonomy/term/%taxonomy_term']['page callback'] = 'tvi_i18n_render_view';
}

/**
 * Replacement tvi taxonomy page callback.
 */
function tvi_i18n_render_view($tid = '', $depth = 0, $op = 'page') {
  if (is_object($tid)) {
    $tid = $tid->tid;
  }

  list($view, $display, $term) = tvi_get_view_info($tid);
  if (is_object($view) && $display) {
    return tvi_render_view($tid, $depth, $op);
  }

  // Is exists i18n taxonomy - show translated term page.
  if (module_exists('i18n_taxonomy')) {
    module_load_include('inc', 'i18n_taxonomy', 'i18n_taxonomy.pages');
    return i18n_taxonomy_term_page($term);
  }

  // Taxonomy is last resort - used if no standard views are found.
  module_load_include('inc', 'taxonomy', 'taxonomy.pages');
  return taxonomy_term_page($term);
}

Если сравнить функции tvi_i18n_render_view и tvi_render_view то они обе проверяют есть ли вьюха для этого термина, и, в моем случае, если есть то вызываю оригинальную функцию, а если вьюхи нету то перед тем как вызвать функцию из модуля taxonomy проверяю включен ли модуль i18n_taxonomy, если включен то вызываю функцию которая вернет перевод термина.

И так как модуль tvi переопределяет пути модуля view, а мой модуль должен переопределить пути tvi то нужно не забыть о весе модуля, чтобы hook_menu_alter работал в правильно порядке.

tvi_i18n/tvi_i18n.install


/**
 * @file
 * Install, update, and uninstall functions for the tvi_i18n module.
 */

/**
 * Implements hook_install().
 */
function tvi_i18n_install() {
  // Ensure weights are ok.
  $tvi_info = db_select('system', 's')
    ->fields('s', array('weight'))
    ->condition('s.name', 'tvi')
    ->range(NULL, 1)
    ->execute()
    ->fetchObject();

  db_update('system')
    ->fields(array('weight' => $tvi_info->weight + 1))
    ->condition('name', 'tvi_i18n')
    ->execute();
}

Drupal TVI + i18n: 4 комментария

  1. drupby

    А почему бы вместо запросов в .install просто не имплементировать hook_module_implements_alter()?

    1. zviryatko Автор записи

      Хороший вопрос, в принципе все в друпале можно сделать разными путями, вес модуля это более явный для других разработчиков вариант — делаешь ты такой hook_menu_alter() и видишь что вместо твоего результат выводится другой, первым думаешь какой логический порядок их запуска, к тому же изменение веса только при установке задается.

      hook_module_implements_alter() использую только в крайнем случае когда более простыми путями не подобраться. К тому же мне нужно в хуке меню только одну строчку изменить, а все остальные чтобы были от предыдущего модуля.

  2. kalabro

    TVI (https://www.drupal.org/project/tvi) официально рекомендует использовать https://www.drupal.org/project/taxonomy_display вместо себя для семёрки. Потому что никто не любит делать к модулям патчи, и мейнтейнер остаётся с 10К юзеров и их багами один на один.

    Патч требует времени, но А) позволяет реально продлить жизнь модулю на орге Б) себя-красавца показать на орге 🙂

    Но патчить уже тогда лучше taxonomy_display (если требуется), а не tvi 🙂

    1. zviryatko Автор записи

      почему никто не любит делать патчи? Я люблю. Только те исправления которые мне нужны уже 100% кто-то запатчил ), а еще тот спорный момент когда твой патч не то чтобы исправление, а скорее дополнительный функционал, и такой сидишь думаешь стоит ли модуль перегружать дополнительным функционалом или нет… Ок, уговорила, завтра же напишу патч, кому нужно тот пусть юзает. А за taxonomy_display спасибо, как-то не читал информацию на странице tvi.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *