I have built a custom form (in its own module using FORM API) and have exposed this form also as a block using Plugin API.

I can add this form fine to page and get it to render using Block Layout but it doesnt appear in the correct place.

I am trying to get it to appear in the main page content of a Page View which has a Header and Footer. The form seems to appear after the footer content, even after shifting the block around in the block layout.

So now I have been trying to use the various view template hooks by loading the form via the snippet:

$block = \Drupal\block\Entity\Block::load('auctioncataloguerequestform');
$block_content = \Drupal::entityTypeManager()
$variables['form_auction_cat_request'] = $block_content;

auctioncataloguerequestform is the machine name of the "form block" added to Block Layouts (Its in the content section, but disabled)

But in XDebug I cannot find the form_auction_cat_request variable and {{ form_auction_cat_request }} renders nothing.

Hooks I tried using where: template_preprocess_views_view, template_preprocess_views_view_field and template_preprocess_views_view_unformatted

At the moment I am simply trying to get the form to render but once this is done I then need to pass a string variable which is a field of the view in question to be passed to the form.

Am I on the right track or completely missing the mark?

View screenshot

Auctions view

1 Answer 1


Print form before the views:

function mymodule_preprocess_views_view(&$variables) {
  $form = \Drupal::formBuilder()->getForm('\Drupal\mymodule\Form\DefaultForm');
  $variables['attachment_before'][] = $form;


Another way is to add your custom form and the views in own controller (and route),

In views add filters and expose them, set exposed in block = yes (this will detach the form from the views),

in exposed filters settings set the names as they are in your form - for each one,

make your form to redirect on submit to the route passing the values as query params (?param_name=value&param_name2=value2), for multiple select or checkboxes params are in format: param_name[6]=6&param_name[17]=17

the rest will be done by views - it will get params automatically



namespace Drupal\mymodule\Controller;

use Drupal\Core\Controller\ControllerBase;
use Drupal\views\Views;

 * Class DefaultController.
class DefaultController extends ControllerBase {

   * Content.
   * @return string
   *   Return Content string.
  public function content() {

    $elements = [];

    $elements['form_search'] = \Drupal::formBuilder()->getForm('\Drupal\mymodule\Form\DefaultForm');
    $elements['form_search']['#weight'] = 0;

    $views_name = 'machine_views_name';
    $display_id = 'page_1';
    $view = Views::getView($views_name);

    $elements['view'] = $view->render($display_id);
    $elements['view']['#weight'] = 1;

    return $elements;


example module with controller, form and exported views "Content list": https://github.com/svetlio/mymodule

  • The first suggestion worked for me for displaying the form correctly, still can't inject a string variable though. Will investigate further today on that. Thanks for the help
    – John Cogan
    Nov 12, 2018 at 10:27
  • There are 2 keys points for this: 1. Add a filter field in the views to search in ("Title" for ex.), expose him, change the "Filter identifier" in a filter conf to "string" for ex.; 2. On submit pass the value to $_GET['string'], so url should look like "/your_views_path?string=something+to+search". You can test it just by typing this kind of url to see results in the views, then research how to redirect your form "on submit" to this url.
    – svetlio
    Nov 13, 2018 at 7:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.