8

私はhook_theme()が何をするのか理解するのに苦労しています。

私の理解では、それはテンプレートをオーバーライドできるようにすることと関係があります。

私が見ていた:

  $theme_hooks = array(
    'poll_vote' => array(
      'template' => 'poll-vote',
      'render element' => 'form',
    ),
    'poll_choices' => array(
      'render element' => 'form',
    ),
    'poll_results' => array(
      'template' => 'poll-results',
      'variables' => array('raw_title' => NULL, 'results' => NULL, 'votes' => NULL, 'raw_links' => NULL, 'block' => NULL, 'nid' => NULL, 'vote' => NULL),
    ),
    'poll_bar' => array(
      'template' => 'poll-bar',
      'variables' => array('title' => NULL, 'votes' => NULL, 'total_votes' => NULL, 'vote' => NULL, 'block' => NULL),
    ),
  );

それがどのように機能するかの例を教えてください。

4

3 に答える 3

22

モジュールがテーマを定義する場所を提供し、他のモジュール/テーマでオーバーライドできます。mymodule_preprocess_theme_nameまた、最終的なテーマ関数またはテンプレートファイルに渡される変数を変更するなど、モジュールがフックを使用する機会も提供します。

テーマ関数を初期化するには、基本的に2つの方法があります。

theme('poll_results', array('raw_title' => 'title', 'results' => $results, etc...));

$build = array(
  '#theme' => 'poll_results',
  '#raw_title' => 'title',
  '#results' => $results,
  etc...
); // Note the '#' at the beginning of the argument name, this tells Drupal's `render` function that this is an argument, not a child element that needs to be rendered.

$content = render($build); // Exact equivalent of calling the previous example now that you have a render array.

次の理由から、theme()を直接(theme.incのドキュメントに従って)呼び出さないようにする必要があることに注意してください。

  • キャッシングを回避します。
  • アタッチされたアセットを含む、hook_element_info()で定義されたタイプのデフォルトを回避します
  • pre_renderステージとpost_renderステージを回避します。
  • JavaScriptの状態情報を回避します。

Drupal 8では、theme()はプライベート関数_theme()です。詳細については、www.drupal.org / node/2173655を参照してください。

これらの2つを上記の例の要素と比較すると、poll_resultsおそらく何が起こっているのかを理解できます... PHPは強く型付けされた言語ではないため、Drupalはtheme関数に渡されるキー配列のいずれかを介して「名前付き引数」を提供しています、またはレンダリング配列のハッシュキーとして。

'render element'に関する限り、これは基本的に、このテーマ関数が1つの名前付き引数(この場合form)を使用してrender配列を使用して呼び出されることをテーマシステムに通知します。コードは次のようになります。

$build = array(
  '#theme' => 'poll_choices',
  '#form' => $form
);

$formこれにより、変数に含まれるものはすべて、唯一の引数としてテーマ関数に渡されます。

templateキーについて:

'poll_vote' => array(
  'template' => 'poll-vote',
  'render element' => 'form',
)

'poll-vote.tpl.php'という名前のpoll_voteテンプレートファイル(したがってキー)を使用するというテーマを定義します(これは慣例によるものです)。templateそのテンプレートファイルへのパスは、それを実装するモジュールへのパス(例:modules / poll / poll-vote.tpl.php)を使用して検出されるため、メインモジュールフォルダーのサブフォルダーにテンプレートファイルを配置することは問題ありません。 。

テーマ関数の出力を実際に返すには、物理​​関数名(この場合はtheme_poll_vote)を実装する方法と、テンプレートファイルを使用する方法の2つがあります。キーが空の場合、templateDrupalは物理関数を実装したと見なし、それを呼び出そうとします。

テーマ用に出力するHTMLがかなりある場合、またはPHP内で文字列にHTMLを記述したくない場合は、テンプレートファイルが適しています(個人的にはそうではありません)。ただし、どちらの場合でも、テーマを呼び出すときに渡される変数(theme()上記のようにまたはレンダリング配列を使用)は、それ自体がテンプレートファイルまたはテーマ関数に渡されます。それで:

function theme_poll_results(&$vars) {
  $raw_title = $vars['raw_title'];
  $results = $vars['results'];
  // etc...
}

同じメソッドの代わりにテンプレートファイルを使用している場合、Drupalはテンプレートファイルを解析する前に実行されるため、変数は$raw_title$resultsなどとして使用できます。extract$vars

私がここで見逃したことはたくさんあると思いますが、もっと具体的な質問があれば、遠慮なく質問してください。私がお手伝いします。

于 2011-10-12T16:52:10.720 に答える
3

Drupal 6

私はこれで一日中立ち往生し、今ではうまく実装されているので、ここで私の発見を共有することは、理解するのに役立つかもしれませんhook_theme

関係する3つのステップがあります:

  1. hook_theme

    function YOURMODULENAME_theme() {
      return array(
        'xxx_xxx' => array(
        'template' => 'xxx-xxx', // define xxx-xxx.tpl.php inside module
        'arguments' => array('xxx' => null), //define $xxx so it will available in your xxx-xxx.tpl.php
        ),
      );
    }
    
  2. echo/あなたまたは任意returnのテーマ.tpl.module

    $output = theme('xxx_xxx', $xxx);
    
  3. これで、変数が魔法のように利用できるようになりましたxxx-xxx.tpl.php

    <?php echo $xxx ?>
    

注:$ xxxは、配列、オブジェクト、その他何でも渡すことができます:)

于 2012-03-13T11:37:24.070 に答える
0

さらに別の方法があります:(Bartikテーマにあります)

ここでのシナリオは、独自のモジュールを作成し、タイトルが「zzz」のノードのみのデフォルト出力をオーバーライドしたい場合です。
デフォルトの出力がどのように生成されるかはわかりませんし、実際には気にしません。必要なのは、Drupalに独自のカスタムテンプレートファイル(node--custom--name.tpl.php)を使用してその特定のノードをレンダリングするように指示することだけです。

手順は次のとおりです。

  1. テンプレートファイルが存在する場所をDrupalに伝えます。(この関数は、Drupalのキャッシュをクリアした後に1回だけ有効になることに注意してください):

    // Implements hook_theme()
    function mymodulename_theme() { 
      $theme = array();
      $theme['node__custom__name'] = array(
        'render element' => 'node',
        'template' => 'path_from_mymodule_root/node__custom__name',
        );
      return $theme;
    }
    
  2. Drupalにいつどこで使用するかを伝えます

    //Implements hook_preprocess_node()
    function mymodulename_preprocess_node($vars) {
        if($vars['node']->title == 'zzzz') {
            $vars['theme_hook_suggestions'][] = 'node__custom__name';
            ... your other code ...
         }
     }
    

    これで、Drupalは、'node--custom--name.tpl.php'ファイルが宣言されたパスにある場合にのみ、その特定の場合にのみテンプレートファイルを使用します。それ以外の場合は、フォールバックテンプレートの命名規則に従って検索を続けます。 。

于 2013-11-19T09:56:10.323 に答える