Static site generator for Gulp ecosystem.
- A single build system is enough for static site development. I already have Gulp. I don’t want to work hard for making full-featured-standalone-static-site-generator to work well with Gulp/Npm/Node. Or to compile, minify, and optimize many different kinds of files properly in their way, while Gulp does everything well.
Making user-friendly presentation (HTML and pertty permalinks) from developer-friendly expression (eg. JSON, YAML, or Markdown and pretty filenames) is the one thing to do well for gulp-minisite. - To start small and expand flexibly, gulp-minisite keeps it simple, works without complex configutations, and provides some handy options and features.
- transform source files into HTML using template engine.
- compose useful data and you can use it in a template file.
- build clean permalink structure.
- compile any file into CSS or JavaScript. Do it with Gulp and your favorite compiler.
- minify or optimize any kind of files. Do it with Gulp and your favorite minifier or optimizer.
- watch file changes. Do it with
gulp.watch()
. - run a local webserver. Do it with gulp-webserver.
- force you to use specific template engine. (Nunjucks by default, but you can change it)
- provide flexible permalink configurations like that. Just put files and follow the convensions.
- generate dynamic pages like paginated indexes. Traverse files and generate “dynamic“ pages manually before executing gulp-minisite tasks. (But considering some sort of helpers)
- behave like a blog engine. It’s made for a general website (including a blog).
- have any theme.
$ npm install gulp-minisite --save-dev
Directory structure:
.
├── src
| └── index.html
├── gulpfile.js
└── package.json
src/index.html
:
<h1>Hello</h1>
<p>Hello World</p>
gulpfile.js
:
var gulp = require('gulp');
var minisite = require('gulp-minisite');
gulp.task('minisite', function() {
return gulp.src('src/**/*')
.pipe(minisite())
.pipe(gulp.dest('dest'));
});
...
├── dest
| └── index.html
...
dest/index.html
:
<h1>Hello</h1>
<p>Hello World</p>
Just copied index.html
. This is still useless.
Add template:
.
├── src
| └── index.html
├── template <- added
| └── home.html <- added
...
template/home.html
:
<h1>{{ page.title }}</h1>
<p>{{ page.description }}</p>
By default, you can use Nunjucks template engine. See the document for further information.
Rename src/index.html
to src/index.yml
and modify content:
.
├── src
| └── index.yml <- rename and modify
...
src/index.yml
:
template: home.html
title: Hello
description: Hello World
Specify template name by template
attribute.
dest/index.html
:
<h1>Hello</h1>
<p>Hello World</p>
Use Markdown with YAML front-matter
.
├── src
| └── index.md <- renamed
...
src/index.md
:
---
template: home.html
title: Hello
---
Hello World with **Markdown** syntax.
Update template/home.html
:
<h1>{{ page.title }}</h1>
{{ page.body | markdown }}
dest/index.html
:
<h1>Hello</h1>
<p>
Hello World with <strong>Markdown</strong> syntax.
</p>
Add document and template:
.
├── src
| ├── index.md
| └── about.yml <- added
├── template
| ├── home.html
| └── about.html <- added
...
src/about.yml
:
template: about.html
title: About
description: [Contact me](mailto:[email protected])
template/about.html
:
<h2>{{ page.title }}</h2>
<p>{{ page.description | markdown }}</p>
...
├── dest
| ├── index.html
| └── about
| └── index.html
...
dest/about/index.html
:
<h2>About</h2>
<p><a href="mailto:[email protected]">Contact me</a></p>
Add some files:
.
├── src
| ├── index.md
| ├── about.yml
| └── product <- added
| ├── index.yml <- added
| ├── salt.yml <- added
| ├── pepper.yml <- added
| └── sugar.yml <- added
├── template
| ├── home.html
| ├── about.html
| ├── product-index.html <- added
| ├── product-detail.html <- added
...
src/product/index.yml
:
template: product-index.html
title: Products
src/product/salt.yml
:
template: product-detail.html
title: Salt
description: This is salty.
template/product-index.html
:
{% for product in page.collection %}
<li><a href="{{ product.path }}">{{ product.title }}</a></li>
{% endfor %}
template/product-detail.html
<h2>{{ page.title }}</h2>
<p>{{ page.description }}</p>
...
├── dest
| ├── index.html
| ├── about
| | └── index.html
| └── product
| ├── index.html
| ├── salt
| | └── index.html
| ├── pepper
| | └── index.html
| └── sugar
| └── index.html
...
dest/product/index.html
:
<li><a href="/product/pepper">Pepper</a></li>
<li><a href="/product/salt">Salt</a></li>
<li><a href="/product/sugar">Sugar</a></li>
dest/product/salt/index.html
:
<h2>Salt</h2>
<p>This is salty.</p>
Products are sorted by filename.
Rename product files:
...
| └── product
| ├── index.yml
| ├── #01.salt.yml <- renamed
| ├── #02.pepper.yml <- renamed
| └── #03.sugar.yml <- renamed
...
dest/product/index.html
:
<li><a href="/product/salt">Salt</a></li>
<li><a href="/product/pepper">Pepper</a></li>
<li><a href="/product/sugar">Sugar</a></li>
Order part of filename is stripped from output.
Add site
option in gulpfile.js
:
...
gulp.task('minisite', function() {
return gulp.src('src/**/*')
.pipe(minisite({
site: {name: 'Hello Website'}
}))
.pipe(gulp.dest('dest'));
});
Prepend title tag to all template files:
{% if page.path === '/' %}
<title>{{ site.name }}</title>
{% else %}
<title>{{ page.title }} - {{ site.name }}</title>
{% endif %}
...
dest/index.html
:
<title>Hello Website</title>
...
dest/about/index.html
:
<title>About - Hello Website</title>
...
Suffix language name:
.
├── src
| ├── index.md
| ├── index.ja.md <- added
| ├── about.html
| ├── about.ja.html <- added
| └── product
| ├── index.yml
| ├── index.ja.yml <- added
| ├── #01.salt.yml
| ├── #01.salt.ja.yml <- added
| ├── #02.pepper.yml
| ├── #02.pepper.ja.yml <- added
| ├── #03.sugar.yml
| └── #03.sugar.ja.yml <- added
...
src/index.ja.md
:
---
template: home.html
title: こんにちは
---
こんにちは、世界
Specify locales
and defaultLocale
in gulpfile.js
:
...
gulp.task('minisite', function() {
return gulp.src('src/**/*')
.pipe(minisite({
site: {name: 'Hello Website'},
locales: ['en', 'ja'],
defaultLocale: 'en',
}))
.pipe(gulp.dest('dest'));
});
...
├── dest
| ├── index.html
| ├── about
| | └── index.html
| ├── product
| | ├── index.html
| | ├── salt
| | | └── index.html
| | ├── pepper
| | | └── index.html
| | └── sugar
| | └── index.html
| └── ja
| ├── index.html
| ├── about
| | └── index.html
| └── product
| ├── index.html
| ├── salt
| | └── index.html
| ├── pepper
| | └── index.html
| └── sugar
| └── index.html
...
dest/index.html
:
...
<h1>こんにちは</h1>
<p>こんにちは、世界</p>
Start filename with _
:
.
├── src
| ├── _contact.html <- added
...
gulpfile.js
:
...
var gutil = require('gulp-util');
...
gulp.task('minisite', function() {
return gulp.src('src/**/*')
.pipe(minisite({
site: {name: 'Hello Website'},
locales: ['en', 'ja'],
defaultLocale: 'en',
draft: !gutil.env.production,
}))
.pipe(gulp.dest('dest'));
});
With $ gulp minisite
:
...
├── dest
| ├── contact
| | └── index.html
...
But with $ gulp minisite --production
, dest/contact/index.html
won’t be generated.
...
├── src
| ├── img <- added
| | ├── logo.png <- added
| | ├── logo.ja.png <- added
| | ├── [email protected] <- added
| | └── [email protected] <- added
...
...
├── dest
| ├── img
| | ├── logo.png
| | └── [email protected]
...
| └── ja
| ├── img
| | ├── logo.png
| | └── [email protected]
...
If your files aren’t document, gulp-minisite just relocate and copies them.
gulp-minisite does nothing for that. Just proceed them as you like.
...
├── style
| └── main.scss
├── script
| └── main.coffee
...
gulpfile.js
:
...
var sass = require('gulp-sass');
var coffee = require('gulp-coffee');
...
gulp.task('css', function() {
return gulp.src('style/**/*')
.pipe(sass())
.pipe(gulp.dest('dest/css'));
});
gulp.task('js', function() {
return gulp.src('script/**/*')
.pipe(coffee())
.pipe(gulp.dest('dest/js'));
});
...
- Type:
Array
ofString
- Default:
null
Acceptable locale names.
- Type:
String
- Default:
null
If defaultLocale
specified, any file without locale part in filename will be assigned that locale.
- Type:
Object
- Default:
null
Site-global variable. You can refer the object in template files like {{ site.name }}
.
- Type:
Function
- Default: Nunjucks template engine
Template engine’s render function. The function should receive template name (actually, template
value of document) and data, and return rendered string.
To use jade:
...
templateEngine: function(tmplName, tmplData) {
var jade = require('jade');
var path = require('path');
var tmplDir = 'jade';
return jade.renderFile(path.join(tmplDir, tmplName), tmplData);
},
...
- Type:
Boolean
- Default:
false
If true
, draft files (their filename starts with _
) will be proceeded.
- Type:
Array
ofString
- Default:
['yml', 'yaml', 'json']
File extensions that are treated as documents. If you want YAML/JSON files not to turn out to be HTML, pass []
or null
.
MIT