2

There are several attempts and questions already asked about near to that topic in combination with the new Drupal core (8), but non of them came down to the bottom of the basic question. And non of them are up-to-date enough (2015) since many late changes in core arrived afterwards (2016). Answering the basic question will hopefully lead to answers for many depending questions and open HOWTO topics and could be a good basis for updated docs on drupal.org.

The basic question is:

How to programmatically render path/page based forms or any other entity bundles on the theming level to display them path independently, e.g. in blocks or other pages other than the given pages/paths of itself? And how can I find the right routing for the correct system calls or class paths for the needed preprocess functions in the new D8 core logic if I am new to D8?

The question arises from 2 points of view:

  1. Why should a form be hard binded to a page view or fixed path? It's a page element, not a page. It should be available easely in any other places without complicated coding struggles in a website building CMF like Drupal on the theming level. It's part of theme design to decide to have a form on frontpage, for example. (ok, this is arguable, I know, but in some cases it is)

  2. From the basic structure how Drupal is build and what it tries to achieve in these times (the goal to rather build web applications instead of classic and static websites), it should be easily reachable to maintain such task like a form on the bottom of a one-page site or to build a survey or render entities on unexpected pages.

To keep with the form example:

here are some links to questions regarding this topic and I've tried already to interfere there and suggest to inform about changes in core here and there to update the posts or to link to sources:

The basic structure

.. how it works is common, mostly clear, and not so far from how it worked in D7:

You will use a preprocess_xxx() function in your D8 twig YOURTHEMENAME.theme file to call and pipe the form or entity array into the region variable array, to be able to render it via {{ var }} twig-tags in your xxx.twig file: e.g. block.html.twig or page.html.twig, since the form or entity is maybe not known in this layer (enviroment variable) by default.

Just an example (needs update and correction) of your THEMENAME.theme file:

preprocess_page(){
  $form = Drupal::routeMatch()->getParameter('contact_form'); // ???
  $message = \Drupal::entityTypeManager() // ???
  ->getStorage('contact_message')
  ->create(array(
      'contact_form' => $form->id(),
  ));
  /// ???
  $form = Drupal::service('entity.form_builder')->getForm($message);
  $variables['contact_form'] = $form;
}

Just an example page.html.twig file:

<header>
  {{ header_region }}
</header> 
<div id="main"> ... </div>
<footer>
  {{ contact_form }} <!-- from $variables['contact_form'] = $form; -->
</footer>

But now comes the tricky part:

The docs are not up-to-date enough to make clear how to build the preprocess_xxx() function correctly, demonstrated with \\ ??? here. Using the demo example here as-is (atm) will cause an almost empty frontpage, only rendering html.html.twig but without the nested page.html.twig, obviously caused by a wrong coding in the preprocess function.

Somebody who tries to find updated docs or QA for that will have a hard time ...

  • 1
    I'm not exactly sure what you are asking in that very long question. As I've answered in multiple of the questions you mention, the entityform_block (and some others too) module does exactly this. A block that allows to display any entity form as a block. Currently add only, but editing existing entities would absolutely be possible too. Use it or learn from it. It has exactly the those pieces of code that you're missing. – Berdir Apr 6 '16 at 19:32
  • 1
    @Berdir, well I can't disagree more. If you are not sure about what nilsun is asking about you definitely doesn't read it. He took the time to explain very clearly and in detail that he tries to collect some infos here for further documentation. And to recommend looking in some specific module-code representing some corner cases, while he tries to get a basis, is the absolutely wrong answer. Then, we can close Drupal Answers, since most of the questions can be reviewed via some other module code. And even the title says theming level. Not module development. Not even hard to read... – diqidoq Apr 6 '16 at 19:49
  • 1
    Despite of that, we agree in the community of many missing documentation @ D8 ATM and we shouldn't discourage people who try to collect informations to build docs. It takes time to write docs or detailed intro questions like this and I don't like the way you slap it, TBH. BTW: most of the mentioned questions and answers are outdated. – diqidoq Apr 6 '16 at 19:54
  • 1
    Let's stay nice ;) You're welcome to explain me the difference between theming level and module development. It's both PHP. You're certainly not going to be able to this just with twig without any PHP. And the way to build something with Drupal (specifically with 8), is with blocks. Theming is there to control how something is displayed, not what. 2 of the 3 questions are a bit older yes. But there's also drupal.stackexchange.com/questions/197084/… from today which has a reference to two different modules that allow you to place contact/entity forms. – Berdir Apr 6 '16 at 20:08
  • 1
    Oh great! For me it isn't hard to stay nice ;-) I like nice people. & I like facts. And missing docs is one. The Q was very good readable seperated by a paragraph and headline IMHO is another one. 2nd, there are many approaches how to build web apps with Drupal, that's the good thing and should not be changed by howto-religions and should not effect docs at all. 3rd, I'd never try to explain you the diff between theme & module level since you obv. can learn from reading module code ;-). But it's about users here who feel unconfident. 4th: There're scenarios where blocks doesn't make it. Then? – diqidoq Apr 6 '16 at 21:01
