Drupal module_invoke() 和 i18n

问题描述 投票:0回答:4

我的任务是在 Drupal 中国际化我们当前的 CMS 设置。 我面临的问题是使用 module_invoke() 在节点内放置块。

我已经成功地对翻译块进行了字符串化,并且当使用 UI 将块放置在某个区域中(块内容已成功翻译)时,该功能就可以工作。

但是,当像这样将块注入节点时:

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

它没有被翻译,或者更糟糕的是,根本没有显示。

我也使用 t() 尝试过这种变体。例如:

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

无济于事。

一般来说,我在使用 i18n 块时遇到了一些麻烦。有没有人有推荐的方法来处理 drupal 中的块并翻译它们?我不想为每种语言创建不同的块。

php drupal internationalization
4个回答
3
投票

所以..在Drupal的内部进行了深入挖掘之后--并且费了很多功夫..我想出了一个几乎不错的解决方案。

基本上,通过这个功能,我可以提取块的翻译版本:

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。

最后(这是我仍然需要找到一个好的解决方案的部分),我发现:includes/blocks/block.inc 中的 block_list() 有一点问题。

看来 $theme_key 没有被可靠地设置,除非从 theme() 函数(在includes/themes.inc中)调用 block_list() ..这会导致 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 对于任何对如何确保在调用 block_list 之前设置 $theme_key 有建议的人:)

3
投票

自从我使用以来,我遇到了与你完全相同的问题

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

将块注入我的节点。然而,在 Drupal 参考文献中查找 module_invoke,我发现了一条标题为“在 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”。


1
投票

创建一个这样的函数

<?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
投票

这可能对您有帮助:http://drupal-translation.com/content/translated-block-contents#

更新:t() 函数允许您传入要使用的语言代码。

© www.soinside.com 2019 - 2024. All rights reserved.