【问题标题】:Drupal module_invoke() and i18nDrupal module_invoke() 和 i18n
【发布时间】:2010-11-02 21:21:07
【问题描述】:

我的任务是 i18n-ing 我们当前在 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中的块来翻译它们?我不希望为每种语言创建不同的块。

【问题讨论】:

  • 另外:有谁知道语言是否可以传递给 module_invote。例如:$block = module_invoke('block', 'block', 'view', 22, 'en')

标签: drupal internationalization


【解决方案1】:

所以 .. 在 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)。对于这种情况,我只是创建了一个名为“hidden”的区域,它不会在我的模板中的任何地方呈现,但可用于调用 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 有建议的人 :)

【讨论】:

    【解决方案2】:

    我和你的问题完全一样,因为我在使用

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

    将块注入我的节点。但是,在 Drupal 参考中查找 module_invoke 时,我发现了一条名为“to render blocks in Drupal 7 better to use 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);
    

    对我来说,它就像一种魅力。但请注意,此方法也会打印块标题,因此您可能希望在原始语言中将其设置为“无”。

    【讨论】:

    • 谢谢!为我工作。
    【解决方案3】:

    创建一个这样的函数

    <?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>'; ?>
    

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

      • 谢谢帕蒂奇。我已经经历过了,并且 似乎 让它与字符串本地化一起工作(至少在某种程度上 - 据我所知 - 当使用 Drupal 将块放入区域时UI 它正在被翻译。问题是即使字符串在理论上是本地化的,当我使用代码(如上)渲染块时,语言并没有应用于渲染的代码:(
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      • 2018-08-23
      • 1970-01-01
      • 2011-05-12
      • 1970-01-01
      • 2011-10-21
      • 2011-12-09
      相关资源
      最近更新 更多