0

I have template form.html.twig Drupal commerce is using it to render cart form. I made override of that template, to be able to change it only for cart form, without affecting other forms. That part works well.

Form template looks like this:

<form class{{ attributes }}>
  {{ children }}
</form>

Where "children" is markup. But (even not documented in template it self) there is also "element" array. So I can print the it instead of children and get the same results:

<form class{{ attributes }}>
  {{ element }}
</form>

This also works well. Now, I need to print it piece by piece. If I put loop like this:

  {% for single in element %}
    {{ single }}
  {% endfor %}

I get some form elements doubled, so obviously some elements must be excluded. But which ones?

Here is the list of all element keys inside this "element" array:

#action
#prefix
#suffix
#pre_render
#cache
#attached
#substitutions
#form_id
#type
#build_id
#token
#id
#attributes
#method
#theme_wrappers
#defaults_loaded
#tree
#parents
#validate
#submit
#theme
#processed
#required
#title_display
#description_display
#errors
#array_parents
#printed
show_view_elements
output
footer
edit_quantity
remove_button
form_build_id
form_token
form_id
actions
#sorted
#children
#render_children

How can I find out what elements should I print and what to exclude to get the same result (valid form) as when printing top element:

{{ element }}

Update: purpose of this is to render cart page a bit differently. Now, inside the form element I have first table with purchased items, then, bellow table goes div with sub-total and total prices and then div with "Update" and "Checkout" buttons. What I want is to display those 3 elements in 2 columns. In left one there should be only table with items and in right prices, buttons and some additional info.

BTW, I'm already displaying another form that way. It's template file looks like this:

<form{{ attributes }}>
  {{ title_prefix }}

  {{ element.pages }}
  {{ element.elements }}
  {{ element.form_build_id }}
  {{ element.form_token }}
  {{ element.form_id }}
  {{ element.footer }}
  {{ element.actions }}
  {{ element.children }}
  {{ element.progress }}

  {{ title_suffix }}

</form>

There I print progress bar bellow the other form elements. But I have problem achieving the same with cart form.

3
  • 1
    This isn't the answer you are looking for, but element will already have themes (templates) assigned for the various elements, so it seems to me you shouldn't be working with that. You've only told us how you are trying to do something though, not what that something you are trying to do is. If you provide that info, it may be easier to provide assistance.
    – Jaypan
    Feb 6, 2020 at 19:23
  • @Jaypan updated my question.
    – MilanG
    Feb 7, 2020 at 7:19
  • 1
    This is the wrong template, it is the #theme_wrapper rendering the form tag. Use it only to change the form tag itself or to add html outside of <form></form>. For the inner parts of the form use #theme, see drupal.stackexchange.com/questions/245127/…
    – 4uk4
    Feb 7, 2020 at 8:48

1 Answer 1

-1

Succeeded it "my way". Template now looks like this:

<form class{{ attributes }}>

{{ element.output }}
{{ element.footer }}
{{ element.form_build_id }}
{{ element.form_token }}
{{ element.form_id }}
{{ element.actions }}

</form>

element.output prints the table
element.footer prints the prices
element.actions prints the buttons
and other fields are printing necessary hidden fields

I know that @4k4 is right and I even tried solution he proposed before, but for some reason it didn't work for me (probably my mistake) and I didn't have more time to spend on this and this solution works well.

Posted this, because it's answer to this question and IMHO this should be "legal" way to print form, achieved only from twig without forcing on creating theme function and other stuff.

Please be gentle with minuses.

1
  • You should do {{ element|without('output','footer') }} after the first two and ditch the other print statements. Jan 13, 2022 at 2:25

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.