• Intro

    This is part one of a mini series on my journey to build my own blogging site without using WordPress or any blogging site like Tumbler or Medium. I want full control of my published thoughts. This includes if (or how) I should share my data with advertisers and crawlers.

    I assume you are comfortable with using git, VScode, and markdown. There are other sites that discuss how to get started with GitHub and programming.

    Getting Started in VScode

    Arguably one of the best (and free) coding editors is Microsoft’s Visual Studio Code. It has a huge marketplace for extensions (or plugins) to handle any popular framework and programming language.

    Download & install vscode:

    Install extensions

    These are the extensions I use to create blog posts and update my blog’s theme.

    Be sure that VScode has the install path defined for the command line.

    Customize your VScode environment

    I typically setup the editor with my favorite color theme and set the wrap length (based on my screen width) plus font sizes. You’ll want it comfortable to your eyes.

    What is HEXO?

    Hexo is a fast, simple and powerful blog framework. You write posts in Markdown (or other markup languages) and Hexo generates static files with a beautiful theme in seconds.

    This entire site is built on the Hexo framework with a heavily customized theme of my own design. The reason I selected Hexo is that it’s built on NodeJS. Having both the frontend and backends written in JavaScript makes management of the website far easier. Plus, JavaScript remains a very popular scripting language with easy to find affordable help to enhance it further. I recall the pain of managing several programming languages for a single project. This blog only requires CSS, HTML, and JavaScript. Even the backend on AWS is simple JavaScript.

    I’ve spent the past 18 months digging into the framework and making a few minor contributions to the project. I’m now very comfortable with how it works and how to enhance it with custom tags and scripting.

    Hexo Tutorial

    setup HEXO environment

    After you download the Hexo package to your project folder, you’ll need to overwrite some files as I define below.

    config

    Need to setup the global config for HEXO and the FrontMatter CMS in VScode.

    The global config needs to be updated to use my custom theme. Here’s what I use for version 2022.04:

    _config.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    ####################################################
    ## HEXO CONFIGURATION
    ##
    ## Docs: https://hexo.io/docs/configuration.html
    ## Source: https://github.com/hexojs/hexo/
    ##
    ####################################################

    # Site
    title: Blog.RichieBartlett.com
    subtitle: 'Father | Entrepreneur | Solutions Architect'
    description: 'Richie is an Entrepreneur, Technologist and Cloud Architect. Loves how technology brings the promise of an easier life, but enjoys the challenge to make it work. Work achievements, play, & fatherhood are the things that drive Richie.'
    keywords:
    - Richie Bartlett
    - Technologist
    - Entrepreneur
    - BlockChain Developer
    - LEGO
    - AFOL
    - Solutions Architect
    - Cloud Architect
    - IT Manager
    author: 'Richie Bartlett, Jr.'

    ## https://ogp.me
    OpenGraph: ## default values for site [can be overridden by `page.OpenGraph` values]
    image: https://2022.blog.richiebartlett.com/img/logoImage.png
    imageAlt: 'Richie Bartlett'
    facebook:
    admins: false
    app_id: false ## https://developers.facebook.com/docs/development/create-an-app
    twitter: ## https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started#display
    image: https://2022.blog.richiebartlett.com/img/R/LEGObtc_thumbsUp.svg
    card: 'summary_large_image' ## [“summary”, “summary_large_image”, “app”, or “player”]
    creator: '@LoreZyra'
    site: '@LoreZyra'
    domain: 'Blog.RichieBartlett.com'
    siteName: 'Blog.RichieBartlett.com'


    ## ISO 639-1 Code
    language:
    - en #English
    - ja #Japanese
    - ar #Arabic
    - zh-TW # Traditional Chinese
    - zh-CN # Simplified Chinese

    ## IANA time zone
    timezone: 'Asia/Tokyo'

    ## URL
    ## Set your site url here. For example, if you use GitHub Page, set url as 'https://lorezyra.github.io/project'
    url: https://blog.RichieBartlett.com
    root: /
    ## https://hexo.io/docs/permalinks
    permalink: :title/
    permalink_defaults:
    lang: en

    pretty_urls:
    trailing_index: false # Set to false to remove trailing 'index.html' from permalinks
    trailing_html: false # Set to false to remove trailing '.html' from permalinks

    # Directory
    source_dir: source
    public_dir: public
    code_dir: code
    i18n_dir: lang

    skip_render:
    - _posts/**/*.json
    - _posts/**/*.yml
    - _posts/**/*.txt
    - _posts/**/*.js
    - _posts/**/*.css
    - _posts/**/*.xml
    - _posts/**/*.svg
    - _posts/**/*.ai
    - _posts/**/*.pdf
    - _posts/**/*.zip
    - themes/**/*.yml
    - themes/**/*.json

    # Writing
    new_post_name: :title.md # File name of new posts
    default_layout: post
    titlecase: true # Transform title into TitleCase
    external_link:
    enable: true # Open external links in new tab
    field: site # Apply to the whole site
    exclude: null
    filename_case: 0
    render_drafts: false
    post_asset_folder: true
    marked:
    prependRoot: true
    postAsset: true
    relative_link: false
    future: true
    markdown:
    preset: default
    render:
    html: true
    xhtmlOut: true
    langPrefix: 'language-'
    breaks: true
    linkify: true
    typographer: true
    quotes: '“”‘’「」'
    enable_rules:
    disable_rules:
    plugins: null
    anchors:
    level: 2
    collisionSuffix: null
    permalink: false
    permalinkClass: 'header-anchor'
    permalinkSide: 'left'
    permalinkSymbol: '¶'
    case: 0
    separator: '-'



    # Code Highlights
    highlight:
    enable: true
    line_number: true
    auto_detect: false
    tab_replace: ' '
    wrap: true
    hljs: true

    prismjs:
    enable: false
    preprocess: true
    line_number: true
    tab_replace: ' '



    # Home page setting
    # path: Root path for your blogs index page. (default = '')
    # per_page: Posts displayed per page. (0 = disable pagination)
    # order_by: Posts order. (Order by date descending by default)
    index_generator:
    path: '/'
    per_page: 15 ## <<<< This will be used as the home feed pagination
    order_by: -date

    archive_generator: ## https://github.com/hexojs/hexo-generator-archive
    enabled: true
    per_page: 30
    yearly: true
    monthly: true
    daily: false
    order_by: -date
    archive_dir: archive


    category_generator: ## https://github.com/hexojs/hexo-generator-category
    per_page: 75
    order_by: name
    category_dir: category
    category_map:

    # Generate categories from directory-tree
    # Dependencies: https://github.com/xu-song/hexo-auto-category
    # depth: the max_depth of directory-tree you want to generate, should > 0
    auto_category:
    enable: true
    depth: false
    default_category: uncategorized


    ## Set per_page to `false` to disable pagination
    tag_generator: ## https://github.com/hexojs/hexo-generator-tag
    per_page: 20
    order_by: name
    tag_dir: tag
    tag_map:

    # Pagination
    pagination_dir: page


    # Metadata elements
    ## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
    meta_generator: true

    # Date / Time format
    ## Hexo uses Moment.js to parse and display date
    ## You can customize the date format as defined in
    ## http://momentjs.com/docs/#/displaying/format/
    date_format: YYYY-MMM-DD
    time_format: HH:mm:ss
    updated_option: mtime ## updated_option supports: mtime | date | empty

    # Include / Exclude file(s)
    ## include:/exclude: options only apply to the 'source/' folder
    include: null
    exclude: null
    ignore: null


    ## Themes: https://hexo.io/themes/
    theme: 2022.richiebartlett.com






    ###################################################################
    # <<<<<<<<< Extensions >>>>>>>>>>>>>>>>
    ## Plugins: https://hexo.io/plugins/
    plugins:
    # https://github.com/hexojs/hexo-generator-feed
    # https://github.com/hexojs/hexo-renderer-markdown-it
    # https://github.com/LouisBarranqueiro/hexo-footnotes
    # https://github.com/tea3/hexo-tag-twitter
    # https://github.com/HCLonely/hexo-calendar
    # https://github.com/quocvu/hexo-tag-youtube-responsive
    # https://github.com/tuanna-hsp/hexo-tag-wikipedia


    ## https://github.com/ludoviclefevre/hexo-generator-seo-friendly-sitemap
    sitemap:
    path: sitemap.xml
    tag: true
    category: true


    ## https://github.com/AsemAlhaidary/hexo-search-generator
    search:
    path: search.xml
    field: post
    content: true
    root: /
    # template: ./search.xml

    database:
    path: db.xml
    fields: [post]


    ## https://github.com/hexojs/hexo-generator-feed
    feed:
    enable: true
    type: ['atom', 'rss2']
    path: [atom.xml, rss2.xml]
    limit: 20
    hub:
    content:
    content_limit: 140
    content_limit_delim: ' '
    order_by: -date
    icon: icon.png
    autodiscovery: true
    template:

    ## https://github.com/next-theme/hexo-filter-mathjax
    mathjax:
    tags: all # none # or 'ams' or 'all'
    single_dollars: true # enable single dollar signs as in-line math delimiters
    cjk_width: 0.9 # relative CJK char width
    normal_width: 0.6 # relative normal (monospace) width
    append_css: true # add CSS to pages rendered by MathJax
    every_page: false # if true, every page will be rendered by MathJax regardless the `mathjax` setting in Front-matter

    ## https://github.com/LouisBarranqueiro/hexo-footnotes
    footnote:
    location_target_class: FootnoteTarget

    advertiser:

    Be sure to update the blog domain to your site.

    Need to ensure the correct npm packages are installed

    package.json
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    {
    "name": "hexo.blog.RichieBartlett.com",
    "version": "2022.04.21",
    "private": true,
    "scripts": {
    "build": "hexo generate",
    "hexo-calendar": "hexo gc",
    "clean": "hexo clean",
    "deploy": "hexo deploy",
    "server": "hexo server"
    },
    "hexo": {
    "version": "6.3.0"
    },
    "dependencies": {
    "expand-range": "^2.0.2",
    "filename-regex": "^2.0.1",
    "hexo": "^6.3.0",
    "hexo-auto-category": "^0.2.1",
    "hexo-calendar": "^1.0.5",
    "hexo-filter-mathjax": "^0.9.0",
    "hexo-footnote": "^1.0.4",
    "hexo-generator-archive": "^1.0.0",
    "hexo-generator-category": "^1.0.0",
    "hexo-generator-database": "^1.1.2",
    "hexo-generator-feed": "^3.0.0",
    "hexo-generator-index": "^2.0.0",
    "hexo-generator-seo-friendly-sitemap": "^0.2.1",
    "hexo-generator-tag": "^1.0.0",
    "hexo-renderer-ejs": "^2.0.0",
    "hexo-renderer-markdown-it": "^6.1.0",
    "hexo-renderer-stylus": "^2.1.0",
    "hexo-search-generator": "^2.0.2",
    "hexo-server": "^3.0.0",
    "hexo-tag-twitter": "^1.0.2",
    "hexo-tag-wikipedia": "^1.0.1",
    "hexo-tag-youtube-responsive": "^0.4.2",
    "is-posix-bracket": "^0.1.1",
    "object.omit": "^3.0.0",
    "parse-glob": "^2.0.1",
    "preserve": "^0.2.0",
    "regex-cache": "^0.4.4"
    },
    "devDependencies": {
    "eslint-config-hexo": "^5.0.0",
    "hexo-util": "^2.7.0"
    }
    }

    After copying this file to the root of the project, run npm install to download all the dependencies.

    scaffolds

    Scaffolds are essentially template files with default values defined in the front-matter section of the markdown file. When you specify hexo new draft ... on the command line, you are telling Hexo to use the draft.md file in the /scaffolds/ folder. My theme has some expected values and I define them well in the scaffolds. You’ll need to copy these files to your project folder.

    /scaffolds/draft.md
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    ---
    title: {{ title }} ### Review: https://hexo.io/docs/variables
    slug: {{ slug }}
    date: {{ date }} ## PUBLISHED date
    updated: {{ date }} ## when you last updated this post
    tags: ## feature to link posts across multiple categories
    - draft
    # categories: {folder name} ## this is replaced by the HEXO plug-in https://github.com/xu-song/hexo-auto-category
    sticky: 999 ## Sticks a post below the recommended section in order specified <#>; "1" will be at the very top
    comments: true #allow comments integration? See theme/_config.yml
    lang: en ## 2-digit language code [+ 2-digit country code]
    draft: draft
    toc: true ## display the table of contents?
    tocOpen: true ## display the ToC open?
    indexing: false ## post is searchable?
    display_tag_onHome: true # display tags for this post?
    swiper: false ## show on home page swiper?
    # swiperDesc: '我是文章在轮播图中的摘要' ## typewriter text under post.title
    # swiperImg: '/img/1.jpg' ## Carousel background image
    recommendedSection: false ## post appears in Recommended articles section on home page
    donate: false ## display the tip button?
    geolocation: Planet Earth
    mathjax: false ## post has LaTeX code?
    share: false ## display social media connection at end of article

    ### when copy&paste from other source: be sure to credit the original Author!
    ## https://www.gnu.org/gwm/libredocxml/x53.html#:~:text=A%20copyright%20infers%20that%20only,community%2C%20provided%20it%20remains%20Libre.
    ## https://www.geeksforgeeks.org/difference-between-copyright-and-copyleft-in-foss/
    copy:
    right: true ## display copyright notice on post
    left: false ## Unicode Character 'COPYLEFT SYMBOL' (U+1F12F)
    License:
    type: false ## declare a different license than the global default set in the _config.yml
    url: false ## link to the online license definitions
    desc: false ## text to briefly describe the license
    origin:
    url: false ## if not `false`, point to SOURCE where post was copied
    author:
    name: false ## if `false`, defaults to global config for `author`
    img: false ## if `false`, defaults to global config for `image`
    published: false ## date the original article was posted


    excerpt: '' ## this blurb is what's displayed on the article summary from the home page/feed.

    # img: /img/1.jpg ## article card image @ page banner
    img: ''
    openGraph_img: false #[PNG/JPG]

    type: HEXO/post
    sitemap: false ## set to `false` to exclude from search engine sitemap
    ---
    /scaffolds/post.md
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    ---
    title: {{ title }} ### Review: https://hexo.io/docs/variables
    slug: {{slug}}
    date: {{ date }} ## PUBLISHED date
    updated: {{ date }} ## when you last updated this post
    tags: ## feature to link posts across multiple categories
    - tagged
    ## tags should be limited to a absolute max of 7; Ideally 3
    categories: ## this is replaced by the HEXO plug-in https://github.com/xu-song/hexo-auto-category
    - automaticallyOverwritten
    sticky: 999 ## Sticks a post below the recommended section in order specified <#>; "1" will be at the very top
    comments: true #allow comments integration? See theme/_config.yml
    lang: en ## { ISO 639-1 Code }#_{ ISO 3166-1 alpha-2 }
    toc: true ## display the table of contents?
    tocOpen: true ## display the ToC open?
    indexing: true ## post is searchable?
    display_tag_onHome: true # display tags for this post?
    swiper: false ## show on home page swiper?
    # swiperDesc: 'typewriter' ## typewriter text under post.title
    # swiperImg: '/img/1.jpg' ## background image
    recommendedSection: false ## post appears in Recommended articles section on home page
    donate: true ## display the tip button?
    # geolocation: "Niseko, Hokkaido, Japan"
    geolocation: "Shibukawa, Gunma, Japan"
    mathjax: false ## post has LaTeX code?
    share: false ## display social media connection at end of article
    keywords: false ## words or phrase that search engines will use to associate your content.

    ### when copy&paste from other source: be sure to credit the original Author!
    ## https://www.gnu.org/gwm/libredocxml/x53.html#:~:text=A%20copyright%20infers%20that%20only,community%2C%20provided%20it%20remains%20Libre.
    ## https://www.geeksforgeeks.org/difference-between-copyright-and-copyleft-in-foss/
    copy:
    right: true ## display copyright notice on post
    left: false ## Unicode Character 'COPYLEFT SYMBOL' (U+1F12F)
    License:
    type: false ## declare a different license than the global default set in the _config.yml
    url: false ## link to the online license definitions
    desc: false ## text to briefly describe the license
    origin:
    url: false ## if not `false`, point to SOURCE where post was copied
    author:
    name: false ## if `false`, defaults to global config for `author`
    img: false ## if `false`, defaults to global config for `image`
    published: false ## date the original article was posted


    # img: /img/1.jpg ## article card image @ page banner
    img: false
    openGraph_img: false #[PNG/JPG]
    readTime: false ## amount of time in seconds to read this post
    wordCount: false ## number of HTML stripped words counted in post
    related: [] ## list of posts (slugs) to associate with this article
    excerpt: "" ## this blurb is what's displayed on the article summary from the home/feed page.


    ## vscode::FrontMatter variable for article status
    draft: draft ## status: [draft, in progress, published]
    published: false ## must be enabled before post is rendered!

    type: HEXO/post ## for vscode::FrontMatter
    sitemap: true ## set to `false` to exclude from search engine sitemap
    ---

    ```md /scaffolds/page.md
    ---
    title: {{ title }}
    date: {{ date }}
    photos: [] ## The photos of the article (Used in gallery posts)
    ---

    basic commands

    As your blog grows in size, you’ll notice that it starts to take longer to build the site. This is because Hexo is comparing the posts with the db.json file it builds each run. I found it much faster to force a clean run by adding hexo clean to the command before building or testing.

    When I’m testing the site locally, I simply run:
    hexo clean && hexo server

    After confirming that everything looks as expected, I’ll build the site:
    hexo clean && hexo gc -w=100 && hexo gen
    This will clear the database file, extract the calendar data for 100 weeks, and generate the site.

    Node heap memory

    As more advanced features are added to the theme, the amount of memory required to process it will increase. Here’s the command to increase Node’s memory allocation.

    1
    export NODE_OPTIONS=--max-old-space-size=8192

    This will increase the memory buffer to 8GB. For my project with over 1400 posts, I needed to increase it to 14GB before it would compile completely. Needless to say, your hardware will need to accommodate these requirements.

    FrontMatter

    Setup FrontMatter plugin:

    As of FrontMatter version 8.1.2, it doesn’t support Hexo out-of-the-box, but it does a great job of providing a headless CMS. I requested the creator to add support - frontMatter.framework.id: “HEXO”. Hopefully, you are reading this after a newer version is published.

    In the root of your project you’ll need to overwrite this configuration file.

    🧑🏻‍💻 frontmatter.json
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    {
    "$schema": "https://frontmatter.codes/frontmatter.schema.json",
    "frontMatter.taxonomy.contentTypes": [{
    "name": "default",
    "pageBundle": false,
    "previewPath": null,
    "fields": [{
    "title": "Title",
    "name": "title",
    "type": "string"
    },
    {
    "title": "Description",
    "name": "description",
    "type": "string"
    },
    {
    "title": "Publishing date",
    "name": "date",
    "type": "datetime",
    "default": "{{now}}",
    "isPublishDate": true
    },
    {
    "title": "Content preview",
    "name": "preview",
    "type": "image"
    },
    {
    "title": "Is in draft",
    "name": "draft",
    "type": "choice",
    "choices": ["draft", "in progress", "published"]
    },
    {
    "title": "Tags",
    "name": "tags",
    "type": "tags"
    },
    {
    "title": "Categories",
    "name": "categories",
    "type": "categories",
    "hidden": true
    }
    ]
    },
    {
    "name": "HEXO/post",
    "pageBundle": false,
    "previewPath": null,
    "fields": [{
    "title": "Title",
    "name": "title",
    "type": "string",
    "editable": true,
    "required": true
    },
    {
    "title": "Slug",
    "name": "slug",
    "type": "slug",
    "editable": true,
    "default": "{{slug}}"
    },
    {
    "title": "Description",
    "name": "excerpt",
    "type": "string",
    "single": false,
    "editable": true
    },
    {
    "title": "Keywords",
    "name": "keywords",
    "type": "list",
    "description": "SEO phrase/words for finding this post",
    "default": false,
    "editable": true,
    "single": true,
    "hidden": true
    },
    {
    "title": "Publish date",
    "name": "date",
    "type": "datetime",
    "default": "{{now}}",
    "isPublishDate": true,
    "editable": false,
    "required": true
    },
    {
    "title": "Updated time",
    "name": "updated",
    "type": "datetime",
    "default": "{{now}}",
    "editable": false,
    "single": true,
    "isModifiedDate": true
    },
    {
    "title": "Tags",
    "name": "tags",
    "type": "tags",
    "description": "Tags should be limited to a absolute max of 7; \n Ideally 3...",
    "taxonomyLimit": 10,
    "editable": true
    },
    {
    "title": "Categories",
    "name": "categories",
    "type": "categories",
    "description": "this is replaced by the HEXO plug-in [hexo-auto-category](https://github.com/xu-song/hexo-auto-category)",
    "hidden": true
    },
    {
    "title": "Related Posts",
    "name": "related",
    "type": "list",
    "description": "List of related articles. (Use {SLUG} only!) Ideally 2~4 links recommended.",
    "taxonomyLimit": 5,
    "editable": true
    },
    {
    "title": "Post Image (PNG / JPG / SVG)",
    "name": "img",
    "editable": true,
    "type": "image",
    "description": "This is the main photo displayed on the website. SVG is recommended, but sometimes not possible if too complex.",
    "isPreviewImage": true
    },
    {
    "title": "OpenGraph image (JPG / PNG)",
    "name": "openGraph_img",
    "type": "image",
    "description": "This is the image used by FB, Twitter, or any social media site. SVG _not_ supported.",
    "default": false,
    "editable": true
    },
    {
    "title": "Post Language",
    "name": "lang",
    "type": "string",
    "description": "{ [ISO 639-1 Code](https://en.wikipedia.org/wiki/ISO_639-1) }",
    "default": "en",
    "editable": true,
    "single": true,
    "required": true
    },
    {
    "name": "divider",
    "type": "divider"
    },
    {
    "title": "Swiper Post?",
    "name": "swiper",
    "description": "Enable if you want to give PRIORITY to this post by displaying in the SWIPER section. Best to limit this to post that users will swipe left or right to view. Most post will be displayed by scrolling down.",
    "type": "boolean",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Pin this post at top?",
    "name": "sticky",
    "description": "Select a priority between 1 and 98 (1 = very top) for this post to be displayed.",
    "type": "number",
    "default": 999,
    "editable": true,
    "single": true
    },
    {
    "title": "Enable ToC?",
    "name": "toc",
    "type": "boolean",
    "description": "Display the Table of Contents?",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "Default ToC open?",
    "name": "tocOpen",
    "type": "boolean",
    "description": "Should the Table of Contents be open already?",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "Allow indexing and search for this post's contents?",
    "name": "indexing",
    "type": "boolean",
    "description": "Enable for internal site's search engine.",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "Add to sitemap?",
    "name": "sitemap",
    "type": "boolean",
    "description": "Enabling this allows search engines to be aware of your articles/content.",
    "default": true,
    "single": true,
    "editable": true
    },
    {
    "title": "Display tags on Home?",
    "name": "display_tag_onHome",
    "type": "boolean",
    "description": "Show the tags for this post in the feed pages?",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "Show in top recommended section on home page?",
    "name": "recommendedSection",
    "type": "boolean",
    "description": "Display this post in the recommended section below the top 'HERO' banner?",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Show donate button?",
    "name": "donate",
    "type": "boolean",
    "description": "This is great for crowd funding your work. However, don't enable this for copy/paste news reports.",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Enable MathJax",
    "name": "mathjax",
    "type": "boolean",
    "description": "If using math formulas, good to enable this.",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Show share icons?",
    "name": "share",
    "type": "boolean",
    "description": "Display the SNS icons or bot to share this post.",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "Enable comments?",
    "name": "comments",
    "type": "boolean",
    "description": "Enable DISQUS tool for comments?",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "COPY",
    "name": "copy",
    "type": "fields",
    "fields": [{
    "title": "Display copyright notice on post?",
    "name": "right",
    "type": "boolean",
    "description": "Should enable this if copied from other _copyrighted_ source... Or, if you have copyrighted it, then enable.",
    "default": true,
    "editable": true,
    "single": true
    },
    {
    "title": "Display copyleft notice on post?",
    "name": "left",
    "type": "boolean",
    "description": "_copyleft_? Unicode Character 'COPYLEFT SYMBOL' (U+1F12F)",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "License",
    "name": "License",
    "type": "fields",
    "fields": [{
    "title": "License Type",
    "name": "type",
    "description": "Declare a different license than the global default set in the _config.yml",
    "type": "string",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "URL of License",
    "name": "url",
    "description": "Link to the online license definitions",
    "type": "string",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Description of License",
    "name": "desc",
    "description": "Briefly describe the license",
    "type": "string",
    "default": false,
    "editable": true,
    "single": true
    }
    ]
    }
    ]
    },
    {
    "title": "origin",
    "name": "origin",
    "description": "Original post where this was copy/pasted.",
    "type": "fields",
    "fields": [
    {
    "title": "URL",
    "name": "url",
    "description": "Original post where this was copy/pasted.",
    "type": "string",
    "editable": true,
    "default": false,
    "single": true
    },
    {
    "title": "Author",
    "name": "author",
    "type": "fields",
    "fields": [
    {
    "title": "Name",
    "name": "name",
    "description": "{First_name} {LAST_NAME} -or- '@username'",
    "type": "string",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Image",
    "name": "img",
    "description": "URL to the author's image",
    "type": "string",
    "default": false,
    "editable": true,
    "single": true
    }
    ]
    },
    {
    "title": "Publish Date",
    "name": "published",
    "type": "datetime",
    "default": false,
    "editable": true,
    "single": true
    }
    ]
    },
    {
    "title": "Location on Earth",
    "name": "geolocation",
    "type": "string",
    "description": "Provide either a coordinate or text string that Google Maps can display. Where did you write this post?",
    "default": "'Chiba, Japan'",
    "editable": true,
    "single": true
    },
    {
    "title": "Read Time (autogenerated)",
    "name": "readTime",
    "type": "number",
    "editable": false,
    "default": false,
    "single": true,
    "hidden": true
    },
    {
    "title": "Word Count (autogenerated)",
    "name": "wordCount",
    "type": "number",
    "default": false,
    "editable": false,
    "single": true,
    "hidden": true
    },
    {
    "name": "divider",
    "type": "divider"
    },
    {
    "title": "Publish it?",
    "name": "published",
    "type": "boolean",
    "description": "Display the post in feed?",
    "default": false,
    "editable": true,
    "single": true
    },
    {
    "title": "Draft Status",
    "name": "draft",
    "type": "choice",
    "choices": ["draft", "in progress", "published"],
    "default": "draft",
    "single": true,
    "editable": true
    },
    {
    "title": "type",
    "name": "type",
    "type": "string",
    "default": "HEXO/post",
    "hidden": true
    }
    ]
    },
    {
    "name": "HEXO/page",
    "pageBundle": true,
    "fields": [{
    "title": "Title",
    "name": "title",
    "type": "string",
    "editable": true,
    "required": true
    },
    {
    "title": "Description",
    "name": "description",
    "type": "string",
    "editable": true
    },
    {
    "title": "Page Image",
    "name": "img",
    "editable": true,
    "type": "string",
    "isPreviewImage": true
    },
    {
    "title": "Publish date",
    "name": "date",
    "type": "datetime",
    "default": "{{now}}",
    "isPublishDate": true,
    "editable": false,
    "required": true
    },
    {
    "title": "layout",
    "name": "layout",
    "type": "string",
    "default": "page"
    },
    {
    "title": "Allow indexing and search for this post's contents?",
    "name": "indexing",
    "type": "boolean",
    "default": true,
    "editable": true,
    "single": true
    }
    ]
    }
    ],
    "frontMatter.taxonomy.tags": [],
    "frontMatter.taxonomy.categories": [],
    "frontMatter.content.defaultFileType": "md",
    "frontMatter.content.fmHighlight": true,
    "frontMatter.content.hideFm": false,
    "frontMatter.content.pageFolders": [{
    "title": "Page",
    "path": "[[workspace]]/source",
    "excludeSubdir": true
    },
    {
    "title": "Post",
    "path": "[[workspace]]/source/_posts"
    },
    {
    "title": "Draft",
    "path": "[[workspace]]/source/_drafts"
    }
    ],
    "frontMatter.content.publicFolder": "[[workspace]]/public",
    "frontMatter.data.folders": [{
    "id": "HEXO/data",
    "title": "Custom data",
    "file": "[[workspace]]/source/data/*.json",
    "fileType": "json"
    },
    {
    "id": "sponsors",
    "title": "Sponsors",
    "file": "[[workspace]]/source/data/sponsors.json",
    "fileType": "json",
    "labelField": "name",
    "schema": {
    "title": "Sponsors",
    "type": "object",
    "required": [
    "name",
    "url"
    ],
    "properties": {
    "name": {
    "type": "string",
    "title": "Name"
    },
    "url": {
    "type": "string",
    "title": "URL"
    },
    "description": {
    "type": "string",
    "title": "Description"
    }
    }
    }
    }
    ],
    "frontMatter.file.preserveCasing": true,
    "frontMatter.framework.id": "HEXO",
    "frontMatter.framework.startCommand": "hexo clean && hexo server",
    "frontMatter.preview.host": "http://127.0.0.0:4000/",
    "frontMatter.preview.pathName": "{{slug}}/",
    "frontMatter.taxonomy.dateFormat": "YYYY/MM/dd",
    "frontMatter.taxonomy.frontMatterType": "YAML",
    "frontMatter.taxonomy.seoContentLength": 2400,
    "frontMatter.taxonomy.indentArrays": true,
    "frontMatter.taxonomy.fieldGroups": [],
    "frontMatter.templates.enabled": true,
    "frontMatter.templates.folder": ".frontmatter/templates",
    "frontMatter.templates.prefix": "",
    "frontMatter.content.draftField": {
    "name": "draft",
    "type": "choice",
    "choices": ["draft", "in progress", "published"]
    },
    "frontMatter.dashboard.content.pagination": true
    }

    Once you’ve updated FrontMatter’s configuration, you can click on the FM tab in VScode to see the panel now supports HEXO with my custom theme.

    Setup GitHub

    This repo uses LFS

    Run the following command to enable proper authentication with GitHub LFS servers:

    1
    git config lfs.https://github.com/{{username}}/{{blog_project_name}}.git/info/lfs.access basic

    Update Git Buffers

    It appears that the default git buffer is too small for sites with large posts or video files. Need to set it to the max:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    git config --global http.postBuffer 2048M
    git config --global http.maxRequestBuffer 1024M
    git config --global core.compression 9

    git config --global ssh.postBuffer 2048M
    git config --global ssh.maxRequestBuffer 1024M

    git config --global pack.windowMemory 256m
    git config --global pack.packSizeLimit 256m

    Git buffer requirements will depend on the amount of RAM available to your machine.

    Support long filenames

    This issue affects mostly Windows users. You may need to run this as Administrator for it to be effective.

    1
    2
    git config --system core.longpaths true
    git config --global core.longpaths true

    Basic blog workflow

    1. Find topic for discussion. I often see an image of something that sparks an idea to discuss. As I do everything on my MacBookPro, MacOS has case sensitive filenames. So, I try to be mindful of this when creating the blog title. If I start the title in all lowercase, then the filename will be lowercase too. From the command line, create a new draft:
      hexo new draft "My new idea or thought"
    2. View the basic preview within VScode until I’m ready to preview it with the theme. FrontMatter can run the HEXO server for you and display the preview live within VScode.
    3. When I’m satisfied with the article, I’ll update the draft and publish status in FrontMatter panel. I’ll also review all the options for the article to ensure I have the best keywords, tags, related posts, description, etc.
    4. Build the site and make sure no errors are found.
    5. Commit the updates to git and push to my repo.
    6. Assuming my Ci/Cd automation is working, then I should see the page on my live website within 10 minutes.

    Reference

    Prev:
    AWS CloudFront CI/CD Pipeline With ECS and GitHub
    Next:
    My Journey to Veganism
    Table of Contents
    Table of Contents