web-dev-qa-db-ja.com

コントローラークラスの出力にカスタムフォームを追加するにはどうすればよいですか?

カスタムモジュールにコントローラーがあります。このコントローラーの内部では、さまざまなもの(いくつかの基本的なhtml、複数のフォームなど)全体をレンダリングする必要があります。私の主な問題は私が方法を理解できないことです

  1. Drupal 8カスタムフォームを適切にロードします
  2. 次に、そのフォームを受け入れ可能な形式にして、コントローラーの#markup出力に渡します。
  3. このフォームは他のhtmlと混ざっていることに注意してください。これはここには表示されていない多くの要素の寄せ集めです(基本的な例を示すために切り詰めています)。

私のコントローラーコードは現在次のようになっています:

<?php

namespace Drupal\my_module\Controller;
use Drupal\Core\Controller\ControllerBase;

class SingleNodeProcessor extends ControllerBase {

  public function processSingle($nid) {    
    $markup = '<div class="process-heading">' . $this->t('My custom Form Is below but there will be alot more html than just the form. So this is just an example.') . '</div>';

    $form = $this->formBuilder()->getForm('Drupal\my_module\Form\MyFormClassGoesHere', $nid);
    $markup .= $form; //this is a render array, how do I turn it to html so it can pass to #markup??

    return [
      '#type' => 'markup',
      '#markup' => $markup,
    ];
  }
}
2
Bobby

マークアップの代わりにレンダー配列を返したいと思います。 fromはレンダー配列のままにする必要があるため、コンテンツコンテンツを他の方法ではなく同じ形式にすることが最善の策です。あなたの例では:

public function processSingle($nid) {
  $build = [];
  $build['heading'] = [
    '#type' => 'markup',
    '#markup' => '<div class="process-heading">' . $this->t('My custom Form Is below but there will be alot more html than just the form. So this is just an example.') . '</div>',
  ];
  $build['form'] = $this->formBuilder()->getForm('Drupal\my_module\Form\MyFormClassGoesHere', $nid);
  return $build;
}
8
Dave Reid

問題は、#markupタイプのレンダー配列がXSSフィルタリングを介して結果のマークアップを実行し、それによって多くのタグを除外することです。 ( Render APIドキュメントを参照 )。この場合、フォームタグは除外されます。

ドキュメントによると、これを行う正しい方法:

マークアップでこのホワイトリストにないタグが必要な場合は、テーマフックやアセットライブラリを実装できます。または、キー#allowed_tagsを使用して、フィルタリングするタグを変更できます。

したがって、解決策は、いくつかのタグをレンダー配列の#allowed_tagsに渡すか、(より良い解決策)単純な#markupの代わりにレンダー配列で#themeを使用することです。

2
Bobby