Gohugo migration #11
345 changed files with 434 additions and 1605 deletions
13
.gitignore
vendored
13
.gitignore
vendored
|
@ -1,13 +1,4 @@
|
|||
# Build directory
|
||||
build
|
||||
/public/
|
||||
/resources/
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
jspm_packages
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Output files
|
||||
*.pdf
|
||||
*.epub
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
image: node:10.16
|
||||
|
||||
cache:
|
||||
paths:
|
||||
- node_modules/
|
||||
|
||||
variables:
|
||||
S3_BUCKET_NAME: recettes.inf3.ch
|
||||
AWS_BUCKET_REGION: us-east-1
|
||||
|
||||
node-build:
|
||||
stage: build
|
||||
gohugo-build-branch:
|
||||
image: monachus/hugo:v0.63.1
|
||||
script:
|
||||
- npm ci
|
||||
- npm run build
|
||||
- hugo -b http://${S3_BUCKET_NAME}.s3-website-${AWS_BUCKET_REGION}.amazonaws.com/${CI_COMMIT_REF_SLUG}
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- build
|
||||
- public
|
||||
except:
|
||||
- /^master$/
|
||||
|
||||
gohugo-build-master:
|
||||
image: monachus/hugo:v0.63.1
|
||||
script:
|
||||
- hugo
|
||||
artifacts:
|
||||
expire_in: 1 week
|
||||
paths:
|
||||
- public
|
||||
only:
|
||||
- /^master$/
|
||||
|
||||
deploys3-branch:
|
||||
image: "python:latest"
|
||||
|
@ -24,7 +30,7 @@ deploys3-branch:
|
|||
before_script:
|
||||
- pip install awscli
|
||||
script:
|
||||
- aws s3 cp build s3://${S3_BUCKET_NAME}/${CI_COMMIT_REF_SLUG} --recursive
|
||||
- aws s3 cp public s3://${S3_BUCKET_NAME}/${CI_COMMIT_REF_SLUG} --recursive
|
||||
environment:
|
||||
name: ${CI_COMMIT_REF_SLUG}
|
||||
url: http://${S3_BUCKET_NAME}.s3-website-${AWS_BUCKET_REGION}.amazonaws.com/${CI_COMMIT_REF_SLUG}
|
||||
|
@ -38,7 +44,7 @@ deploys3-master:
|
|||
before_script:
|
||||
- pip install awscli
|
||||
script:
|
||||
- aws s3 cp build s3://${S3_BUCKET_NAME}/ --recursive
|
||||
- aws s3 cp public s3://${S3_BUCKET_NAME}/ --recursive
|
||||
environment:
|
||||
name: ${CI_COMMIT_REF_SLUG}
|
||||
url: http://${S3_BUCKET_NAME}.s3-website-${AWS_BUCKET_REGION}.amazonaws.com/
|
||||
|
|
17
README.md
17
README.md
|
@ -8,10 +8,9 @@ et les modifications intégrées sur la branche `master`.
|
|||
|
||||
## URLs utiles
|
||||
|
||||
## Usage
|
||||
Le blog peut être généré en local avec `nodejs`. Il suffit d'installer
|
||||
les dépendances avec `npm ci`, puis, une fois celles-ci installées,
|
||||
lancer la génération avec `npm run build`.
|
||||
## Installation
|
||||
1. `curl -SsL https://github.com/gohugoio/hugo/releases/download/v0.63.2/hugo_0.63.2_Linux-64bit.tar.gz | tar zxvf - hugo`
|
||||
2. `./hugo serve`
|
||||
|
||||
## Ajouter des recettes
|
||||
|
||||
|
@ -27,15 +26,7 @@ lancer la génération avec `npm run build`.
|
|||
9. Suivre le lien donné pour créer une Merge Request avec les nouvelles
|
||||
recettes.
|
||||
|
||||
### Visualiser les changements
|
||||
* En local, il est possible de compiler le site avec `npm run build` puis
|
||||
visualiser le site généré avec `http-server build`.
|
||||
* A distance, GitLab compile et déploie sur le site sur une addresse de prévisualisation
|
||||
disponible dans la MR.
|
||||
|
||||
## Technologies
|
||||
* Le site est généré statiquement avec [metalsmith](https://metalsmith.io/)
|
||||
* Le site est généré statiquement avec [Hugo](https://gohugo.io)
|
||||
* Les fichiers générés sont déployés automatiquement dans un bucket Amazon S3
|
||||
* Le site web est distribué par Amazon CloudFront
|
||||
* Un fichier epub avec les recettes est généré à partir des pages générées
|
||||
statiquement.
|
||||
|
|
276
build.js
276
build.js
|
@ -1,276 +0,0 @@
|
|||
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 postcss = require('metalsmith-postcss')
|
||||
var discoverPartials = require('metalsmith-discover-partials')
|
||||
|
||||
var fs = require('fs');
|
||||
var moment = require('moment');
|
||||
var _ = require('underscore');
|
||||
|
||||
var handlebars = require('handlebars');
|
||||
var handlebarsLayout = require('handlebars-layouts');
|
||||
|
||||
moment.locale('fr');
|
||||
|
||||
//--------------------------- Handlebars -----------------------------//
|
||||
handlebars.registerHelper(handlebarsLayout(handlebars));
|
||||
|
||||
handlebars.registerHelper('formatDate', function(date) {
|
||||
return moment(new Date(date)).format('DD MMMM YYYY');
|
||||
});
|
||||
|
||||
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('eachSorted', function(context, member, item, order, options) {
|
||||
var tot = '';
|
||||
|
||||
var entries = _.sortBy(context, function(item){
|
||||
return item[member][item] === undefined? 0 : item[member][item];
|
||||
})
|
||||
|
||||
if (order === 'desc') {
|
||||
entries = entries.reverse();
|
||||
}
|
||||
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
tot += options.fn(entries[i]);
|
||||
}
|
||||
|
||||
return tot;
|
||||
});
|
||||
|
||||
handlebars.registerHelper('eachCenter', function(context, number, index, options) {
|
||||
if (number > context.length) {
|
||||
number = context.length;
|
||||
}
|
||||
|
||||
var start = index - number / 2;
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
var end = start + number;
|
||||
if (end > context.length) {
|
||||
end = context.length;
|
||||
start = end - number;
|
||||
}
|
||||
|
||||
var tot = '';
|
||||
|
||||
for (var i = start; i < end; i++) {
|
||||
if (i === index) {
|
||||
tot += options.inverse(context[i]);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
//--------------------------- Build pipeline -------------------------//
|
||||
metalsmith(__dirname)
|
||||
.source('recettes')
|
||||
.metadata(require('./config/metadata'))
|
||||
.frontmatter(false)
|
||||
.use(matters(require('./config/matters')))
|
||||
.use(filemetadata(require('./config/filemetadata')))
|
||||
.use(addCategory())
|
||||
.use(createCategories())
|
||||
.use(collections(require('./config/collections')))
|
||||
.use(markdown(require('./config/markdown')))
|
||||
.use(pagination(require('./config/pagination')))
|
||||
.use(paths(require('./config/paths')))
|
||||
.use(discoverPartials(require('./config/layouts-partials')))
|
||||
.use(layouts(require('./config/layouts')))
|
||||
.use(copyVendor())
|
||||
.use(postcss(require('./config/postcss')))
|
||||
.use(epubGen())
|
||||
.destination('build')
|
||||
.build(function (err) {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
//--------------------- Helper functions -----------------------------//
|
||||
|
||||
// Generates an epub file from the list of recettes.
|
||||
function epubGen() {
|
||||
var fs = require('fs');
|
||||
var epubGenerator = require('epub-generator');
|
||||
|
||||
return function(files, metalsmith, done) {
|
||||
var epubStream = epubGenerator({
|
||||
title: metalsmith.metadata().site.title,
|
||||
author: metalsmith.metadata().site.authors,
|
||||
language: metalsmith.metadata().site.language
|
||||
});
|
||||
|
||||
for (var f in files) {
|
||||
if (files[f].type == 'recette') {
|
||||
epubStream.add(f, files[f].contents, {
|
||||
title: files[f].data.title,
|
||||
toc: true
|
||||
});
|
||||
} else if (files[f].type == 'style') {
|
||||
epubStream.add(f, files[f].contents, {
|
||||
toc: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
epubStream.end()
|
||||
.pipe( fs.createWriteStream('basic.epub') )
|
||||
.on('error', function(err){
|
||||
console.trace(err);
|
||||
});
|
||||
|
||||
return done();
|
||||
}
|
||||
}
|
||||
|
||||
function createCategories() {
|
||||
return function(files, metalsmith, done) {
|
||||
var tagList = {};
|
||||
for (var fileName in files) {
|
||||
var data = files[fileName];
|
||||
if (!data) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var tagsData = data.category;
|
||||
if (!tagsData) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (typeof tagsData === 'string') {
|
||||
tagsData = tagsData.split(',');
|
||||
}
|
||||
|
||||
data.category = [];
|
||||
|
||||
tagsData.forEach(function(rawTag) {
|
||||
var tag = String(rawTag).trim();
|
||||
|
||||
data.category.push(tag);
|
||||
|
||||
if (!tagList[tag]) {
|
||||
tagList[tag] = [];
|
||||
}
|
||||
tagList[tag].push(fileName);
|
||||
});
|
||||
}
|
||||
|
||||
var metadata = metalsmith.metadata();
|
||||
metadata.tags = metadata.tags || {};
|
||||
|
||||
for (var tag in tagList) {
|
||||
var posts = tagList[tag].map(function(fileName) {
|
||||
return files[fileName];
|
||||
});
|
||||
|
||||
var tagPage = files[tag + '/index.md'];
|
||||
|
||||
tagPage.tag = tag;
|
||||
tagPage.posts = posts;
|
||||
tagPage.title = tagPage.data.title;
|
||||
|
||||
posts.forEach(function(post) {
|
||||
post.categoryPage = tagPage;
|
||||
});
|
||||
|
||||
metadata['tags'][tag] = tagPage;
|
||||
}
|
||||
|
||||
tagList = {};
|
||||
|
||||
return done();
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the category to the recette entry based on the parent directory
|
||||
function addCategory() {
|
||||
return function(files, metalsmith, done) {
|
||||
for (var f in files) {
|
||||
if (f.indexOf('.md') > 0 && f.indexOf('index.md') < 0) {
|
||||
var idx = f.indexOf('/');
|
||||
var cat = f.substring(0, idx);
|
||||
|
||||
files[f].category = cat;
|
||||
files[f].title = files[f].data.title;
|
||||
}
|
||||
}
|
||||
return done();
|
||||
}
|
||||
}
|
||||
|
||||
function copyVendor() {
|
||||
return function(files, metalsmith, done){
|
||||
var styleFiles = fs.readdirSync('styles');
|
||||
for (var i = 0; i < styleFiles.length; i++) {
|
||||
var stylePath = 'styles/' + styleFiles[i];
|
||||
files[stylePath] = {
|
||||
contents: fs.readFileSync(stylePath),
|
||||
type: 'style'
|
||||
};
|
||||
}
|
||||
|
||||
var fontFiles = fs.readdirSync('fonts');
|
||||
for (var i = 0; i < fontFiles.length; i++) {
|
||||
var fontPath = 'fonts/' + fontFiles[i];
|
||||
files[fontPath] = {
|
||||
contents: fs.readFileSync(fontPath),
|
||||
type: 'font'
|
||||
};
|
||||
}
|
||||
|
||||
return done();
|
||||
};
|
||||
}
|
20
config.toml
Normal file
20
config.toml
Normal file
|
@ -0,0 +1,20 @@
|
|||
contentDir = "content"
|
||||
layoutDir = "layouts"
|
||||
publishDir = "public"
|
||||
buildDrafts = false
|
||||
baseURL = "https://recettes.inf3.ch"
|
||||
canonifyURLs = true
|
||||
theme = "hugo-recettes"
|
||||
|
||||
languageCode = "fr"
|
||||
|
||||
title = "Recettes"
|
||||
author = "Anne-Catherine Pormann et Thomas Schwery"
|
||||
copyright = ""
|
||||
|
||||
[taxonomies]
|
||||
category = "categories"
|
||||
tag = "tags"
|
||||
|
||||
[params]
|
||||
logo = "/images/logo.png"
|
|
@ -1,38 +0,0 @@
|
|||
module.exports = {
|
||||
recettes: {
|
||||
pattern: '*/*.md',
|
||||
sortBy: function(oa, ob) {
|
||||
a = oa.data.publication;
|
||||
b = ob.data.publication;
|
||||
|
||||
if (!a && !b) {
|
||||
return 0;
|
||||
}
|
||||
if (!a) {
|
||||
return -1;
|
||||
}
|
||||
if (!b) {
|
||||
return 1;
|
||||
}
|
||||
if (a < b) {
|
||||
return -1;
|
||||
}
|
||||
if (a > b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
ta = oa.data.title;
|
||||
tb = ob.data.title;
|
||||
return (ta > tb) ? -1 : 1;
|
||||
},
|
||||
reverse: true
|
||||
},
|
||||
categories: {
|
||||
pattern: '*/index.md',
|
||||
sortBy: 'title'
|
||||
},
|
||||
index: {
|
||||
pattern: '*/*.md',
|
||||
sortBy: 'title'
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
module.exports = [
|
||||
{
|
||||
pattern: '*/*.md',
|
||||
metadata: {
|
||||
layout: 'recette.hbs',
|
||||
type: 'recette'
|
||||
}
|
||||
},{
|
||||
pattern: '*/index.md',
|
||||
metadata: {
|
||||
layout: 'tag.hbs',
|
||||
type: 'tag'
|
||||
}
|
||||
}
|
||||
]
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
preserveComments: 'some'
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
directory: "templates/partials",
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
module.exports = {
|
||||
engine: 'handlebars',
|
||||
default: 'test.hbs',
|
||||
directory: 'templates',
|
||||
partials: 'templates/partials'
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
module.exports = {
|
||||
gfm: true,
|
||||
tables: true
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
module.exports = {
|
||||
site: {
|
||||
title: 'Recettes',
|
||||
url: 'none',
|
||||
authors: 'Anne-Catherine Portmann, Thomas Schwery',
|
||||
language: 'fr-CH'
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
module.exports = {
|
||||
'collections.recettes': {
|
||||
perPage: 20,
|
||||
first: 'index.html',
|
||||
layout: 'index.hbs',
|
||||
path: 'page/:num/index.html',
|
||||
filter: 'type == \'recette\''
|
||||
},
|
||||
'collections.index': {
|
||||
perPage: 250,
|
||||
first: 'search.html',
|
||||
layout: 'search.hbs',
|
||||
path: 'search/:num/index.html',
|
||||
filter: 'type == \'recette\'',
|
||||
groupBy: function(data) {
|
||||
return data.title.normalize('NFD').charAt(0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
'autoprefixer': {}
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
module.exports = {
|
||||
src: 'vendor',
|
||||
dest: 'vendor'
|
||||
}
|
4
content/recettes/_index.md
Normal file
4
content/recettes/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Recettes
|
||||
type: sectionroot
|
||||
---
|
4
content/recettes/accompagnements/_index.md
Normal file
4
content/recettes/accompagnements/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Accompagnements
|
||||
type: section
|
||||
---
|
4
content/recettes/base/_index.md
Normal file
4
content/recettes/base/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Recettes de base
|
||||
type: section
|
||||
---
|
4
content/recettes/boissons/_index.md
Normal file
4
content/recettes/boissons/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Boissons et cocktails
|
||||
type: section
|
||||
---
|
Before Width: | Height: | Size: 6.9 KiB After Width: | Height: | Size: 6.9 KiB |
4
content/recettes/desserts/_index.md
Normal file
4
content/recettes/desserts/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Desserts
|
||||
type: section
|
||||
---
|
4
content/recettes/divers/_index.md
Normal file
4
content/recettes/divers/_index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Divers
|
||||
type: section
|
||||
---
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue