Skip to content

Dev-Mind/devmind-website

Repository files navigation

Module node devmind-website

Travis status

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…​

Dev-Mind

If you want a real example see https://www.dev-mind.fr/ or https://http://mixteen.org

Typescript

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

Use this module

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.Z

To import the module in your gulpfile.js you can use

const website = require('devmind-website').DevMindGulpBuilder()();

You can also send parameters. Below I use the default values

const WEBSITE_PARAMS = {
  path : '../../../',
  metadata : {
    rss: 'src/metadata/rss.json',
    blog: 'src/metadata/blog.json',
    html: 'src/metadata/html.json',
    sitemap: 'src/metadata/sitemap.json'
  }
};
const website = require('./index')(WEBSITE_PARAMS);

Extensions

apply-template

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

const HANDLEBARS_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.

convert-to-html

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'))
);

convert-to-json

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": "/"
    },
    ...
]

convert-to-rss

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": "/"
    }
]

convert-to-sitemap

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,
  }
]

file-exist

This extension return true if the file exists

Example of usage

const page = path.resolve(__dirname, options.path, file.path);
if(!fileExist(page)){
  throw new PluginError('files-exist', `File ${file.path} does not existe`);
}

files-exist

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'))
);

highlight-code

Use to highlight the source code defined in yours HTML pages.

Example of usage If your code is defined between these markups

<pre class="highlight">
    <code class="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-asciidoctor

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 article

In 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-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

const WEBSITE_PARAMS = {
  metadata : {
    html: 'src/metadata/html.json'
  }
};
const website = 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>

read-index

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

convert-to-blog-list

TODO

convert-to-blog-page

TODO

Dev & prod

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=production

If 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)

Compatibility

You have to use a

  • node version >= 10.0

  • gulp >= 4.0.0

License

devmind-website is released under the MIT license.