Sytone's Ramblings

The occasional posts of a guy who plays with technology.

Managing hugo blog entries in Obsidian

2022-03-04 4 min read Obsidian

To make using and blogging simpler I have made some scripts, templates and quickadd commands to make a new article for my blog and then be able to run a PowerShell script to publish it.

Environment

For this process to work you will need the following.

  • Your blog setup in a git repo so when changes are pushed it builds and deploys the updated site.

    You could update the script to push to git with a manual local hugo build and push.

  • PowerShell Core installed (Windows, Linux and Mac are supported)
  • Templater plugin enabled in Obsidian
  • Quick Add plugin enabled in Obsidian

Setup

  • Copy the content folder from you local repo to a folder in obsidian.
  • Make a note of the folder in Obsidian, I will be using /400 Reference/Blog/personal in this setup.
  • Determine structure of articles. For my layout I have an article folder and under that a folder for each article with a index.md file holding the article entry. You will need to change the path where the blog entry is created for your setup if it differs.
  • Create a template for the blog article. This is the template I use below. It is using parameters from quick add and templater. Make sure you record the template name and location. For my setup it is DataStores/Templates/400_BlogArticle.md
---
title: "{{VALUE:articleName}}"
date: 2022-03-04T15:48:38
tags: ["git"]
categories: ["Development"]
author: ""
toc: false
draft: false
description: "{{VALUE:articleDescription}}"
---

{{VALUE:articleDescription}}

Add more details here before the continue reading link...

<!--more-->

## First heading
  • Create a script somewhere in you obsidian vault called get_blog_article_name.js Quick Add needs to be able to access this.
  • In this file add the following script. This will prompt for the article title and description. It will also generate the folder name for you.
module.exports = async (params) => {
    QuickAdd = params;
    const name = await QuickAdd.quickAddApi.inputPrompt("Blog - Article Name");
    const description = await QuickAdd.quickAddApi.inputPrompt("Blog - Article Description");
    const folderName = name.toLowerCase().replace(/ /g, "-");

    QuickAdd.variables["articleName"] = name;
    QuickAdd.variables["articleDescription"] = description;
    QuickAdd.variables["articleFolder"] = folderName;

    console.log(QuickAdd.variables);
};
  • Create a new macro in quick add called Add Blog Article
  • Add a User Script as the first entry, make sure you select get_blog_article_name.js
  • Next add a template and select the file you created above (DataStores/Templates/400_BlogArticle.md)
  • Enable setting the file name. The value for my setup is /400 Reference/Blog/personal/article/{{VALUE:articleFolder}}/index
  • If you want the article to open after creation then select open file.
  • Go back to the main Quick Add menu and add the Macro to the list. I creatively called mine Add Blog Article
  • Run the new Quick Add command and check to see if the new article is created alongside your other articles. If it is you are in a good place.
  • I have the following Dataview query to list all my articles to make it simpler to find them.
```dataviewjs
dv.table(["Title","Date"],dv.pages('"400 Reference/Blog/personal"')
    .sort(p => p.date, 'desc')
    .map(b => ['[['+b.file.path+'|'+b.title+']]', b.date])
)
```
  • Once you have your setup in place to create and edit articles you need a way to publish. The PowerShell script below will clone your git repo to a temp directory and copy the files over. It will then commit any changes and push them. You can run this manually or via the templater scripts. I will leave that to you to decide.

# This needs to be the root of the vault. I store this script in Datastore/scripts
# so this goes up two levels.
$root = "$PSScriptRoot/../.."
# This is the path to the content of your blog.
$blogContentRoot = "$root/400 Reference/Blog/personal"
$blogContentRoot = Resolve-Path $blogContentRoot

$checkoutPath = $env:TEMP
$repoFolder = Join-Path $checkoutPath "personal-blog$(Get-Date -Format 'yyyyMMddhhmmss')"
$repoUri = '<git repo path to clone locally.>'

Push-Location

if (!(Test-Path -Path $checkoutPath)) {
    New-Item -ItemType directory -Path $checkoutPath
}
Set-Location $checkoutPath

if (!(Test-Path -Path $repoFolder)) {
    Write-Host("Cloning $repoUri into $repoFolder")
    git clone --depth 1 $repoUri $repoFolder 2>&1 | Write-Host
}
Set-Location $repoFolder

# This is an alias I have to set name and email for local repo, comment
# out if you have this globally set.
git pid

# Copy the blog content to the repo, update the destination path as needed.
Copy-Item -Path $blogContentRoot/* -Destination "$repoFolder/hugo-blog/content/" -Recurse -Force

git status

[string] $status = (& git status)
if (!$status.Contains('working tree clean')) {
    git add .
    git commit -m 'blog update from obsidian'
}

git push origin master

Pop-Location
Remove-Item -Path $repoFolder -Force -Recurse