Super Simple Local PHP Twig Setup

Published
Categories

I am working on some twig stuff and needed a way to test out sharing components between projects, so I wanted to set up a quick PHP site that can use twig templates without messing with any frameworks or complicated server setups. It turns out that PHP already routes stuff pretty well with its local server option:

URI requests are served from the current working directory where PHP was started, unless the -t option is used to specify an explicit document root. If a URI request does not specify a file, then either index.php or index.html in the given directory are returned. If neither file exists, the lookup for index.php and index.html will be continued in the parent directory and so on until one is found or the document root has been reached. If an index.php or index.html is found, it is returned and $_SERVER[‘PATH_INFO’] is set to the trailing part of the URI.

PHP: Built-in web server – Manual

So I just set up a subdirectory in my project that acts as the “public root” called site/ that contains just index.php. From there, we just need to use composer to require twig, require composer’s autoload, and set up a simple lookup to check for existing twig files. A couple other notes:

  • I start the PHP server from the project root with -t site/ to ensure that composer’s vendor files are not accessible.
  • I set up a simple data.json in the project root that acts as an external data source that I can pass to my twig files when they render
<?php

// constant to access root project directory
define('BASE_DIR', __DIR__ . '/..' );

// set up composer
require_once( BASE_DIR . '/vendor/autoload.php' );

// twig templating
$loader = new \Twig\Loader\FilesystemLoader(BASE_DIR . '/templates');

$twig = new \Twig\Environment($loader, [
	'cache' => false,
]);

// simple router
$template_name = 'index.twig';

if ( array_key_exists( 'PATH_INFO', $_SERVER ) ) {
	$request_file = rtrim($_SERVER['PATH_INFO'], '/') . '.twig';
	$error_template = '404.twig';

	if ( file_exists( BASE_DIR . '/templates/' . $request_file ) ) {
		$template_name = $request_file;
	} elseif ( file_exists( BASE_DIR . '/templates/' . $error_template ) ) {
		$template_name = $error_template;
	}
}

// example external data for templates
$data = file_exists( BASE_DIR . '/data.json' ) ? json_decode( file_get_contents( BASE_DIR . '/data.json' ), true ) : false;

// render page
$html = $twig->render($template_name, $data);

echo $html;

Code language: PHP (php)