Using Eleventy and PHP Together

Eleventy is a static site generator that outputs HTML files based on templates and layouts. By default, it does not contain support for adding dynamic parts like a contact form to the website. Therefore, often third party services are used for contact forms, which might be problematic in regard to data protection. In case the HTTP server used supports PHP, Eleventy can be used to output PHP files for the dynamic elements.

Outputting PHP Files

By default, Eleventy outputs static HTML files named index.html for each template file it processes. Eleventy can also be set up to output PHP files, such as index.php, which will be executed as PHP scripts on the server.

The listing below shows the content of a Markdown template named index.php (the file could even be named index.md):

---
permalink: "{{ page.filePathStem }}.php"
---

# Using Eleventy with PHP

<?php
echo '<p>Hello World from PHP!</p>';
?>

Without further configuration, Eleventy would generate a URL ending in …/index.php instead of just …/. In order to create URLs without the file name, the file name can be removed in the Eleventy configuration file as follows:


// Remove "index.php" from `page.url`.
eleventyConfig.addUrlTransform((page) => {
  if (page.url.endsWith('index.php')) {
    return page.url.slice(0, -1 * 'index.php'.length);
  }
});

Basic PHP Contact Form

The listing below shows the PHP source code for a basic HTML contact form. The template is used to generate the PHP file:

---
title: Contact Form
permalink: "{{ page.filePathStem }}.php"
---
<h1>Contact Form</h1>
<?php
$to_email = 'joe@example.org';
$errors = [];
$status_message = "";
$success = false;
if (!empty($_POST)) {
  $name = $_POST['name'];
  $email = $_POST['email'];
  $message = $_POST['message'];
  if (empty($name)) {
    $errors[] = "Name is empty.";
  }
  if (empty($email)) {
    $errors[] = "E-mail address is empty.";
  } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
    $errors[] = "E-mail address is invalid.";
  }
  if (empty($message)) {
    $errors[] = "Message is empty.";
  }
  if (!empty($errors)) {
    $status_message = join(" ", $errors);
  } else {
    $subject = "Contact form submission";
    $headers = [
      'From' => $email,
      'Reply-To' => $email,
      'Content-Type' => 'text/plain; charset=utf-8'
    ];
    $body_lines = [
      "Name: {$name}",
      "E-mail address: {$email}",
      "Message:",
      $message
    ];
    $body = join("\n", $body_lines);
    if (mail($to_email, $subject, $body, $headers)) {
      $status_message = "Message sent successfully.";
      $success = true;
    } else {
      $status_message = "Something went wrong. Please try again later.";
    }
  }
}
if (!$success) { ?>
<form method="post">
  <label for="name">Name:</label>
  <input id="name" name="name" type="text" value="<?php
echo htmlspecialchars($name, ENT_HTML5 | ENT_QUOTES);
?>">
  <label for="email">E-mail address:</label>
  <input id="email" name="email" type="email" value="<?php
echo htmlspecialchars($email, ENT_HTML5 | ENT_QUOTES);
?>">
  <label for="message">Message:</label>
  <textarea id="message" name="message"><?php
echo htmlspecialchars($message, ENT_HTML5);
?></textarea>
  <input type="submit" value="Send">
</form>
<?php
}
if (!empty($status_message)) {
  echo "<p>{$status_message}</p>";
}
?>