× Home
Enable dynamic functions in the static website generator Hugo with PHP.

Using PHP in Hugo

Use PHP in Hugo

There are limits to the use of the static website generator Hugo. With PHP, server-side dynamics can be built in. This article uses examples to explain the configuration and different types of PHP calls in Hugo.

This tutorial is based on the know-how of Christoph Lieck (totoff) - Hugo Forum - How to include a PHP form in HUGO - many thanks for that.

Configure the recognition of PHP in Hugo

Hugo does not know PHP in the default configuration. The media type and output format must be configured in config.toml as follows:

[mediaTypes]
  [mediaTypes."application/x-php"]
  suffixes = ["php"]

[outputFormats]
  [outputFormats.PHP]
    mediaType = "application/x-php"
    isPlainText = true
    baseName = "index"

mediaTypes

Via the mediaTypes, the type and suffix of the file names are made known.

outputFormats

In Hugo’s documentation - Configure Output Formats - it says for isPlainText = true: “isPlainText use Go’s plain text templates parser for the templates.” I guess this means that Hugo simply passes everything marked with PHP through the generator as text. So you really should know what you’re doing.

baseName = "index" now it gets more complicated. I assume that a Leaf Bundle with an index.md is expected with this configuration. Leaf Bundle see - Page Bundles - in the Hugo documentation. For multilingual web pages, the primary language is stored in the file index.md and another language in, for example, index.en.md. The multilingual web pages are taken into account by Hugo through the baseName.

Pass the output format in Front Matter

The structure for the Markdown files is as follows:

content
|__ php-test
    |__ index.md
    |__ index.en.md

The file index.md:

---
title: "PHP Test"
date: 2021-05-25T20:50:28+02:00
lastupdate: ""
draft: false
slug:  
translationKey: phptest
description: "PHP Konfiguration in Hugo testen"
author: "Frank Kunert"
outputs: PHP
---

Deutsche Version von PHP Test.  

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.  
  

And the English version index.en.md

---
title: "Test PHP"
date: 2021-05-25T20:50:28+02:00
lastupdate: ""
draft: false
slug: test-php
translationKey: phptest
description: "Test PHP configuration in Hugo"
author: "Frank Kunert"
outputs: PHP
---

English version of PHP test.  

Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.  
  

Create templates for PHP

If you now save the above and call it up in the browser, you will get a “Not Found” error page. For PHP, the appropriate templates have to be created first.

My theme has a baseof.html for the basic page structure. The template defines the head, header, menu bar, content block and footer. The single.html template is included from the content block. For PHP to work in Hugo, these two templates must be copied and renamed as *.php files in the same directory. The baseof.php is not changed afterwards. There will be changes in the single.php further down.

The structure of the layouts directory will then look like this:

layouts
|__default
   |__baseof.html
   |__baseof.php
   |__list.html
   |__single.html
   |__single.php

If you now call localhost:1313/php-test in the browser with a running Hugo generator, you get a white, empty web page. But that’s ok, because Hugo doesn’t provide a PHP server.

In my post - Using MAMP Webserver locally with Hugo - I described how you can install a local webserver that provides PHP and connect it to Hugo. With the MAMP server running, you can call the new web page in the browser with localhost:8888/php-test. The web server will change the URL line to localhost:8888/php-test/index.php when it is displayed.

No line of PHP has been written yet. This will change in a moment.

Insert PHP into the single.php template

My layouts/_default/single.php template currently looks like this:

{{ define "main" }}
<section class="container">
  <h1>{{ .Title }}</h1>
  {{ .Content }}
</section>
{{end}}

In the {{ .Content }} the “Lorem ipsum …” text from the index.md is output. PHP is now added below this:

{{ define "main" }}
<section class="container">
  <h1>{{ .Title }}</h1>
  {{ .Content }}

  <?php
  echo 'Your browser: <br>' . $_SERVER['HTTP_USER_AGENT'];
  echo '<br>Author: ' . '{{ .Params.author }}';
  ?>

</section>
{{end}}

If you now call up the page again, the user agent of your browser is displayed below the “Lorem ipsum …” text. Calling up the page in a different browser also creates a different user agent. The dynamic during runtime is now available through PHP.

In addition, and this is truly remarkable, you can access the front matter variables of index.md. In the example above, to author and this is within PHP. Thanks for pointing this out - frjo - very helpful.

Call up the PHP file in the single.php template

It is clearer if the PHP code is stored in a file. However, the front matter variables of Hugo can then no longer be accessed. The single.php template then looks like this:

{{ define "main" }}
<section class="container">
  <h1>{{ .Title }}</h1>
  {{ .Content }}

  {{ readFile "static/php/php-test.php" | safeHTML }}

</section>
{{end}}

The outsourced PHP code is now in the file php-test.php. The directory path is then with me:

tekki-tipps
|__content
|__static
   |__php
      |__php-test.php

Below is the PHP code of php-test.php:

<?php
  echo 'Your browser: <br>' . $_SERVER['HTTP_USER_AGENT'];
?>

Call PHP within a shortcode

Shortcodes in Hugo allow code to be executed in a Markdown file. This can also be used for PHP. In single.php, the readFile call is removed.

{{ define "main" }}
<section class="container">
  <h1>{{ .Title }}</h1>
  {{ .Content }}
</section>
{{end}}

The shortcode has the file name php.html and is very clear:

<div>
  {{ .Inner | safeHTML }}
</div>

Within the content file index.md I use the shortcode as follows:

Hugo PHP Shortcode
The modified index.md with shortcode.

Haven’t found any other option than an image for the display. A highlight shortcode and within it a php shortcode does not work in the Markdown file.

Conclusion

Once you know how the basic structure for PHP has to be done within Hugo, the rest is relatively easy. A big advantage of Hugo is the security of a static website. By drilling down with PHP, there is one more potential security hole. For this reason, I will only use PHP in Hugo if there is absolutely no other way.

List of links to this post

This might also interest you

- Update 02. Aug. 2021 |
6 minutes to read
0
This post was created with Hugo version 0.87.0.

With the German language setting, comments are not displayed in the English version of the website and vice versa.

© 2021 - Frank Kunert  -  About me
A service from webdienste-kunert.de