Recette build system
This commit is contained in:
commit
6b35c9509b
17 changed files with 441 additions and 0 deletions
146
build.js
Normal file
146
build.js
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
var metalsmith = require('metalsmith')
|
||||||
|
var layouts = require('metalsmith-layouts')
|
||||||
|
var markdown = require('metalsmith-markdown')
|
||||||
|
var collections = require('metalsmith-collections')
|
||||||
|
var pagination = require('metalsmith-pagination')
|
||||||
|
var paths = require('metalsmith-paths')
|
||||||
|
var filemetadata = require('metalsmith-filemetadata')
|
||||||
|
var matters = require('metalsmith-matters')
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
var moment = require('moment');
|
||||||
|
|
||||||
|
var handlebars = require('handlebars');
|
||||||
|
var hlayouts = require('handlebars-layouts');
|
||||||
|
|
||||||
|
handlebars.registerHelper(hlayouts(handlebars));
|
||||||
|
handlebars.registerPartial('base', fs.readFileSync('templates/base.hbs', 'utf8'));
|
||||||
|
|
||||||
|
handlebars.registerHelper('formatDate', function(date) {
|
||||||
|
return moment(new Date(date)).format('MMMM D, YYYY HH:mm:ss');
|
||||||
|
});
|
||||||
|
|
||||||
|
handlebars.registerHelper('formatTimestamp', function(date) {
|
||||||
|
return moment(date, 'X').format('MMMM D, YYYY HH:mm:ss');
|
||||||
|
});
|
||||||
|
|
||||||
|
function compareWith(v1, v2, operator) {
|
||||||
|
var itm = false;
|
||||||
|
|
||||||
|
switch (operator) {
|
||||||
|
case '==':
|
||||||
|
itm = (v1 == v2);
|
||||||
|
break;
|
||||||
|
case '!=':
|
||||||
|
itm = (v1 != v2);
|
||||||
|
break;
|
||||||
|
case '===':
|
||||||
|
itm = (v1 === v2);
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
itm = (v1 < v2);
|
||||||
|
break;
|
||||||
|
case '<=':
|
||||||
|
itm = (v1 <= v2);
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
itm = (v1 > v2);
|
||||||
|
break;
|
||||||
|
case '>=':
|
||||||
|
itm = (v1 >= v2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return itm;
|
||||||
|
}
|
||||||
|
|
||||||
|
handlebars.registerHelper('eachCond', function(context, member, operator, cond, options) {
|
||||||
|
var tot = '';
|
||||||
|
for (var i = 0; i < context.length; i++) {
|
||||||
|
var itm = false;
|
||||||
|
var v1 = context[i][member];
|
||||||
|
|
||||||
|
|
||||||
|
if (compareWith(v1, cond, operator)) {
|
||||||
|
tot += options.fn(context[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tot;
|
||||||
|
});
|
||||||
|
|
||||||
|
handlebars.registerHelper('ifCond', function (v1, operator, v2, options) {
|
||||||
|
if (compareWith(v1, v2, operator)) {
|
||||||
|
return options.fn(this);
|
||||||
|
} else {
|
||||||
|
return options.inverse(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
metalsmith(__dirname)
|
||||||
|
.source('recettes')
|
||||||
|
.metadata(require('./config/metadata'))
|
||||||
|
.frontmatter(false)
|
||||||
|
.use(matters())
|
||||||
|
.use(filemetadata(require('./config/filemetadata')))
|
||||||
|
.use(collections(require('./config/collections')))
|
||||||
|
.use(markdown(require('./config/markdown')))
|
||||||
|
.use(pagination(require('./config/pagination')))
|
||||||
|
.use(paths(require('./config/paths')))
|
||||||
|
.use(layouts(require('./config/layouts')))
|
||||||
|
.use(copyVendor())
|
||||||
|
.destination('build')
|
||||||
|
.build(function (err) {
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function debugCollection() {
|
||||||
|
return function(files, metalsmith, done) {
|
||||||
|
console.log(files);
|
||||||
|
for (var i in files) {
|
||||||
|
console.log(i + ' -> ' + ' (' + files[i].collection + ')');
|
||||||
|
console.log(files[i]);
|
||||||
|
}
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugMeta(metaname) {
|
||||||
|
return function(files, metalsmith, done) {
|
||||||
|
if (metaname !== undefined) {
|
||||||
|
console.log(metalsmith.metadata()[metaname]);
|
||||||
|
} else {
|
||||||
|
console.log(metalsmith.metadata());
|
||||||
|
}
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function debugPagination() {
|
||||||
|
return function(files, metalsmith, done) {
|
||||||
|
|
||||||
|
for (var i in files) {
|
||||||
|
var f = files[i];
|
||||||
|
if (f !== undefined && f.path != undefined) {
|
||||||
|
console.log(f.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function copyVendor() {
|
||||||
|
|
||||||
|
return function(files, metalsmith, done){
|
||||||
|
|
||||||
|
var bufferMoment = fs.readFileSync('styles/customHighlight.css');
|
||||||
|
files['styles/customHighlight.css'] = {
|
||||||
|
contents: bufferMoment
|
||||||
|
};
|
||||||
|
|
||||||
|
return done();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
6
config/collections.js
Normal file
6
config/collections.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
recettes: {
|
||||||
|
pattern: '*/*.md',
|
||||||
|
sortBy: 'title'
|
||||||
|
}
|
||||||
|
}
|
6
config/css.js
Normal file
6
config/css.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
files: '**/*.css',
|
||||||
|
cleanCSS: {
|
||||||
|
rebase: true
|
||||||
|
}
|
||||||
|
}
|
9
config/filemetadata.js
Normal file
9
config/filemetadata.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
module.exports = [
|
||||||
|
{
|
||||||
|
pattern: '*/*.md',
|
||||||
|
metadata: {
|
||||||
|
layout: 'recette.hbs',
|
||||||
|
type: 'recette'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
3
config/js.js
Normal file
3
config/js.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
preserveComments: 'some'
|
||||||
|
}
|
5
config/layouts.js
Normal file
5
config/layouts.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
engine: 'handlebars',
|
||||||
|
default: 'test.hbs',
|
||||||
|
directory: 'templates'
|
||||||
|
}
|
32
config/markdown.js
Normal file
32
config/markdown.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
var highlightjs = require('highlight.js');
|
||||||
|
|
||||||
|
highlightjs.registerLanguage('procedurelog', function(hljs) {
|
||||||
|
|
||||||
|
return {
|
||||||
|
case_insensitive: false,
|
||||||
|
keywords: {
|
||||||
|
keyword: 'return',
|
||||||
|
literal: 'true false null undefined NaN Infinity',
|
||||||
|
built_in: 'macroBreak callTask executeAction createNewPage',
|
||||||
|
assertSuccess: 'SUCCESS',
|
||||||
|
assertFail: 'FAIL',
|
||||||
|
info: 'PROCEDURE ENDPROCEDURE SCRIPT INIT',
|
||||||
|
action: 'ACTION ASSERT'
|
||||||
|
},
|
||||||
|
contains: [
|
||||||
|
hljs.APOS_STRING_MODE,
|
||||||
|
hljs.QUOTE_STRING_MODE
|
||||||
|
]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
var highlighter = function (code) {
|
||||||
|
var hl = highlightjs.highlightAuto(code, ['procedurelog', 'xml']);
|
||||||
|
return hl.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
gfm: true,
|
||||||
|
tables: true,
|
||||||
|
highlight: highlighter
|
||||||
|
}
|
6
config/metadata.js
Normal file
6
config/metadata.js
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
module.exports = {
|
||||||
|
site: {
|
||||||
|
title: 'SNV4-cclient tests',
|
||||||
|
url: 'none'
|
||||||
|
}
|
||||||
|
}
|
8
config/pagination.js
Normal file
8
config/pagination.js
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
module.exports = {
|
||||||
|
'collections.recettes': {
|
||||||
|
perPage: 15,
|
||||||
|
first: 'index.html',
|
||||||
|
layout: 'index.hbs',
|
||||||
|
path: 'page/:num/index.html'
|
||||||
|
}
|
||||||
|
}
|
3
config/paths.js
Normal file
3
config/paths.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
}
|
3
config/redirect.js
Normal file
3
config/redirect.js
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
|
||||||
|
}
|
4
config/vendor.js
Normal file
4
config/vendor.js
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
module.exports = {
|
||||||
|
src: 'vendor',
|
||||||
|
dest: 'vendor'
|
||||||
|
}
|
29
package.json
Normal file
29
package.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "snv4-testresults",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"bower": "^1.5.2",
|
||||||
|
"handlebars": "^3.0.3",
|
||||||
|
"handlebars-layouts": "^3.1.0",
|
||||||
|
"highlight.js": "^9.4.0",
|
||||||
|
"metalsmith": "^1.0.1",
|
||||||
|
"metalsmith-collections": "^0.7.0",
|
||||||
|
"metalsmith-collections-paginate": "^2.0.1",
|
||||||
|
"metalsmith-filemetadata": "^1.0.0",
|
||||||
|
"metalsmith-layouts": "^1.6.5",
|
||||||
|
"metalsmith-markdown": "^0.2.1",
|
||||||
|
"metalsmith-matters": "^1.2.0",
|
||||||
|
"metalsmith-paginate": "^0.3.0",
|
||||||
|
"metalsmith-pagination": "^1.0.0",
|
||||||
|
"metalsmith-paths": "^2.1.2",
|
||||||
|
"metalsmith-permalinks": "^0.4.0",
|
||||||
|
"moment": "^2.6.0",
|
||||||
|
"serve": "^1.4.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"serve": "serve build -p ${PORT:-3000}",
|
||||||
|
"build": "node build.js"
|
||||||
|
},
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
35
styles/customHighlight.css
Normal file
35
styles/customHighlight.css
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
.step {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ingredients {
|
||||||
|
display: inline-block;
|
||||||
|
list-style-type: none;
|
||||||
|
max-width: 240px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instructions {
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
left: 250px;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ing-name {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recipe-image {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-title {
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: solid 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: right;
|
||||||
|
}
|
39
templates/base.hbs
Normal file
39
templates/base.hbs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||||
|
<script src="http://localhost:35729/livereload.js"></script>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/styles/default.min.css">
|
||||||
|
<link rel="stylesheet" href="/styles/customHighlight.css">
|
||||||
|
|
||||||
|
<title>{{#block "title"}} {{/block}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav class="navbar navbar-default">
|
||||||
|
<div class="container">
|
||||||
|
<div class="navbar-header">
|
||||||
|
<a class="navbar-brand">{{#block "title"}} {{/block}}</a>
|
||||||
|
{{!-- Fixme
|
||||||
|
<div id="navbar" class="navbar-collapse collapse">
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
{{#block "navitems"}} {{/block}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
--}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<div class="container">
|
||||||
|
<article class="content">
|
||||||
|
{{#block "content"}} {{/block}}
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
<footer class="col-md-12">
|
||||||
|
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
35
templates/index.hbs
Normal file
35
templates/index.hbs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{{#extend "base"}}
|
||||||
|
|
||||||
|
{{#content "title"}}
|
||||||
|
Recettes
|
||||||
|
{{/ content}}
|
||||||
|
|
||||||
|
{{#content "navitems"}}
|
||||||
|
{{#if pagination.previous }}
|
||||||
|
<li><a href="/{{ pagination.previous.path }}" class="btn pull-right">
|
||||||
|
<i class="glyphicon glyphicon-chevron-right">
|
||||||
|
</i>Newer </a></li>
|
||||||
|
{{/ if}}
|
||||||
|
{{#if pagination.next }}
|
||||||
|
<li><a href="/{{ pagination.next.path }}" class="btn pull-left">
|
||||||
|
<i class="glyphicon glyphicon-chevron-left">
|
||||||
|
</i> Older</a></li>
|
||||||
|
{{/ if}}
|
||||||
|
{{/content}}
|
||||||
|
|
||||||
|
{{#content "content"}}
|
||||||
|
{{#each pagination.files}}
|
||||||
|
<article class="content">
|
||||||
|
<header class="header">
|
||||||
|
<h2 class="content-title">
|
||||||
|
<a href="{{ path.href }}">{{ data.title }}</a>
|
||||||
|
</h2>
|
||||||
|
</header>
|
||||||
|
<section class="content-article">
|
||||||
|
{{{ data.description }}}
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
{{/ each}}
|
||||||
|
{{/ content}}
|
||||||
|
|
||||||
|
{{/ extend}}
|
72
templates/recette.hbs
Normal file
72
templates/recette.hbs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{{#extend "base"}}
|
||||||
|
|
||||||
|
{{#content "title"}}
|
||||||
|
Recettes • {{ data.title }}
|
||||||
|
{{/ content}}
|
||||||
|
|
||||||
|
{{#content "navitems"}}
|
||||||
|
{{#if next }}
|
||||||
|
<li><a href="{{ next.path.href }}">{{formatTimestamp next.date }} {{ next.procedure }}</a></li>
|
||||||
|
{{/if }}
|
||||||
|
<li><a href="/{{ date }}/index.html">Up</a></li>
|
||||||
|
{{#if previous }}
|
||||||
|
<li><a href="{{ previous.path.href }}">{{formatTimestamp previous.date }} {{ previous.procedure }}</a></li>
|
||||||
|
{{/if }}
|
||||||
|
{{/content}}
|
||||||
|
|
||||||
|
{{#content "content"}}
|
||||||
|
<header class="header">
|
||||||
|
<h1 class="content-title">
|
||||||
|
Recette {{ data.title }}
|
||||||
|
</h1>
|
||||||
|
<small class="header-metadata">
|
||||||
|
{{#if data.category }}{{ data.category }} • {{/if }}
|
||||||
|
{{#if data.description }}{{ data.description }} • {{/if }}
|
||||||
|
{{ data.portion }} •
|
||||||
|
{{ data.time }}
|
||||||
|
</small>
|
||||||
|
</header>
|
||||||
|
<section class="content">
|
||||||
|
{{#each data.steps }}
|
||||||
|
<div class="step">
|
||||||
|
<ul class="ingredients">
|
||||||
|
{{#each ingredients}}
|
||||||
|
<li class="ingredient">
|
||||||
|
<span class="ing-quantity">{{ quantity }} {{ unit }}</span>
|
||||||
|
<span class="ing-name">{{ name }}</span>
|
||||||
|
{{#if comment }}<span class="ing-comment">{{ comment }}</span>{{/if }}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
<div class="instructions">
|
||||||
|
{{ instructions }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each }}
|
||||||
|
{{#if data.image }}
|
||||||
|
<div class="recipe-image">
|
||||||
|
<img src="{{ data.image }}" />
|
||||||
|
</div>
|
||||||
|
{{/if }}
|
||||||
|
|
||||||
|
{{{ contents }}}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<comments>
|
||||||
|
<h2>Commentaires</h2>
|
||||||
|
<div id="disqus_thread"></div>
|
||||||
|
<script>
|
||||||
|
(function() { // DON'T EDIT BELOW THIS LINE
|
||||||
|
var d = document, s = d.createElement('script');
|
||||||
|
|
||||||
|
s.src = '//inf3recettes.disqus.com/embed.js';
|
||||||
|
|
||||||
|
s.setAttribute('data-timestamp', +new Date());
|
||||||
|
(d.head || d.body).appendChild(s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>
|
||||||
|
</comments>
|
||||||
|
{{/ content}}
|
||||||
|
|
||||||
|
{{/ extend}}
|
Loading…
Add table
Reference in a new issue