npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

statiq

v0.7.4

Published

A static website generator

Downloads

5

Readme

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](http://www.google.com/)
[Wikipedia](http://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.