I recently needed to include a PHP form in one of my HUGO projects and found myself struggling with this task quite a bit. Some Google searches and within the forum gave me the impression I’m not the only one having difficulties with PHP forms within HUGO. So I thought I’ll post my solution here as a step-by-step guide. Maybe it can serve as a starting point for your project. However, I’m not a super-dev therefore my solution might not the optimum one can come up with and, in addition, English is not my first language. This said, please excuse me for language mistakes and please don’t hesitate to give feedback on the coding.
1. Make HUGO render .php files
HUGO ships with some default Media Types and Output Format Definitions but unfortunately PHP is not among it. As our form requires a .php file we need to setup custom Media Type and Output formatting for it.
Go to your config.toml and set up a Media Type for PHP:
# examplel for .toml
[mediaTypes]
[mediaTypes."application/x-php"]
suffixes = ["php"]
Based on this you may now define your output format in config.toml:
# example for .toml
[outputFormats]
[outputFormats.PHP]
mediaType = "application/x-php"
isHTML = true
baseName = "index"
2. Set output formatting in page front matter
Basically you are now (almost) ready to render pages as .php files. In my case I had a dedicated page that I wanted to hold the form:
|_ content
|_ form
|_ index.md
So I decided to set output formatting in front matter:
+++
title = "form"
outputs = ["PHP"]
+++
3. Create templates for PHP
Having set all this will output nothing until you’ve created a template to render your file.
As my page is a regular page it gets rendered with layouts/default/single.html. Duplicate this file and name it single.php.php (see the docs for more information):
|_____default
| | |____single.html
| | |____single.php.php
However, that won’t give you what you want if you have a baseof.html file in your layouts/_default directory. In this case you also need to duplicate this as single.php.php depends on it. Finally, this is how your _default dir should look like:
|_____default
| | |____single.html
| | |____baseof.php.php
| | |____list.html
| | |____baseof.html
| | |____single.php.php
Now calling hugo will render content/form/index.md as index.php instead of index.html (Unneccessary to say: you won’t be able to see your file content under localhost:1313 as HUGO’s local webserver is not capable of PHP. From here on you need either a local webserver with PHP (I use Apache in a docker container) or you need to push to a hosted environment with PHP in order to see the effect of content changes etc.).
4. Create a PHP form
My form was rather complicated. So I used the highly recommended form generator by Werner Zenk to create it. The tool returns all required logic and markup in one single .php file. So i decided to use it in my template “as it is.” (If you search for similar solutions with HUGO on the internet you’ll find approaches with shortcodes in .md files. I won’t discuss this but it’s an equivalent valid approach and depending on how you create your form it might be a better or less good fit).
In my case I saved the form as form.php under static/php/:
|____
| |____php
| | |____form.php
5. Include the form in your template file
Now, how do you include the form in your single.php.php file? Partial function won’t help you as your file lives under static and you can’t stop HUGO escaping your PHP code. But HUGO’s readFile function gives us what we want. Together with safeHTML is returns the PHP code as it is. This is what the template looks like in my project:
{{/*single.php.php*/}}
{{ define "main" }}
{{ .Content }}
{{ readFile "static/php/form.php" | safeHTML }}
{{ end }}
And bam!, here you are. HUGO renders your PHP code nicely and untouched to an index.php file. If your PHP code is error free your form should work now.
However, please note: the --minify flag doesn’t play nice with .php files. In my case HUGO erased some of the PHP code so I had to waive --minify. (If somebody knows a way to use --minify with the approach outlined please comment!)
Hope this tutorial makes including forms in HUGO a little bit more fun Comments are very welcome.