ilmiont/ardea

Ardea is a minimal static site generator using PHP.

1.1.2 2022-06-10 19:30 UTC

This package is auto-updated.

Last update: 2024-05-10 23:52:20 UTC


README

Ardea is a minimal static site generator using PHP. It focuses on the essentials of loading and rendering your site's pages and content. An extendable foundation lets you add custom content discovery mechanisms and template renderers.

Usage

Install Ardea in your project using Composer:

$ composer require ilmiont/ardea

Create an ardea.json file in your working directory:

{
	"content": {
		"pages": {
			"template": "tpl/page.php",
			"items": [
				{
					"uri": "/index.html",
					"title": "Home",
					"body": "Welcome to my website."
				},
				{
					"uri": "/about.html",
					"title": "About Me",
					"body": "I'm a developer."
				},
				{
					"uri": "/contact.html",
					"title": "Contact Me",
					"body": "You can contact me by email."
				}
			]
		}
	}
}

Next create a tpl/page.php file, again inside your working directory:

<!DOCTYPE html>

<html>
	<head>
		<meta charset="utf-8">
		<title><?= $i -> prop("title"); ?></title>
	</head>
	<body>
		<h1><?= $i -> prop("title"); ?></h1>
		<p><?= $i -> prop("body"); ?></p>
	</body>
</html>

Now you can run Ardea to render your site:

$ vendor/bin/ardea

Your pages will be rendered into build within your working directory:

$ ls build
about.html  contact.html  index.html

That's it! This example demonstrates the basics of using Ardea.

Getting Started

Ardea is configured using an ardea.json file in your working directory. Within this file, the content property is the most important, as it defines the content items that Ardea will render to create your site.

Each property nested inside content defines a "content type." Content items within a content type are logically grouped together and rendered with the same template.

The template to use for a content type is defined by the template property within its definition object. The property's value should be the relative path to a PHP file within your working directory.

When a content type omits the template property, the default template set in your configuration file will be used instead. See the Configuration section below for more information.

Content items can be added to a content type in several ways. In the example above, content items are defined as static objects within the content type's items array. Each object is rendered individually and saved to the path given by its uri property, which is resolved relative to the active output directory.

Static Content Items

Content items can be added to a content type as static objects by defining an items property on the content type as an array of content objects. Each content object needs a uri property that defines the path to save that content item's rendered output to, relative to the active output directory.

All other properties of each content item object become item props which are accessible in your template.

An example of static content items is included in the Usage section above.

Markdown Content Items

Ardea has built-in support for rendering on-disk Markdown files. Each Markdown file's name must end with .md and the file must exhibit a valid Markdown MIME type.

To add Markdown-sourced items to a content type, provide a markdown property in its configuration object. Supply the path to load the Markdown content items from as the property's value. The path is resolved relative to your working directory.

{
	"content": {
		"posts": {
			"template": "tpl/post.php",
			"markdown": "content/blog"
		}
	}
}

The directory will be recursively searched for valid Markdown files. Each found file will be rendered using the specified template and output to the path it was discovered at, relative to the output directory. For example, using the example configuration above, the Markdown file content/blog/demo-post.md will be output to content/blog/demo-post.html within the output directory. You can change the output path URI for a specific Markdown file by supplying a uri property in its front matter.

The Markdown content loader provides the following template props for each rendered file:

PropertyTypeDescription
fileStringThe relative path to the file, within the searched directory root (e.g. 2022/05/01/demo-post.md).
filenameStringThe name of the file (e.g. demo-post.md).
htmlStringThe Markdown file's content, rendered to HTML.
markdownStringThe Markdown file's content.
srcStringThe complete relative path to the file, relative to the working directory (e.g. content/blog/2022/05/01/demo-post.md).
titleStringThe assumed title of the content; this is the first line of the Markdown content, stripped of any tags.

The Markdown content loader is front matter-aware. Any front matter will be stripped from the markdown and html props. Front matter is extracted and made available as key/value props in your template; where a front matter key is the same as one of the properties listed above, the value from the front matter will overwrite that supplied by Ardea.

Ardea uses Parsedown to render Markdown files. You can provide a custom Parsedown instance by manually constructing the MarkdownContentLoader instance:

use Ardea\MarkdownContentLoader;
use Parsedown;

$markdownLoader = new MarkdownContentLoader(new Parsedown());

Refer to the Writing Extensions section of this guide below for details of how to supply Ardea with your customised content loader instance.

Templates

Ardea defaults to using plain PHP templates which are rendered by the included PhpRenderer. You can implement your own renderers using the guidance in the Writing Extensions section of this guide below.

When using the default PhpRenderer, you can access the following variables in your templates:

