Skip to content

ezakto/statiq

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

statiq

A node.js static website generator

Install

$ npm install -g statiq

Basic usage:

Create a statiq website with the interactive cli tool:

$ statiq init

statiqinit

This will bootstrap the folder structure, statiqfile.js and package.json in the current directory. There are four directories: content, templates, assets and publish. By default, files in the assets folder will be copied as-is to the publish folder. Documents in the content folder will be merged into their corresponding templates from the templates folder and saved to the publish folder (mirroring content folder structure). For example, this structure:

content/index.md
content/about.md
content/docs/index.md

Will result in:

publish/index.html
publish/about.html
publish/docs/index.html

Content

By default, content is placed in .html files. If you added the markedPlugin, content is placed in markdown .md documents.

Sample index.md:

Welcome!
=======

This is a *test page*.

File variables

You can set context variables in each file, by placing a yaml/json object in its first lines, followed by a triple dash (---):

title: Index page
---

Welcome!
========
...

Templates

Default templating engine is ejs. An index.html template file could look like this:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title><%- title %></title>
</head>
<body>
    <div id="main">
        <%- content %>
    </div>
</body>
</html>

Context variables are available, and the special content variable contains the document itself.

Building

Finally, run:

$ statiq

And you're ready to go!

Advanced

Directory context

If files in a same folder share some metadata, you can put it in context files within the folder. For example, add a context.json or context.yaml file in a content/docs/ folder, like this:

subtitle: My documents
somedata: ...

Now, every document under content/docs/ (including sub-directories) will have those variables set at build time, unless they are overwritten by a deeper level context or in-file context.

Global context

Use the context property in the configuration object within the statiqfile.js:

statiq.config({
  ...
  context: {
    sitename: "My awesome website",
    ...
  }
})

This works just like putting a context file in the content/ root. However, by using the statiqfile, you may perform any data processing/manipulation and pass the result, or even pass functions (like moment.js, sorting methods, etc).

Directory indexes

In templates, you can iterate through files in a given folder using the special index[folder] variables. Given this structure:

content/index.md
content/articles/myarticle.md
content/articles/myarticle2.md
content/articles/myarticle3.md
content/articles/subarticles/subarticle.md
content/articles/subarticles/subarticle2.md

You can list the articles folder in your templates accesing index['articles'], and the subarticles folder with index['articles/subarticles'].

<h4>Articles:</h4>
<ul>
<% index['articles'].forEach(function(article){ %>
    <li><a href="<%= article.path %>"><%= article.title %></a></li>
<% }) %>
</ul>

Each index[folder] item is set to the context of that file plus a special path variable containing the relative path from the current file and a current variable which is true when the item is the same file accessing it.

Hidden documents

Files prefixed with _ will be processed but they won't be included in the index.

Command line tool

$ statiq

Look for nearest statiqfile.js and build website

$ statiq init

Create a new statiqfile and default folder structure

$ statiq init -s

Create a new statiqfile only

$ statiq add <filename>

Create a new website document/page/post

$ statiq add <filename> --<key>=<value> --<key>=<value>...

Create a new document and set local context values

$ statiq serve

Start a local server

$ statiq watch

Start a file watcher and rebuild website when changes occur

$ statiq serve -w

Start server and watcher

$ statiq help

Show help

Programmatic API

const statiq = require('statiq');
const site = statiq();

site.config({
  ...
});

site.run();

Methods

site.config(object config)

Sets site configuration just like a statiqfile. Default configuration is:

{
  contentPath: 'content',
  templatesPath: 'templates',
  publishPath: 'publish',
  assetsPath: 'assets',
  defaultTemplate: 'index.html',
  contentExtension: '.md',
  publishExtension: '.html',
  hiddenRegex: /^_/, // filenames that shouldn't be included in indexes
  plugins: [],
  context: {}, // global context
  cwd: process.cwd(), // if site is built using the cli tool, it's set to the statiqfile.js dir by default
}

Returns the config object.

site.use(fn plugin)

Adds a statiq plugin. Returns void.

site.create(string file, object context, string content?)

Creates a document file with local context and content. Returns a promise containing the document object.

Hooks: beforeCreate, afterCreate

site.read(string file)

Reads and cache a file in the content folder. Returns a promise containing the document object.

Hooks: beforeRead, afterRead

site.update(string file, object context, string content)

Updates the context and content of a cached document file. Returns a promise containing the document object.

Hooks: beforeUpdate, afterUpdate

site.build(string file)

Builds the cached document file. It'll use other cached documents and contexts to generate indexes. Returns a promise containing the built document object.

Hooks: beforeBuild, afterBuild

site.buildAll()

Convenience method to build all the cached documents.

site.write(string file)

Writes the cached built document file to the filesystem. Returns a promise containing the file path.

