Drupal module_invoke () и i18n - PullRequest
       1

Drupal module_invoke () и i18n

3 голосов
/ 03 ноября 2010

Мне поручено установить нашу текущую настройку CMS в Drupal. Проблема, с которой я сталкиваюсь, заключается в использовании module_invoke () для размещения блоков внутри узлов.

Мне удалось перевести блоки перевода строк, и это работает, когда блок помещается в область (содержимое блока успешно переведено) с помощью пользовательского интерфейса.

Однако, когда блок внедряется в узел, например:

$block = module_invoke('block', 'block', 'view', 22); print $block['content'];

Это не переводится, или, что еще хуже, не показывается вообще.

Я также пробовал этот вариант, используя t (). e.g.:

$block = module_invoke('block', 'block', 'view', 22); print t($block['content']);

безрезультатно.

Вообще говоря, у меня есть небольшие проблемы с блоками для i18n. У кого-нибудь есть рекомендуемый подход для работы с блоками в друпале в отношении их перевода? Я бы предпочел не создавать разные блоки для каждого языка.

Ответы [ 4 ]

3 голосов
/ 27 февраля 2014

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

  $block = module_invoke('block', 'block_view', 'block_id');
  print render($block['content']);

чтобы вставить блок в мои узлы. Однако, просматривая module_invoke в справочнике Drupal, я нашел комментарий под названием «Чтобы лучше отображать блоки в Drupal 7 для использования Block API», с таким кодом:

  function block_render($module, $block_id) {
    $block = block_load($module, $block_id);
    $block_content = _block_render_blocks(array($block));
    $build = _block_get_renderable_array($block_content);
    $block_rendered = drupal_render($build);
    return $block_rendered;
  }

Я просто отключил его для непосредственного использования, вот так:

  $block = block_load('block', 'block_id');
  $block_content = _block_render_blocks(array($block));
  $build = _block_get_renderable_array($block_content);
  print render($build);

И для меня это работает как шарм. Однако учтите, что этот метод также печатает заголовок блока, поэтому, возможно, вы захотите установить для него значение «none» на языке оригинала.

3 голосов
/ 11 ноября 2010

Итак ... После того, как покопался в недрах Друпала - и много потянул за волосы ... Я нашел почти приличное решение.

По сути, с помощью этой функции я могу извлечь переведенную версию блока:

function render_i18n_block($block_id, $region = "hidden"){

    if ($list = block_list($region)) {
        foreach ($list as $key => $block) {
          // $key == <i>module</i>_<i>delta</i>
          $key_str = "block_".$block_id;
          if ($key_str == $key){
          return theme('block', $block);
          }
        }
    }
}

Затем в моем узле я просто вызываю:

<?php echo render_i18n_block(<block_id>,<region>); ?>

Могут быть некоторые проблемы, когда ваши блоки могут не отображаться в регионе (и, следовательно, вы не можете передать регион в block_list). Для этого случая я просто создал область с именем «скрытый», которая не отображается нигде в моем шаблоне, но может использоваться для вызова block_list.

Наконец (и это та часть, для которой мне все еще нужно найти хорошее решение), я обнаружил, что block_list () в: includes / blocks / block.inc имеет некоторую проблему.

Похоже, что $ theme_key не установлен надежно, если не вызывается block_list () из функции theme () (в include / themes.inc). Это заставляет SQL возвращать пустой набор результатов. SQL выглядит так:

$result = db_query(db_rewrite_sql("SELECT DISTINCT b.* FROM {blocks} b LEFT JOIN {blocks_roles} r ON b.module = r.module AND b.delta = r.delta WHERE b.theme = '%s' AND b.status = 1 AND (r.rid IN (". db_placeholders($rids) .") OR r.rid IS NULL) ORDER BY b.region, b.weight, b.module", 'b', 'bid'), array_merge(array($theme_key), $rids));

Как вы можете видеть, если theme_key не установлен, он просто вернет пустой результат. Сейчас я обхожу это, просто добавив:

if (!isset($theme_key)){$theme_key="<my_theme_name>";}

в modules / blocks / block.inc :: block_list () в строке 429. Мне все еще нужно найти лучший способ сделать это.

  • 10 для всех, у кого есть предложения о том, как можно установить $ theme_key перед вызовом block_list:)
1 голос
/ 20 марта 2011

Создайте функцию, подобную этой

<?php

function stg_allcontent2($allC, $level
= "1") {

    global $language;   $lang = $language->language;

    foreach ($allC as $acKey => $ac) {

        if($ac['link']['options']['langcode']
== $lang){          if ($level == "1") 
                $toR .= "";

            if (is_array($ac['below']))
                $class="expanded";          else
                $class="leaf";
                            $toR .= "<li class=\"".$class."\">" . l($ac['link']['link_title'], $ac['link']['link_path']) . "</li>";

            if ($level != "1") $toR .= "";          if (is_array($ac['below'])) $toR .= "<ul class=\"menu\">".stg_allcontent2($ac['below'], "2")."</ul>";           if ($level == "1") $toR .= "";      }
    }
    return $toR; } ?>

звоните так

<?php echo '<ul class="menu">'; echo stg_allcontent2(menu_tree_all_data($menu_name
= 'menu-header', $item = NULL)); echo '</ul>'; ?>
0 голосов
/ 03 ноября 2010

Это может помочь вам: http://drupal -translation.com / content / translation-block-contents #

ОБНОВЛЕНИЕ: функция t () позволяет вам передать используемый код языка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...