VariableTypeDescription
$iArdea\ContentItemThe content item that's being rendered.
$itemArdea\ContentAggregate of the content item that's being rendered and its content type.
$contentArdea\ContentCollectionAll of the content items that are being rendered.
$ardea / $config / $propsArdea\PropStoreThe content of your ardea.json file.
$tplStringThe path to the template that the content item's being rendered with.
$dstStringThe path that the content item's rendered output will be saved to.
$thisArdea\PhpRendererThe active renderer instance.

Refer to the API Reference below for details of the methods available on the content, content collection, and config prop store objects. You'll use these ubiquitously to access your active configuration values and content item properties.

Example: Rendering a list of Markdown-sourced blog posts, ordered by their date front matter property

ardea.json

{
	"content": {
		"posts": {
			"template": "tpl/post.php",
			"markdown": "content/blog"
		}
	}
}

tpl/post.php

// ...
<?php foreach ($content -> getByContentType("posts") -> sortByContentProp("date") as $post): ?>
	<li><a href="<?= $post -> ContentItem -> uri(); ?>"><?= $post -> ContentItem -> prop("title"); ></a></li>
<?php endforeach; ?>
// ...

Example: Accessing a custom configuration property

ardea.json

{
	"site": {
		"theme": {
			"palette": {
				"accent": "##bbddff"
			}
		}
	},
	"content": {
		"pages": {
			"template": "tpl/page.php",
			"items": [
				{
					"uri": "/index.html"
				}
			]
		}
	}
}

tpl/page.php

// ...
<head>
	<meta name="theme-color" content="<?= $props -> prop("site.theme.palette.accent"); ?>">
</head>
// ...

Configuration

All configuration properties are set in your ardea.json file within the ardea property:

{
	"ardea": {
		"template": "tpl/page.php",
		"outputDir": "build",
		"workDir": "/tmp/my-site"
	}
}
PropertyTypeDescriptionDefault Value
ardea.templateStringThe path to the template file to render content items with, when their content type doesn't define one (relative to the working directory).-
ardea.outputDirStringThe path to output rendered content to, relative to the working directory.build
ardea.workDirStringPath to interpret the working directory as. Only reliable within the Ardea core - content loaders and renderers, including built-in ones, may not currently support it and may use your real working directory instead.A call to PHP's getcwd() function.

API Reference

It's recommended you currently refer to the source code to obtain a complete API reference. Inspecting the Content, ContentCollection, ContentItem, ContentItemCollection, ContentType, ContentTypeCollection, ContentTypeDefinition, HasProps, and PropStore objects will inform you how to access content and configuration values within your templates.

When writing extensions, refer primarily to the application entrypoint (ardea at the root of the repository), and the PropStore, ContentLoader, and Renderer interfaces.

Writing Extensions

Ardea can be extended with new content loaders and renderers.

To write and use your own extensions, create your own entrypoint that constructs an instance of Ardea\Ardea. The signature is as follows:

namespace Ardea;

final class Ardea {

	public function __construct(
		protected readonly PropStore $Config,
		protected readonly ContentLoaderCollection $ContentLoaders,
		protected readonly Renderer $Renderer) {}

}
  • $Config - This PropStore instance provides Ardea with its configuration values (i.e. ardea.json content by default).
  • $ContentLoaders - The ContentLoader instances provided here will be used to discover the content to render within each of your content types.
  • Renderer - This Renderer instance is used by Ardea to render all your content items.

Refer to the standard application entrypoint, ardea at the root of the repository, for an example of how Ardea's default content loaders and renderer are configured.

Writing a Content Loader

Content loaders add content items to your content types. Ardea ships with support for inline statically defined content items and content items sourced from on-disk Markdown files.

To create a new content loader, implement the ContentLoader interface and provide an instance as a member in the $ContentLoaders collection when you construct Ardea.

Renderers

Renderers convert a content item to rendered output. Ardea ships with a default renderer that supports PHP template syntax.

To create a new renderer, implement the Renderer interface and provide an instance as the $Renderer parameter when you construct Ardea.

Customising the default renderer

The default PHP template renderer has two constructor parameters:

namespace Ardea;

final class PhpRenderer {

	public function __construct(

		/**
		 * Props to make available to templates
		 */
		protected readonly PropStore $Props,

		/**
		 * Writer instance that saves rendered output
		 */
		protected readonly Writer $Writer) {}

}

$Props is made available to your templates as the $ardea, $config, and $props variables.

The Writer instance supplied as $Writer is responsible for writing rendered templates to the intended output path. The default writer saves to the local filesystem. You can create your own writers by implementing the Writer interface.

©James Walker. Licensed under the MIT License.