2

フィールドセットを含むフォームを構築するモジュールがあります。<legend>要素を使用してフィールドセットのタイトルをレンダリングする代わりに、このコンテンツを<div>要素に配置したいと考えています。しかし、モジュールによって返されるフォームの動作のみを変更したいので、テーマの template.php ファイルに新しい機能を配置したくありません。

mymod.module で、次のように定義しました。

// custom rendering function for fieldset elements
function theme_mymod_fieldset($element) {
  return 'test';
}

// implement hook_theme
function mymod_theme() {
  return array(
    'mymod_fieldset' => array('arguments' => array('element' => NULL)),
    'mymod_form' => array('arguments' => array())
  );
}

// return a form that is based on the 'Basic Account Info' category of the user profile
function mymod_form() {
  // load the user's profile
  global $user;
  $account = user_load($user->uid);

  // load the profile form, and then edit it
  $form_state = array();
  $form = drupal_retrieve_form('user_profile_form', $form_state, $account, 'Basic Account Info');

  // set the custom #theme function for this fieldset
  $form['Basic Account Info']['#theme'] = 'mymod_fieldset';

  // more form manipulations
  // ...

  return $form;
}

ページがレンダリングされると、「基本アカウント情報」を表すフィールドセットがテスト メッセージ「test」に完全に置き換えられることを期待していました。代わりに、<fieldset>and<legend>要素が通常どおりにレンダリングされますが、代わりにフィールドセットの本体が次のようにテスト メッセージに置き換えられます。

<fieldset>
  <legend>Basic Account Info</legend>
  test
</fieldset>

#theme 関数で<fieldset>要素全体を置き換えることができないのはなぜですか? 代わりにこの関数でテキストフィールドをラップすると、<input>要素をそのラベルとともに完全に置き換えることができます。さらに、自分のサイトの template.php で theme_fieldset のオーバーライドを提供すると、期待どおりに機能し、 を完全に置き換える<fieldset>ことができるので、それが可能であることがわかります。

モジュール内のフィールドセットに #theme 関数を提供することの違いは何ですか?

4

5 に答える 5

2

#theme 関数を使用する代わりに、theme_fieldset() をオーバーライドしようとしましたか? .module ファイルで次のようなことができると思います。

function mymodule_fieldset($element) {
  // do something;
  return $html;
}

これは、すべてのフィールドセットに適用されます。影響を与えたいフィールドセットの $element で何らかのチェックを行い、他のすべてのフィールドセットにデフォルトの実装を使用できます。

見てみましょう: http://api.drupal.org/api/function/theme_fieldset/6

于 2010-05-05T06:26:54.460 に答える
1

私はこれが古い投稿であることを知っています-しかし私は同じ問題に遭遇しました。私は醜い回避策を思いついた。これは間違いなくFormAPIのバグです。たぶん私の一時的な修正は誰かに役立つでしょう。

ここでバグレポートを見つけました(そして追加しました):http://drupal.org/node/225698

私のハッキーな修正を試す前にそれをチェックする価値があります。

この例の子が何であるかはわかり$form['Basic Account Info']ませんが、基本的にはdrupal_render()、そのフィールドセットの子で使用してから、とは別にフィールドセット配列を再作成し$form['Basic Account Info']、テーマを設定theme()して、マークアップとしてフォーム配列に返します。 。

$fieldsetElement = array(
   //$child is the key of whatever child you need in the fieldset
   //you may have to alter this for multiple children, stringing 
   //together multiple drupal_render calls on each children
   //(#children needs to be a string.. unless your theme can handle the array)
   '#children'=>drupal_render($form['Basic Account Info'][$child]),
   '#attributes'=>array(),//set real attributes
   '#title'=>$form['Basic Account Info']['#title']
);
$form['Basic Account Info'] = array(
  '#type'=>'markup',//not really needed, is default
  '#value'=>theme('mymod_fieldset',$fieldsetElement)
);

超大げさなハッキングは、フォームの状態との切断と潜在的な検証の失敗を引き起こす可能性がありますが、どちらもフォームAPIの試行錯誤によって修正可能です。PHPとdrupalフォームAPIで手を汚したい場合を除いて、これはお勧めしませんが、モジュールに可変フィールドセットテーマがない場合を除いて、これが唯一の方法です...プレフィックスとサフィックスを試してみてください。

于 2011-09-21T15:06:43.827 に答える
0

これは私の頭から離れたところにありますが、おそらく違いは、フィールドセットがフォーム要素ではなく、必要に応じて、分離子またはハタにすぎないためです。たぶん、#themeコールバックはフォーム要素専用ですか?

于 2010-05-04T07:59:38.033 に答える
0

私は同じ問題を抱えていました。

#theme_wrappers代わりに使用する必要があります#theme

'#type' => 'fieldset',
'#theme_wrappers' => array('mymodule_fieldset'),
于 2013-02-22T23:41:16.660 に答える
0

コードの概念は機能します。つまり、やりたいことを実行できます。

うまくいかない理由を説明できるものがあります。

  • フィールドセットは ではありません$form['Basic Account Info']
  • キャッシュをクリアする必要があります。
  • $form['Basic Account Info']['#theme'] は、コード実行の後半で失われるかオーバーライドされます。

$formモデレーションを行う前に、見てみてください。あなたのコードをコピーしようとすると、バグに遭遇しました:

  • user.pages.inc ファイルをロードする必要がありました
于 2010-05-04T10:23:23.007 に答える