This project is used to build the Dev-Mind websites. The aim is to use handlebars as template solution and asciidoctor.js to writes dynamic pages as a blog. Several others extensions help to generate a rss file, a sitemap file…
If you want a real example see https://www.dev-mind.fr/ or https://http://mixteen.org
This library is written with typescript. When Typescript is updated we have to compile the file is js to be able to use them in a project which don’t use typescript
To do that run
npm run build
This module is made to be used in a GulpFile. You can read the gulpfile.ts used to test the extensions or you can see the gulpfile used on the main Dev-Mind website (https://github.com/Dev-Mind/dev-mind.fr).
To install this module use for example with yarn
yarn add https://github.com/Dev-Mind/devmind-website.git#X.Y.ZFind the good version X.Y.Z on https://github.com/Dev-Mind/devmind-website/releases
To import the module in your gulpfile.js you can use
constwebsite=require('devmind-website').DevMindGulpBuilder()();You can also send parameters. Below I use the default values
constWEBSITE_PARAMS={path : '../../../',metadata : {rss: 'src/metadata/rss.json',blog: 'src/metadata/blog.json',html: 'src/metadata/html.json',sitemap: 'src/metadata/sitemap.json'}};constwebsite=require('./index')(WEBSITE_PARAMS);Used to apply a handlebar template on a file stream. This extension has to be applied after read-html or read-asciidoctor extensions which create the templateModel sent to handlebars to populate the template
Example of usage
constHANDLEBARS_PARTIALS=[{key: '_html_header',path: 'src/templates/_html_header.handlebars'},{key: '_html_footer',path: 'src/templates/_html_footer.handlebars'}];gulp.task('html-template',()=>gulp.src(`src/html/**/*.html`).pipe(website.readHtml()).pipe(website.applyTemplate(`src/templates/site.handlebars`,HANDLEBARS_PARTIALS)).pipe(gulp.dest('build/dist')));The templateModel has several attributes. For more details read the section about read-html or read-asciidoctor extension.
Used to change Asciidoc file extension to html
Example of usage
gulp.task('blog-indexing',()=>gulp.src('src/blog/**/*.adoc').pipe(website.readAsciidoc()).pipe(website.convertToHtml()).pipe(gulp.dest('build/.tmp')));Used to generate a JSON file with data read in HTML or Asciidoc file
Example of usage
gulp.task('blog-indexing',()=>gulp.src('src/blog/**/*.adoc').pipe(website.readAsciidoc()).pipe(website.convertToHtml()).pipe(website.convertToJson('blogindex.json')).pipe(gulp.dest('build/.tmp')));The result is for example
[{"strdate": "28/09/2018","revdate": "28/09/2018","doctitle": "Expérience de Guillaume EHRET","description": "CV numérique de Guillaume EHRET fondateur de Dev-Mind","keywords": ["Dev-mind","Java","JavaScript","HTML","CSS"],"filename": "experience","priority": 0.6,"dir": "/"},
...
]Tansforms a Json list with metadata to an RSS file
Example of usage
gulp.task('blog-rss',()=>gulp.src('build/.tmp/blogindex.json').pipe(website.readIndex()).pipe(website.convertToRss('blog.xml')).pipe(gulp.dest('build/dist/rss')));In this example I read an index written in Json and read-index helps to read the content and send it to the extension convert-to-rss. This extension creates the file blog.xml
The file build/.tmp/blogindex.json is for example
[{"strdate": "28/09/2018","revdate": "28/09/2018","doctitle": "Expérience de Guillaume EHRET","description": "CV numérique de Guillaume EHRET fondateur de Dev-Mind","keywords": ["Dev-mind","Java","JavaScript","HTML","CSS"],"filename": "experience","priority": 0.6,"dir": "/"}]If you want to be indexed your website on Google or other web brothers, you can expose a file sitemap.xml with all the pages to index. This extension is used for that
Example of usage
gulp.task('sitemap',()=>gulp.src(['build/.tmp/blogindex.json','build/.tmp/pageindex.json']).pipe(website.readIndex()).pipe(website.convertToSitemap()).pipe(gulp.dest('build/dist')));In this example I read 2 index written in Json (blogindex and pageindex). Extension read-index helps to read them, and send them to the extension convert-to-sitemap which is able to generate the file sitemap.xml
The file build/.tmp/blogindex.json is for example
[{"strdate": "28/09/2018","revdate": "28/09/2018","doctitle": "Expérience de Guillaume EHRET","description": "CV numérique de Guillaume EHRET fondateur de Dev-Mind","keywords": ["Dev-mind","Java","JavaScript","HTML","CSS"],"filename": "experience","priority": 0.6,}]This extension return true if the file exists
Example of usage
constpage=path.resolve(__dirname,options.path,file.path);if(!fileExist(page)){thrownewPluginError('files-exist',`File ${file.path} does not existe`);}Use to verify if each files exists in your project. If a file is not present an Exception is thrown
Example of usage
gulp.task('check',()=>gulp.src(['build/.tmp/blogindex.json','build/.tmp/pageindex.json','build/dist/rss/blog.xml','build/dist/sitemap.xml']).pipe(website.extFilesExist()).pipe(gulp.dest('build/check')));Use to highlight the source code defined in yours HTML pages.
Example of usage If your code is defined between these markups
<preclass="highlight"><codeclass="language-html"data-lang="java">
// My code
</code></pre>You can use this extension like this
gulp.task('blog-page',(cb)=>{gulp.src('src/blog/**/*.adoc').pipe(website.readHtml()).pipe(website.highlightCode({selector: 'pre.highlight code'})).pipe(gulp.dest('build/dist/blog')).on('end',()=>cb())});Read a stream of Asciidoc files and build for each HTML file. If you use code example in your asciidoc we use https://prismjs.com/ to highlight language keywords.
a templateModel, a structure JSON used after with handlebar and
an indexData object used to build an index file used by other extensions
Example of usage
gulp.task('adoc-template',()=>gulp.src(`src/html/**/*.html`).pipe(website.readAsciidoc()).pipe(website.convertToHtml()).pipe(website.applyTemplate(`src/templates/site.handlebars`)).pipe(gulp.dest('build/dist')));The JSON templateModel has these values.
keywords : to provided in a metadata JSON
title : to provided in a metadata JSON
description : to provided in a metadata JSON
contents : read from the file in the stream
gendate : current instant
filename : name of the future page
dir : for asciidoc you can define your page in a subdirectory (usefull for a blog with a subdirectory per year, or by topic)
category : to regroup elements
teaser: little teaser to introduce the page
imgteaser: image to use with this teaser (used on https://www.dev-mind.fr/ to display page blog with all articles)
canonicalUrl : computed from the current file path
modedev : read in environment variables
When you define a new page in asciidoc you can use these metadata in your header
:doctitle: Do your Blog yourself
:description: Comment construire le blog parfait
:keywords: Web, Blog, Asciidoc, Asciidoctor, CMS, Clever Cloud
:author: Guillaume EHRET - Dev-Mind
:revdate: 2018-01-02
:category: Web
:teaser: Début 2017, j'ai choisi de migrer mon blog de Blogspot vers une solution personnalisée à base de Asciidoc. J'ai continué à faire évoluer mon site web pour enfin arriver à une solution qui me satisfait.
:imgteaser: ../../img/blog/2018/siteweb_00.jpg
Start of your articleIn your handlebar template you can use the templateModel property values. For example
<html><head><title>{{ title }}</title></head><body><h1>{{ title }}</h1><p><small>{{category}}</small></p>
{{content}}
</body></html>Read a stream of HTML files and build for each HTML file
a templateModel, a structure JSON used after with handlebar and
an indexData object used to build an index file used by other extensions
Example of usage
gulp.task('html-template',()=>gulp.src(`src/html/**/*.html`).pipe(website.readHtml()).pipe(website.applyTemplate(`src/templates/site.handlebars`)).pipe(gulp.dest('build/dist')));The JSON templateModel has these values.
keywords : to provided in a metadata JSON
title : to provided in a metadata JSON
description : to provided in a metadata JSON
contents : read from the file in the stream
gendate : current instant
canonicalUrl : computed from the current file path
modedev : read in environment variables
Some elements cannot be deduced. You have to provide these informations in JSON structure. By default this module read src/metadata/html.json. You can overrided this property in the config sent to this module
constWEBSITE_PARAMS={metadata : {html: 'src/metadata/html.json'}};constwebsite=require('./index')(WEBSITE_PARAMS);This file has for example this content
{"404.html" : {"keywords": "Dev-mind Guillaume EHRET développeur indépendant spécialiste Java, Web","title": "Dev-Mind 404","description" : "Page non trouvée sur le serveur","priority": -1},"formations.html" : {"keywords": "Dev-mind organisme de formation","title": "Les formationds dispensées","description" : "Dev-Mind dispense plusieurs formations autour du web et de Java","priority": 0.6}}In your handlebar template you can use the templateModel property values. For example
<html><head><title>{{ title }}</title></head><body><h1>{{ title }}</h1>
{{content}}
</body></html>Used to parse a JSON file with metadata and send the content to another extension in file stream in gulp
Example of usage
gulp.task('blog-rss',()=>gulp.src('build/.tmp/blogindex.json').pipe(website.readIndex()).pipe(website.convertToRss('blog.xml')).pipe(gulp.dest('build/dist/rss')));In this example I read an index written in Json and read-index helps to read the content and send it to another extension like convert-to-rss for example
In production you have to activate the mode prod in environment variable. For more detail you can read http://expressjs.com/en/advanced/best-practice-performance.html#set-node_env-to-production
With systemd, use the Environment directive in your unit file. For example:
# /etc/systemd/system/myservice.service
Environment=NODE_ENV=productionIf we are not in production the templateModel used in handlebar templates contains a property modeDev to true (see section about read-html or read-asciidoctor extension)
