Alternator⚡
A CLI tool for building static websites on your Mac. Layouts, includes, and variables in HTML, CSS, and JS. Markdown built-in. Localhost server optional.
⤓ Download v2.2.0
/website $ alternator --help
USAGE: alternator <source> <target> [--watch] [--port <port>]
ARGUMENTS:
<source> Path to your source directory.
<target> Path to your target directory.
OPTIONS:
-w, --watch Rebiuld <source> as you save changes.
-p, --port <port> Serve <target> on localhost:<port>.
--version Show the version.
-h, --help Show help information.
Getting Started
Alternator reads the files in your <source>
directory, fills in the layouts, includes, and variables, then saves the rendered files to your <target>
directory for publishing.
/website $ alternator path/to/source path/to/target
Layouts, includes, and variables are defined in <source>
files using comments and metadata. More on that later.
Watching for Changes
Use the --watch
flag to monitor <source>
for changes and automatically render after each save.
/website $ alternator path/to/source path/to/target --watch
[watch] watching path/to/source for changes
^c to stop
Localhost Server
Add a --port
to serve <target>
on a localhost server.
/website $ alternator path/to/source path/to/target --port 8080
[serve] serving path/to/target at http://localhost:8080
^c to stop
Putting It Together
Combine --watch
and --port
for a simple dev setup.
/website $ alternator path/to/source path/to/target -wp 8080
[watch] watching path/to/source for changes
[serve] serving path/to/target at http://localhost:8080
^c to stop
Layouts
Any file can be used as a layout by adding a @content
comment to specify where its contents should be rendered.
path/to/source/.layouts/main.html
<!doctype html>
<html>
<head>
<title>Alternator</title>
</head>
<body>
<!-- @content -->
</body>
</html>
The @layout
metadata key defines which layout a file should use. The layout file path is relative to <source>
.
path/to/source/index.html
---
@layout: .layouts/main.html
---
<h1>Welcome</h1>
<p>Hello, world!</p>
Alternator will render a file inside its layout.
path/to/target/index.html
<!doctype html>
<html>
<head>
<title>Alternator</title>
</head>
<body>
<h1>Welcome</h1>
<p>Hello, world!</p>
</body>
</html>
Includes
Files can include other files using an @include
comment. The included file path is relative to <source>
.
path/to/source/app.js
// @include .scripts/foo.js
// @include .scripts/bar.js
path/to/source/.scripts/foo.js
function foo() {
console.log("hello")
}
path/to/source/.scripts/bar.js
function bar() {
console.log("world")
}
Alternator will render included files in place.
path/to/target/app.js
function foo() {
console.log("hello")
}
function bar() {
console.log("world")
}
Variables
Variables are defined with @
arguments on includes.
path/to/source/design.css
/* @include .styles/fontFace.css @fontName: Helvetica */
And referenced in comments.
path/to/source/.styles/fontFace.css
@font-face {
font-family: /* @fontName */;
src: url("/fonts//* @fontName */.woff2");
}
Alternator will render variables in place.
path/to/target/design.css
@font-face {
font-family: Helvetica;
src: url("/fonts/Helvetica.woff2");
}
Pro Tips
Structuring Your Site
Alternator has no directory structure requirements so you can organize <source>
however you like.
The structure of <source>
will be copied to <target>
.
The structure of <target>
becomes published URLs.
Keeping <target>
Clean
Removing a <source>
file also deletes its <target>
.
Ignoring Dotfiles
Use a .
at the beginning of a file or directory name to tell Alternator to ignore it, both in <source>
and <target>
.
<source>
dotfiles won’t be moved to <target>
.
<target>
dotfiles won’t be cleaned and will be published.
This leaves config files such as .env
and .git/
untouched.
Use this feature to keep <source>
layouts and includes from being moved to <target>
and prevent assets in <target>
from being cleaned up.
Using Markdown
Markdown files (.md
) are automatically converted to HTML and copied to <target>
as .html
files.
Multiple Include Arguments
@include
statements can have multiple arguments, formatted as @key: value
and separated by spaces:
// @include sample.js @foo: true @bar: false
Fallback Variable Values
Define fallback values for variables with the ??
operator:
<!-- @foo ?? bar -->
Layout Your Includes
Included files can have their own layouts, either defined in their metadata or as an argument passed with the @include
statement:
<!-- @include .posts/post.md @layout: .postLayout.html -->
Bypass an included file’s layout with @layout: false
.
Managing Static Assets
Files that can’t be rendered, such as images, are considered static assets and copied as-is from <source>
to <target>
.
Put static assets directly in <target>
under a .
directory like .assets/
or .images/
to avoid excess copies.
Clean URLs
The localhost server supports clean urls.
For example, <target>/foo.html
is available at localhost:8080/foo
so you don’t have to clutter your project with extra directories and index files.
Not all production servers support this.
Displaying a 404 Not Found Page
If the localhost server cannot find a requested file, it will return the 404 Not Found HTTP response status code.
If <target>/404.html
exists, it will be returned for any not found HTML requests.
No response body will be returned for non-HTML requests.
Not all production servers support this.
Publishing Your Site
Sites can be published to any host that serves static files.
This site is hosted on GitHub using /docs as the <target>
.
Check your web host’s documentation for specifics.