Globally configured frontend forms

Hello there!

I’m looking for a way to globally configure forms for the purpose of reusing them across many landing pages.

I’m aware I could create the form, once, inside any page, then use its name to include it in other pages. However, these landing pages will be short-lived, and making all of them dependent on one arbitrary page is not something I feel very comfortable with (especially since my client will be the one creating the landing pages, from the admin interface).

I’ve tried defining the form inside my site.yaml, but to no avail. I’ve also stumbled upon the usage of a frontmatter.yaml file, however, these also appear to be page-specific only.

Is there a way to define forms, once, in a global file accessible to all pages?

I’m a bit confused. Do you want to have one global form which would show on all pages, or you want to have multiple forms, from which you could assign one to a page to show?


Is there a way to define forms, once, in a global file accessible to all pages?

Yes, see Displaying forms from Twig

1 Like

I have started to add a user/pages/shared folder for reusable content in my projects. It’s always a bit different, I am still looking for a good standard structure. Haven’t done this to pull a form out, but it should work fine :stuck_out_tongue:

You might have user/pages/shared/forms/, containing the frontmatter:

routable: false
  # your form here

(the page is already not visible because of its folder names)

Then in your landing page template you might have:

{% include 'forms/form.html.twig' with {form: page.find('/shared/forms').forms(0) } %}

That last expression page.find('/shared/forms').forms(0) probably needs tweaking, I apologise for not testing it. Edit: That expression seems fine, you could also use ...forms('NameOfForm').

Grav might also complain that there is no template reusable-form.html.twig in your theme. I doubt it.

I have mostly used the shared pages folder for modular page components (modules) so far.

I’ll update this if I get a chance to test that code above.

@Karmalakas The latter. Have some predefined forms, and be able to include them in any page/template.

@pamtbaau That’s not really a solution though, since displaying a form anywhere is not the issue (either through the method you linked, or through the inclusion of a twig snipped in the markdown itself).

The issue is defining the forms somewhere. The forms are not logically tied to any one page, and there’s a possibility that a form will not be displayed on any page - so, where put the definition?

A global version of frontmatter.yaml would solve the problem, and so would being able to define forms in site.yaml.

@hughbris That looks like what I’m trying to do! Ngl, it feels a little hacky, but I’ll have a try at your method. Thanks!

I would have forms defined somewhere as @hughbris suggested and then a separate page template with extended default (or whichever template you use for landing pages) and additional field to choose a form from a dropdown. You might need a simple plugin though for the dropdown to return forms selection though

It is hacky! I haven’t come with anything better overall, and been thinking about this problem for a while. The core team would probably tell you to use flex objects somehow and they will be right. That’s no hack. Good luck if you can follow the documentation!

I understood it’s always the same form, so could be hardcoded into the template, but I could have interpreted it wrong.

@Karmalakas Good idea! The blueprint for my landing template already extends default, so it should be easy to add.

@hughbris It works splendidly though! Very nice. Do you happen to know if there’s a way to hide the /shared/ folder in the Admin panel, though? ^^

I don’t actually and had a quick check. There should be custom frontmatter you can put on a page. That’s the convention in a lot of plugins. It might exist.

You could probably use the permission system to prevent a group of users from editing the page if that suffices.

Following this link, it looks like there is another expression for referencing the shared form:

# Contact Form
{% include "forms/form.html.twig" with { form: forms( {route:'/forms/contact'} ) } %}