web-dev-qa-db-ja.com

Hook_menuタイトルコールバック内のHTML

タイトルコールバックのテキストの周りにスパンクラスを挿入しようとしています。 t()関数を通過するため、すべてのHTMLがエスケープされます。

これを回避する方法はありますか?

私のコードは:

function custom_module_menu() {
  $items = array();

  $items['discussion'] = array(
    'title' => 'Discussion',
    'title callback' => 'custom_module_title',
    'page callback' => 'custom_module_tester1',
    'access callback' => TRUE,
    'menu_name' => 'document-menu',
    'type' => MENU_NORMAL_ITEM,
    'options' => array('attributes' => array('class' => 'discussion')),
    'weight' => 10,
  );

  return $items;
}
function custom_module_title() {
  $discussionnid = custom_module_postexist(3);
  if ($discussionnid) {
    return 'Discussion <span class="discussionnumber">85</span>';
  }
  else {
    return 'Discussion';
  }

}
3
digital

template_preprocess_page() が次のコードを使用してタイトルを取得するため、タイトルのHTMLはエスケープされます。

_// Construct page title
  if (drupal_get_title()) {
    $head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
  }
_

drupal_get_title() には、次のコードが含まれます。

_function drupal_get_title() {
  $title = drupal_set_title();

  // during a bootstrap, menu.inc is not included and thus we cannot provide a title
  if (!isset($title) && function_exists('menu_get_active_title')) {
    $title = check_plain(menu_get_active_title());
  }

  return $title;
}
_

タイトルはその関数からエスケープされます。

私の知る限り、_<title>_のコンテンツにはHTMLタグを含めないでください。それがエスケープされる理由です。

HTML 4の W3C仕様では、次のテキストが報告されています

タイトルには文字エンティティ(アクセント付き文字、特殊文字など)を含めることができますが、他のマークアップ(コメントを含む)を含めることはできません。ドキュメントのタイトルの例を次に示します。

_<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A study of population dynamics</TITLE>
<!-- other head elements -->
</HEAD>
<BODY>
<!-- document body -->
</BODY>
</HTML>
_

Changed Elements では、_<title>_タグに関するHTML 5とHTML 4の間の変更は報告されません。

Drupal 7では、 drupal_set_title($title, PASS_THROUGH) でタイトルを設定できますが、ドキュメントには次のように記載されています:

PASS_THROUGH に設定するのは、 のような関数を使用して_$title_から危険な可能性のあるコードをすでに削除している場合のみですcheck_plain() または filter_xss() 。このフラグを使用すると、文字列は変更されずに渡されます。

_PASS_THROUGH_は、タイトルが2回フィルタリングされるのを回避するために使用され、タイトルをまったくフィルタリングするためではありません。

この場合、タイトルコールバックからdrupal_set_title()を使用することはできません。別の場所に設定する必要があります。ただし、そうすることはお勧めしません。

5
kiamlaluno

同様の状況で、リンクのすぐ隣にメニュー項目の重みを表示したいと思いました。リンクのタイトル自体にHTMLを挿入することは問題があるようなので、私は別のアプローチを選択しました。

リンクに追加の属性を追加し、CSSを使用して表示します

$items['discussion'] = array(
  // ... all the other properties
  // Our special attributes:
  'options' => array(
    'attributes' => customAttr()
  ),
);

function customAttr() {
  $discussionnid = custom_module_postexist(3);
  if ($discussionnid) {
    return array(
      'class' => 'discussion',
      'data-discussionnumber' => 85
    );
  }
  else {
    return array(
      'class' => 'discussion'
    );
  }
}

これは次のようなリンクを返します:

<a class="discussion" data-discussionnumber="85" href="yourHref">yourTitle</a>

これで、次のCSSを追加できます。

#document-menu a:after {
  content: attr(data-discussionnumber);
  /* your custom styles */
}

お役に立てれば!

2
AvL

使用できます

_drupal_set_title('your html title',PASS_THROUGH) 
_

ページをレンダリングする前に。

_PASS_THROUGH_ = drupal_set_title();のフラグ。テキストはすでにサニタイズされています。

2
Bruno

_title callback_を置き換える関数を定義するt()

例えば.

_<?php
function node_menu() {
  $items['node/%node'] = array(
    'title callback' => 'node_page_title',
    'title arguments' => array(1),
    'page callback' => 'node_page_view',
    'page arguments' => array(1),
    'access callback' => 'node_access',
    'access arguments' => array('view', 1),
    'type' => MENU_CALLBACK,
  );
}

/**
* Title callback.
*/
function node_page_title($nid) {
  $node = node_load($nid);
  return "<span>" . $node->title . "</span>";
}
?>
_
1
Shoaib Nawaz

drupal 7.の答えを探してここに到着した場合(これがdrupal 6で機能するかどうかはわかりません)。あなたは " options "array" html "=>" true "。このパラメーターは、l()に渡され、htmlタグを解析しないように言います。危険なので、注意して使用してください。

から hook_men

"options":このメニュー項目からリンクを生成するときにl()に渡されるオプションの配列。 "options"パラメータはMENU_LOCAL_TASK、MENU_DEFAULT_LOCAL_TASK、およびMENU_LOCAL_ACTIONには影響しないことに注意してくださいアイテム。

および l ()から:

'attributes':アンカータグに適用するHTML属性の連想配列。要素「クラス」が含まれる場合、それは配列でなければなりません。 'title'は文字列でなければなりません。他の要素はdrupal_attributes($ options ['attributes'])の呼び出しで機能する必要があるだけなので、より柔軟です。

'html'(デフォルトはFALSE):$ textがHTMLか単なるテキストか。たとえば、画像タグをリンクにするには、これをTRUEに設定する必要があります。そうしないと、エスケープされたHTML画像タグが表示されます。 'html'がTRUEの場合、$ textはサニタイズされません。呼び出し元の関数は、$ textがすでに安全であることを確認する必要があります。

そのようになります:

 function custom_module_menu() {
  $items = array();

  $items['discussion'] = array(
    'title' => 'Discussion',
    'title callback' => 'custom_module_title',
    'page callback' => 'custom_module_tester1',
    'access callback' => TRUE,
    'menu_name' => 'document-menu',
    'type' => MENU_NORMAL_ITEM,
    'options' => array('attributes' => array(
       'class' => 'discussion',                //will be passed to l()
       'html' => true 
       )),
    'weight' => 10,
  );

  return $items;
  }


  function custom_module_title() {
    $discussionnid = custom_module_postexist(3);
    if ($discussionnid) {
      return 'Discussion <span class="discussionnumber">85</span>';
    }
    else {
      return 'Discussion';
    }
  }
0
nimbfire