-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ce88460
commit 8f4ac65
Showing
10 changed files
with
2,896 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# Logs | ||
logs | ||
*.log | ||
npm-debug.log* | ||
|
||
# Runtime data | ||
pids | ||
*.pid | ||
*.seed | ||
.tmp | ||
|
||
# Directory for instrumented libs generated by jscoverage/JSCover | ||
lib-cov | ||
|
||
# Coverage directory used by tools like istanbul | ||
coverage | ||
|
||
# nyc test coverage | ||
.nyc_output | ||
|
||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) | ||
.grunt | ||
|
||
# node-waf configuration | ||
.lock-wscript | ||
|
||
# Compiled binary addons (http://nodejs.org/api/addons.html) | ||
build/Release | ||
|
||
# Dependency directories | ||
node_modules | ||
.env | ||
jspm_packages | ||
|
||
# Optional npm cache directory | ||
.npm | ||
|
||
# Optional REPL history | ||
.node_repl_history | ||
|
||
|
||
# SASS | ||
.sass-cache |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>{{title}}</title> | ||
<link rel="stylesheet" href="https://unpkg.com/picnic"> | ||
<link rel="stylesheet" href="/style.min.css"> | ||
</head> | ||
<body> | ||
<em>Rendered with Handlebars</em> | ||
{{{body}}}{{{content}}} | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>{{title}}</title> | ||
<link rel="stylesheet" href="https://unpkg.com/picnic"> | ||
<link rel="stylesheet" href="/style.min.css"> | ||
</head> | ||
<body> | ||
<em>Rendered with Liquid!</em> | ||
{{ body }}{{ content }} | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Hello world!</title> | ||
<link rel="stylesheet" href="https://unpkg.com/picnic"> | ||
<link rel="stylesheet" href="/style.min.css"> | ||
</head> | ||
<body> | ||
<em>Rendered with Liquid!</em> | ||
<h1 id="create-static-web">Create-Static-Web</h1> | ||
<p>Another static site generator:</p> | ||
<pre><code class="language-bash">$ npm install create-static-web -g | ||
$ web</code></pre> | ||
<table> | ||
<thead> | ||
<tr> | ||
<th>Transformations</th> | ||
<th>Features</th> | ||
</tr> | ||
</thead> | ||
<tbody><tr> | ||
<td><code>.liquid</code> <code>.hbs</code> → <code>.html</code></td> | ||
<td>• Works out of the box</td> | ||
</tr> | ||
<tr> | ||
<td><code>.md</code> + <code>layout:</code> → <code>.html</code></td> | ||
<td>• Livereload</td> | ||
</tr> | ||
<tr> | ||
<td><code>.scss</code> <code>.sass</code> → <code>.min.css</code></td> | ||
<td>• Extensible with hooks [WIP]</td> | ||
</tr> | ||
<tr> | ||
<td><code>.src.js</code> → <code>.min.js</code> [WIP]</td> | ||
<td>• Basic compatibility with Jekyll</td> | ||
</tr> | ||
</tbody></table> | ||
<h2 id="getting-started">Getting Started</h2> | ||
<p>Create your <code>readme.md</code>:</p> | ||
<pre><code class="language-md">--- | ||
layout: hello.hbs | ||
--- | ||
|
||
Front-matter enabled website</code></pre> | ||
<p>Also your <code>_hello.hbs</code> file:</p> | ||
<pre><code class="language-js"><p>{{ content }}</p></code></pre> | ||
<p>Voila! Your site should be ready to go:</p> | ||
<pre><code class="language-html"><p>Front-matter enabled website</p></code></pre> | ||
<h2 id="demo">Demo</h2> | ||
<p>Clone this repo and run web:</p> | ||
<pre><code class="language-bash">$ git clone | ||
</code></pre> | ||
<h2 id="automatic-compilation">Automatic compilation</h2> | ||
<p>The command <code>web</code> will automatically compile some extensions (explained below). <strong>Except</strong> if they also start by an underscore. Then they will be considered partials and not be rendered by default.</p> | ||
<h3 id="liquid-template">Liquid template</h3> | ||
<p>These will be rendered (excluding <a href="#partials">Partials</a>) into a file with the same name and the extension <code>html</code>:</p> | ||
<ul> | ||
<li><code>./index.liquid</code> → <code>./index.html</code></li> | ||
<li><code>./demo.liquid</code> → <code>./demo.html</code></li> | ||
<li><code>./blog/index.liquid</code> → <code>./blog/index.html</code></li> | ||
</ul> | ||
<p>They will receive the data as specified in the <a href="#data-specification">Data Specification</a>:</p> | ||
<pre><code class="language-html">// index.liquid | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>{{title}}</title> | ||
... | ||
</head> | ||
... | ||
</html></code></pre> | ||
<h3 id="sass-and-scss">SASS and SCSS</h3> | ||
<p>The style files (excluding <a href="#partials">Partials</a>) will be compiled to a file with the same name in the same folder, with the extension <code>.min.css</code>:</p> | ||
<ul> | ||
<li><code>./style.scss</code> → <code>./style.min.css</code></li> | ||
<li><code>./demo.scss</code> → <code>./demo.min.css</code></li> | ||
<li><code>./blog/style.scss</code> → <code>./blog/style.min.css</code></li> | ||
</ul> | ||
<p>Then you have to include it in your template as normal:</p> | ||
<pre><code class="language-hbs">// index.hbs | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
... | ||
<link rel="stylesheet" href="/style.min.css"> | ||
</head> | ||
... | ||
</html></code></pre> | ||
<p>Files ending with these extensions will be automatically compiled:</p> | ||
<p><code>.liquid</code>, <code>.hbs</code>, <code>.sass</code>, <code>.scss</code></p> | ||
<p>They are compiled to the same folder with the same filename. SASS and SCSS will add a <code>.min</code> to the extension to differentiate in case you have any <code>.css</code>.</p> | ||
<h2 id="partials">Partials</h2> | ||
<p>Partials are useful in two situation: as layouts and to be included in another files.</p> | ||
<h2 id="data-specification">Data Specification</h2> | ||
<blockquote> | ||
<p>Work in Progress</p> | ||
</blockquote> | ||
<p>Any <code>.json</code> found in the filesystem will be parsed and its value will be set into a variable with the same name as the filename:</p> | ||
<p>For example, for the filename <code>info.json</code>:</p> | ||
<pre><code class="language-json">{ "title": "My Cool Website" }</code></pre> | ||
<p>You can access this variable within your templates as:</p> | ||
<pre><code class="language-html"><!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>{{info.title}}</title> | ||
... | ||
</head> | ||
... | ||
</html></code></pre> | ||
<h3 id="front-matter">Front Matter</h3> | ||
<p>There is a special variable called <code>content</code> (aliased as <code>body</code>) which represents the Markdown content as html into your template:</p> | ||
<pre><code class="language-html">// index.liquid | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>{{title}}</title> | ||
... | ||
</head> | ||
<body> | ||
{{ content }} | ||
</body> | ||
</html></code></pre> | ||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
#! /usr/bin/env node | ||
|
||
// Static website generator. Compiles three things: | ||
// - Handlbars: compile all "name.hbs" into "name.html" | ||
// - Markdown: compile all "name.md" into "index.html" using the layout template | ||
// - SASS: compile all "name.scss" into "name.min.css" | ||
// All of this while ignoring the partials (filenames startig by "_") | ||
const { start } = require("live-server"); | ||
|
||
const ignoreFiles = require('ignore'); | ||
const marked = require('marked'); | ||
const hbs = require('handlebars'); | ||
const liquid = require('liquidjs')(); | ||
const sass = require('node-sass'); | ||
const watch = require('node-watch'); | ||
const fm = require('front-matter'); | ||
const { abs, dir, exists, join, name, read, stat, walk, write } = require('fs-array'); | ||
|
||
// Check whether a folder has a 'readme.md' file or not | ||
const hasReadme = src => exists(join(src, 'readme.md')); | ||
|
||
// Find all the relevant data for a blog post entry (a folder) | ||
const parseData = (file, i, blog) => { | ||
// const file = join(folder, 'readme.md'); | ||
const folder = file.replace(/readme\.md$/, ''); | ||
const { attributes: { layout, ...attr }, body } = fm(read(file)); | ||
if (!layout) return; | ||
attr.layout = layout + ((/\.\w+$/.test(layout)) ? '' : '.liquid'); | ||
attr.layout = '_' + attr.layout.replace(/^_/, ''); | ||
return { | ||
id: folder.split('/').slice(-2).shift(), | ||
file, | ||
folder, | ||
...attr, | ||
// Create the main handlebars template based on the selected layout | ||
// template: hbs.compile(`{{> ${attr.layout}}}`), | ||
body: marked(body) | ||
}; | ||
}; | ||
|
||
// Folders to ignore | ||
const svc = ignoreFiles().add('.git'); | ||
if (exists('.gitignore')) svc.add(read('.gitignore')); | ||
const ignore = src => !svc.ignores(src); | ||
|
||
// Extensions to handle to changes | ||
const filter = /\.(js|sass|scss|md|hbs|liquid)$/; | ||
const isPartial = src => name(src)[0] === '_'; | ||
const isFull = src => !isPartial(src); | ||
const ext = (...end) => src => end.find(ext => src.slice(-ext.length) === ext); | ||
|
||
|
||
const compile = (err, file) => { | ||
|
||
// All of the valid filenames within the project | ||
const walked = walk(__dirname).filter(ignore).filter(src => filter.test(src)); | ||
|
||
const templates = { hbs: {}, liquid: {}, pug: {} }; | ||
|
||
// Handlebars import all '_name.hbs' in the blog folder as partials | ||
walked.filter(isPartial).filter(ext('hbs')).forEach(src => { | ||
const file = name(src, '.hbs').slice(1); | ||
templates.hbs[file] = read(src); | ||
hbs.registerPartial(file, read(src)); | ||
}); | ||
|
||
walked.filter(isPartial).filter(ext('liquid')).forEach(src => { | ||
templates.liquid[name(src, '.liquid').slice(1)] = src; | ||
}); | ||
|
||
// Render any .hbs in the page in place for a .html file | ||
walked.filter(isFull).filter(ext('hbs')).forEach(src => { | ||
const output = src.replace(/\.hbs$/, '.html'); | ||
write(output, hbs.compile(read(src))({ blog })); | ||
}); | ||
|
||
// Actual markdown parsing | ||
// const blog = dir(folder).filter(hasReadme).map(parseData).filter(a => a); | ||
const blog = walked.filter(ext('md')).map(parseData).filter(Boolean); | ||
blog.forEach(data => { | ||
const [layout, ext] = data.layout.slice(1).split('.'); | ||
if (!templates[ext][layout]) { | ||
return console.log(`Couldn't find template "${layout}". Make sure you have a file named "${data.layout}"`); | ||
} | ||
if (ext === 'liquid') { | ||
liquid.renderFile(templates.liquid[layout], data).then(html => { | ||
write(join(data.folder, 'index.html'), html); | ||
}); | ||
} | ||
if (ext === 'hbs') { | ||
const html = hbs.compile(`{{> ${layout}}}`)(data); | ||
write(join(data.folder, 'index.html'), html); | ||
} | ||
}); | ||
|
||
// The SASS or SCSS is being modified, rebuild them all | ||
if (!file || /\.s(a|c)ss$/.test(file)) { | ||
// Only main scss that are not partials (ignore "_name.scss" ) | ||
walked.filter(isFull).filter(ext('scss')).forEach(style => { | ||
const options = { file: style, outputStyle: 'compressed' }; | ||
const output = style.replace(/\.s(a|c)ss$/, '.min.css'); | ||
write(output, sass.renderSync(options).css.toString()); | ||
}); | ||
} | ||
}; | ||
|
||
watch(__dirname, { recursive: true, filter }, compile); | ||
compile(); | ||
|
||
start({ port: 3000, host: "localhost", open: true }); |
Oops, something went wrong.