The framework uses a simple file-based theme system. Each theme is a folder inside themes/ containing a set of PHP files that control the site's HTML structure and page layouts. The active theme is set by the $theme variable in config/config.php.
The repository ships with one theme: themes/skeleton/. This is intended as your starting point — clone it, rename the folder, point $theme at it, and customise from there.
Theme File Structure
A complete theme folder contains the following files:
themes/your-theme/
├── header.php # <head>, navigation, hero banner — opened but not closed
├── footer.php # Closing tags, footer columns, below-content scripts
├── navigation.php # The rendered navigation bar HTML
├── navigation-options.php # StellarNav JavaScript initialisation
├── navigation.css # Navigation bar styles
├── custom.css # Your theme's main stylesheet
├── page-md.php # Layout: Markdown page with title
├── page-md-notitle.php # Layout: Markdown page without title
├── page-html.php # Layout: HTML page with title
├── page-html-notitle.php # Layout: HTML page without title
├── postarchives.php # Layout: Post archive/listing page
├── postarchives-styled.php # Layout: Styled post archive variant
└── postarchives-notitle.php # Layout: Post archive without title
How a Page is Assembled
When a request comes in, index.php determines the page name, extracts metadata from the page file, then hands off to the theme's header.php. The header file is responsible for pulling in everything else via PHP includes. The overall assembly order is:
themes/[theme]/header.php— outputs, loads CSS and plugins, renders the nav bar and hero, then includes the layout file based on$pagelayout- The layout file (e.g.
page-md.php) — reads the page content file frompages/, processes shortcodes, renders Markdown (if applicable), and outputs the content themes/[theme]/footer.php— outputs footer columns, flushes$pluginCalledBelowContent, includesnavigation-options.php, and closes
Available Variables in Theme Files
The following PHP variables are available inside all theme files:
| Variable | Type | Description |
|---|---|---|
$pagename |
string | The URL slug of the current page (e.g. documentation/introduction) |
$pagetitle |
string | From page metadata. Falls back to ucwords($pagename) if not set |
$pagelayout |
string | The layout filename to use (without .php) |
$pagedate |
string | Publication date, normalised to Y-m-d H:i:s. Falls back to file modification time |
$pageimage |
string | Relative path to the page image. Falls back to $WebsiteImage |
$pageexcerpt |
string | Short description. Falls back to $WebsiteDescription |
$pagekeywords |
string | SEO keywords. Falls back to $WebsiteKeywords |
$pageauthor |
string | Author name. Falls back to $WebsiteAuthor |
$pagetype |
string | OpenGraph type (e.g. article, website). Falls back to "website" |
$WebsiteTitle |
string | From config |
$WebsiteURL |
string | Full canonical URL (protocol + domain) |
$currentURL |
string | Full URL of the current request |
$theme |
string | Active theme name |
$showhomepagetitle |
bool | Whether to show title on home page |
$pluginCalledBelowContent |
string | Accumulated plugin scripts, flushed in footer |
Page Layouts
The $pagelayout metadata value in each page file controls which layout PHP file is used to render the content. If pagelayout is not set, the framework defaults to page-md.
| Layout value | File | Behaviour |
|---|---|---|
page-md |
page-md.php |
Renders page content as Markdown, shows title |
page-md-notitle |
page-md-notitle.php |
Renders page content as Markdown, hides title |
page-html |
page-html.php |
Renders page content as raw HTML, shows title |
page-html-notitle |
page-html-notitle.php |
Renders page content as raw HTML, hides title |
postarchives |
postarchives.php |
Generates a paginated list of all posts |
postarchives-styled |
postarchives-styled.php |
Styled variant of the post archive |
postarchives-notitle |
postarchives-notitle.php |
Post archive without a page title |
You can add your own layout files to the theme folder and reference them by name in page metadata.
The Navigation File
Navigation is defined in pages/navigation.html as a standard Markdown unordered list. The navigation.php theme file reads this file, passes it through the Markdown parser, and outputs it inside a <div class="stellarnav"> wrapper which StellarNav then enhances.
Nested lists become dropdown menus. Use #0 as the href for parent items that should not be links themselves:
* Home
* [About](#0)
* [Team](/about/team)
* [History](/about/history)
* [Contact](/contact)
Nesting can go three levels deep. See the StellarNav page for configuration options.
Footer Columns
Footer content is driven by Markdown files in pages/footer/. Each file corresponds to one column. The number of columns is set by $numberFooterColumns in config.php. Files must be named footer1.html, footer2.html, etc.
Each footer file can optionally include a section title using an HTML comment at the top:
<!-- sectiontitle: About Us -->
Some footer content here.
Creating a New Theme
- Copy
themes/skeleton/to a new folder, e.g.themes/mytheme/ - Update
$theme = "mytheme";inconfig/config.php - Edit
custom.cssfor your styles and modify the PHP layout files as needed - The
required/files and core CSS (css/base.css,css/flexgridsystem.css,css/normalize.css) are shared across all themes and should not need to be duplicated
Keep the include calls in header.php intact — they load the plugin system, metadata, and navigation. The layout include (include $pagelayout . ".php") and the footer.php include at the bottom of header.php are also required for the framework to function.