3

How to programmatically render path/page based forms or any other entity bundles on the theming level to display them path independently, […]

Because in Drupal 8/7/6/…, forms do not have dedicated routes/controllers (D8) or page callbacks/paths (D7/6…). Hence they are path-dependent.

Once that is solved, then yes, you would be able to do that. For now, it's literally impossible.

See https://www.drupal.org/node/2503429

The only way you could perhaps make this work, but even then only for forms you define (and not for every form), is by defining a route where your form always POSTs to, and then setting it as the form action ($form['#action'] = 'foo'; is mapped to <form action="foo").


For now, the recommended approach to be able to put a form anywhere, is to expose it as a block. For an example, see \Drupal\search\Plugin\Block\SearchBlock and how it uses \Drupal\search\Form\SearchBlockForm.

  • I'm not sure I follow that argument :) Of course, the way form submission has to be implemented internally right now is awkward, but form placement is path-independant. As long as the form is somehow rendered again when doing the POST request, then it can be submitted. Can be the same page or it can be a different page. – Berdir Apr 7 '16 at 19:37
  • @Wim Leers Thanks a million for the detailed explanation and the link to the issue. This gives a lot of inside to dip deeper into it. – nilsun Apr 8 '16 at 12:28
3

The question is a feature request. Providing this feature "entity/form as a block" can be done in the core module, but usually this kind of features are first provided in contrib and later they may become part of core. There are projects to address this:

https://www.drupal.org/project/entityblock

https://www.drupal.org/project/contact_block

https://www.drupal.org/project/entityform_block

In my opinion putting the code in theming is only a short time solution, until this is solved in contrib/core. As the OP has experienced, you don't know how long it works, because this code doesn't get updated.

  • thanks for your effort, time and links for this. You are partly right but in some cases in can become the only option to render entity bundles directly in a dedicated type-of-something.html.twig. It depends also on how the build project tries to seperate things. Lucky enough Drupal tries to keep being flexible for such decisions, which is part of its strength. – nilsun Apr 8 '16 at 12:30
  • 1
    @nilsun I agree, there are always cases where you need to do something apart from the mainstream, which is in in D8 that every element on a page without it's own path is a block. Compare the page templates from D7 and D8. – 4k4 Apr 8 '16 at 12:52
3

I'm still new to drupal but here is what i did to render a form in node.html.twig:

//file themename.theme
function themename_preprocess_node(&$variables) {
  if(isset($variables['node'])){
    $node = $variables['node'];
    if($node->getType() == 'application') {
        $message = \Drupal::entityTypeManager()
            ->getStorage('contact_message')
            ->create(array(
            'contact_form' => 'webentwickler_job', //ID(Machine name) of form
        ));
        $form = \Drupal::service('entity.form_builder')->getForm($message);
        $variables['application_form'] = $form;
    }
  }
}

//file node--application.html.twig
{{ application_form }}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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