Managing hugo blog entries in 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 aindex.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