Hooks: beforeWrite, afterWrite

site.writeAll()

Convenience method to write all the cached built documents.

site.delete(string file)

Deletes the document file from the cache and the filesystem. Returns a promise containing void.

site.scan(string path?)

Deep-scans the content directory and reads its documents. Specify a path if you don't want to start from the content root. Returns a promise containing an array of read documents.

site.handleAssets()

Process the assets folder. By default, it'll just copy all files to the publish folder.

Hooks: beforeAsset, afterAsset

site.list()

Returns all the cached documents

site.run()

Convenience method to run scan(), buildAll() and writeAll(). Returns a promise containing an array of generated paths.

Plugins

Plugins can be loaded using the plugins array in the site configuration:

statiq.config({
    context: { ... }
    plugins: [myPlugin(), ejsPlugin(), markedPlugin()]
});

Or alternatively, loaded later using .use():

statiq.use(myPlugin());

A statiq plugin consists of a function that returns an object with a set of hook properties that will exec in a given step of the build process.

function myPlugin(options) {
    return {
        beforeBuild(document) {
            document.title = "Foo";
            return document;
        },
    }
}

These hooks are executed in the same order the plugins were loaded. When an before* hook returns a falsy value, it prevents its after* execution and also any other before* in the chain.

Plugins API

beforeCreate(object document)

Runs before a new document is written into the file system. The document object contains contentPath, context, content and source. Must return the document object (modified or not), a new document object, or falsy to cancel the document creation.

afterCreate(object document)

Runs after a new document has been written to the file system, and can be used to perform any side effects. Returns void.

beforeRead(object document)

Runs before a content file is read and cached. The document object contains contentPath, publishPath, and context (including global context). Must return the document object (modified or not), a new document object, or falsy to skip reading the document.

afterRead(object document)

Runs after a document has been read and cached, and can be used to perform any side effects. Returns void.

beforeUpdate(object document, object newContext, string newContent)

Runs before an update is made to a cached document. To access the current context or content of the document, you can use document.context and document.content. Must return the document object (modified or not), a new document object, or falsy to skip updating the document.

afterUpdate(object document)

Runs after a document has been updated in cache, and can be used to perform any side effects. Returns void.

beforeBuild(object document, string template)

Runs before a document is built in memory. Must return the document object (modified or not), a new document object, or falsy to skip building the document.

afterBuild(object document)

Runs after a document has been built in cache, and can be used to perform any side effects. Returns void.

beforeWrite(object document)

Runs before a cached document is written to the file system. Must return the document object (modified or not), a new document object, or falsy to skip writting the file.

afterWrite(object document)

Runs after a file has been written to the file system, and can be used to perform any side effects. Returns void.

beforeAsset(object assetDocument)

Runs when an asset file is found in the assets directory. assetDocument is an object containing assetPath and publishPath. Must return the asset object (modified or not), a new object or falsy to skip processing this asset.

afterAsset(object assetDocument)

Runs after an asset has been processed, and can be used to perform any side effects. Returns void.

Included plugins

These plugins are shipped with statiq and can be imported from statiq/plugins.

markedPlugin

Lets you write documents content in markdown. Requires marked.

Usage
const { markedPlugin } = require('statiq/plugins');

statiq.use(markedPlugin(options))
Options

parseMultilineContext (boolean) Process context variables containing a multiline string. Defaults to true.

ejsPlugin

Lets you write templates using ejs. Requires ejs.

Usage
const { ejsPlugin } = require('statiq/plugins');

statiq.use(ejsPlugin())

lessPlugin

Converts .less files in the assets folder into .css files at build time. Requires less.

Usage
const { lessPlugin } = require('statiq/plugins');

statiq.use(lessPlugin(options))
Options

main (string) Optional. Copy only this filename to the publish folder.

The options object is passed as options to less' render method.

blocksPlugin

Lets you define content blocks in documents. Consider a multicolumn layout like this:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title><%= title %></title>
</head>
<body>
    <div class="left-column">
        <%- left %>
    </div>
    <div class="main">
        <%- content %>
    </div>
    <div class="right-column">
        <%- right %>
    </div>
</body>
</html>

Instead of using the content variable, you can define block sections just like this:

title: Multi column
---

<<left
Welcome!
========

Lorem ipsum dolor sit amet blah blah.
left;

<<right
### Useful links
[Google](https://www.google.com/)
[Wikipedia](https://www.wikipedia.org/)
right;

This is the main content.

These are Heredoc-ish declaration. Blocks start with <<BLOCK_NAME and end with BLOCK_NAME; (both in their own lines). Block names are case-sensitive alphanumeric strings. Their content is removed from the content variable.

About

A node.js static website generator

Resources

License

Stars

Watchers

Forks

Packages

No packages published