A simple blog engine for personal blogging
MIT License
A simple blog engine for personal blogging
Website: meblog.sinzii.me
npm install --save meblog
npx meblog init
npx meblog sample --number-of-posts=20
npx meblog serve
pug
template is? meblog is the right tool for you.The project makes use of pug
for templating, scss
for styling and gulpjs
for generating the site and automating the process.
templates
: Template files
templates/pages
: Add new pages heretemplates/posts
: Add new post layout here. By default, post.pug
will be used as default layout for poststemplates/tags
:
templates/tags/tag.pug
: Default tag template for rendering tag pagesscss
: SCSS styling files
scss/main.scss
: Main entry point of scss files, the engine will generate this file to main.css
on building.assets
: Put your images, favicon, and other resources hereposts
: Put your posts in markdown format here. Ideally, arrange your posts into year and month folders for better searching.config.js
: Config file for the sitei18n
: Put translation files for i18n hereSimply run meblog draft
or create a new file post-name.md
in folder posts
using the below format:
---
title: This is the post title
publishedAt: 2021-05-15T18:04:00+07:00 (YYYY-MM-DDTHH:mm:ssZ)
tags: tag1, tag2
excerpt: Some thoughts about the growing journey
layout: ... (post is default layout for rendering posts page, but you can defined new layout in templates/posts folder)
language: en
customfield: Custom field will also be parsed and loaded into post object
---
Post body goes here
The file name post-name
will be used as post slug.
Run the command meblog serve
and start editing your post then hit the save button if you want to see the change.
Set the auto saving interval to 2s in your editor for better editing experience. (As far as I know, Visual Studio Code or IntelliJ-based IDEs have this feature 😄)
Put all configurations in config.js
file, then all the data in this file will be available to use in the pug
templates.
But there are some configurations that you need understand why do we have it.
baseUrl
: This will be the host url that you're about to deploy to, eg: https://sinzii.me
or https://yourname.github.io
. It's not required for the site to work properly. But if you care about sharing your posts on Facebook, this property will be used to calculate the url in meta tags for the purpose of SEO or sharing your posts on social media or generate RSS feed.baseContext
: If you want to deploy the site on a sub directory like https:/sinzii.me/blog
. Then set it's value as blog
.postUrlStyle
: The engine can generate different styles of post url, choose your favorite one.
POSTS_SLUG
: ../posts/hello-world.html (default)
POSTS_YEAR_MONTH_SLUG
: ../posts/2021/05/hello-world.htmlPOSTS_YEAR_SLUG
: ../posts/2021/hello-world.htmlYEAR_MONTH_SLUG
: ../2021/05/hello-world.htmlYEAR_SLUG
: ../2021/hello-world.htmlSLUG
: ../hello-world.htmllocale
: Current rendering localeallPosts
: List of all posts include every locales, a post can also be accessed by its slug using allPosts[post-slug]
.posts
: List of posts of current rendering localetags
: List of available tagstemplateName
: Name of current rendering templateformatDateTime
: A function taking a date and locale as inputs, output formatted date time follow dateTimeFormat
configformatDate
: A function taking a date and locale as inputs, output formatted date follow dateFormat
configrootUrl
: A function taking a path and locale as inputs, ouput an absolute url of the siteurl
: A function taking a path and locale as inputs, output a relative url from current baseContext
configpostRootUrl
: A function taking post object as input, output an absolute url of the postpostUrl
: A function taking post object as input, output a relative url of the posttagRootUrl
: A function taking tag name and locale as inputs, output an absolute url of the tagtagUrl
: A function taking tag name and locale as inputs, output a relative url of the tagconfig.js
will be available as global variables (eg: baseUrl
, siteName
, ...)Variable listed here is only available in post layout template in folder templates/posts
post
: Current rendering post objectVariables listed here are only available in tag template in folder templates/tags
tag
: Current rendering tag namepostsByTag
: List of post tagged with current rendering tag
of current rendering localeBy default, the engine only processes pug
tempate to html pages and scss
to css. What if you need to write some JavaScript
or even TypeScript
and want those scripts to be bundle into one file or hot reload the script files on change when designing the site?
This is when event hooks come into play. Let me first explain about the build process of meblog.
Both meblog serve
and meblog build
commands will trigger the build process when running, the only different is the former uses dev
enviroment, and the latter uses prod
enviroment.
When the build process is running, a series of tasks will be triggered one by one.
CleanCache
: Clean cacheClean
: Clean output directoryBuild
: Build the site
CopyAssets
: Copy assets to output directoryLoadData
: Parsing and loading posts from markdown format to javascript object.GenerateTemplates
: Generate templates
GeneratePages
: Generate pagesGeneratePosts
: Generate postsGenerateTags
: Generate tagsGenerateRssFeed
: Generate RSS feedGenerateCSS
: Generate CSSOnServe
: Starting local development server & watching file changes (only in meblog serve
command)For each task, the engine will emit one event named BEFORE:TaskName
before running the task and one event named AFTER:TaskName
after the task is finished running. Therefore, in order to hook into the build process, we simply need to listen to those events and do some customization.
For example, we need to write some javascript in js/main.js
then want to minify and copy this file to output directory after GenereteCss
task.
// in config.js file
const gulp = require('gulp');
const minify = require('gulp-minify');
module.exports = {
...
eventRegister(emitter) {
emitter.on('AFTER:GenerateCss', () => {
return new Promise(resolve => {
const prod = !this.config.devMode;
let stream = gulp.src('./js/main.js');
if (prod) {
stream = stream.pipe(minify());
}
stream
.pipe(gulp.dest(this.outputDirectory))
.on('end', resolve);
});
})
}
...
}
The project uses package i18n-node to implement i18n.
Put translation files in folder i18n
and update config.js
for which locales you want to support.
// in config.js file
module.exports = {
...
defaultLocale: 'en', // Default language of the site, default: en
locales: ['en', ...] // A list of the language that you want to support, default ['en']
...
}
In pug
template, i18n
translate functions are available to use. Supported translate functions: __
, __n
, __l
, __h
, __mf
.
By default, all posts are belong to the defaultLocale
, use language
meta field to define language for a post in markdown file.
posts
.meblog build
, your site will be generated into folder docs
, use option --outdir
if you want the build to be generated somewhere else./docs
as the source folder.