Setting Up My First Blog
Table of Contents
Tech stack
- Obsidian
- Hugo
- NetworkChuck’s script
- Hostinger
Obsidian
Obsidian is a FOSS note-taking app that utilizes markdown. It has a lot of plugins and themes for insane customization.
Hugo Set up
Pre-reqs
-
Git install: https://github.com/git-guides/install-git
- free and open-source version control system used for tracking changes in source code during software development
-
Go install: https://go.dev/dl/
- a fast statically typed, compiled high-level general purpose programming language
-
Hugo install: https://gohugo.io/installation/
- framework for building websites
-
Dart Sass install: https://gohugo.io/hugo-pipes/transpile-sass-to-css/#dart-sass
-
I installed via winget `winget install Hugo.Hugo.Extended
-
Once done, close and reopen terminal, run
hugo version
!
Setting up blog with HUGO
- cd to desired directory to store blog
- run command
hugo new site [NAME]
! git init
to create a local repo!git config --global user.name "[YOUR NAME]"
git config --global user.email "[YOUR EMAIL]"
Choose a theme from https://themes.gohugo.io
- I’m using https://themes.gohugo.io/themes/hugo-blog-awesome/
- Follow the instructions in the Setup for the theme. I’m setting up the theme as a Git submodule!
- Following the instructions from the theme:!
- run command in blog directory
notepad hugo.toml
Testing the server
hugo server -t [name of theme]
!- CTRL + click link or type it in!
Adding content to blog
cd .\content\
- We need to sync Obsidian posts folder to Hugo posts folder
mkdir posts
- Windows command
robocopy sourcepath destination path /mir
! - In my
hugo.toml
I copied from the example site and my posts will be going into\drakeblog\content\en\posts
instead because of how the theme is styled - We can run the server again
hugo server
!
Adding images to the blog
cd .\static\
mkdir images
- Run the following python script is made by NetworkChuck and used to transfer images from your obsidion dir to hugo dir. Make sure the paths are correct
- In obisidan make sure to change where attachments are stored by default (NetworkChuck doesn’t mention this)!
import os
import re
import shutil
# Paths (using raw strings to handle Windows backslashes correctly)
posts_dir = r"C:\Users\chuck\Documents\chuckblog\content\posts"
attachments_dir = r"C:\Users\chuck\Documents\my_second_brain\neotokos\Attachments"
static_images_dir = r"C:\Users\chuck\Documents\chuckblog\static\images"
# Step 1: Process each markdown file in the posts directory
for filename in os.listdir(posts_dir):
if filename.endswith(".md"):
filepath = os.path.join(posts_dir, filename)
with open(filepath, "r", encoding="utf-8") as file:
content = file.read()
# Step 2: Find all image links in the format 
images = re.findall(r'\[\[([^]]*\.png)\]\]', content)
# Step 3: Replace image links and ensure URLs are correctly formatted
for image in images:
# Prepare the Markdown-compatible link with %20 replacing spaces
markdown_image = f"})"
content = content.replace(f"[[{image}]]", markdown_image)
# Step 4: Copy the image to the Hugo static/images directory if it exists
image_source = os.path.join(attachments_dir, image)
if os.path.exists(image_source):
shutil.copy(image_source, static_images_dir)
# Step 5: Write the updated content back to the markdown file
with open(filepath, "w", encoding="utf-8") as file:
file.write(content)
print("Markdown files processed and images copied successfully.")
- create
images.py
in root directory of your blog, run it!! - OUR IMAGES SHOW UP IN THE STATIC DIRECTORY AND IMAGES SHOW UP IN THE BLOG!
!
Pushing to Github
- Create your Github Repo
- Make sure you have SSH keys uploaded to github
- test with
ssh -T git@github.com
!
- Pushing to remote
- In your blog’s root directory
git remote add origin git@github.com:[yourUsername]/[reponame].git
- run
hugo
to compile hugo files git add .
to add all files to github repogit commit -m "[your message]
git push -u origin master
!
- Publishing just the public folder to work with Hostinger, a new hostinger branch will be created.
# Step 8: Push the public folder to the hostinger branch using subtree split and force push
echo "Deploying to GitHub Hostinger..."
git subtree split --prefix public -b hostinger-deploy
git push origin hostinger-deploy:hostinger --force
git branch -D hostinger-deploy
!
Hostinger
- You will need to set A-records and all that stuff but I already did so
- In hostinger create an empty php website
- On the left,
hosting plan
>plan details
! - get your website IP
- On the left,
Advanced
>GIT
- Generate SSH Key
- Add SSH Key to github
- Add your blog repo
- Add your hostinger branch
Create!
!
- On the left,
Automation
- Under manage repositories, >
Auto deployment
> copy webhook URL! - Click on
Setup webhook on Github
> paste in URL Add webhook
!- Finally we can use the mega script from NetworkChuck
- Set your variables!!
- run!
# PowerShell Script for Windows
# Set variables for Obsidian to Hugo copy
$sourcePath = "C:\Users\path\to\obsidian\posts"
$destinationPath = "C:\Users\path\to\hugo\posts"
# Set Github repo
$myrepo = "reponame"
# Set error handling
$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest
# Change to the script's directory
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
Set-Location $ScriptDir
# Check for required commands
$requiredCommands = @('git', 'hugo')
# Check for Python command (python or python3)
if (Get-Command 'python' -ErrorAction SilentlyContinue) {
$pythonCommand = 'python'
} elseif (Get-Command 'python3' -ErrorAction SilentlyContinue) {
$pythonCommand = 'python3'
} else {
Write-Error "Python is not installed or not in PATH."
exit 1
}
foreach ($cmd in $requiredCommands) {
if (-not (Get-Command $cmd -ErrorAction SilentlyContinue)) {
Write-Error "$cmd is not installed or not in PATH."
exit 1
}
}
# Step 1: Check if Git is initialized, and initialize if necessary
if (-not (Test-Path ".git")) {
Write-Host "Initializing Git repository..."
git init
git remote add origin $myrepo
} else {
Write-Host "Git repository already initialized."
$remotes = git remote
if (-not ($remotes -contains 'origin')) {
Write-Host "Adding remote origin..."
git remote add origin $myrepo
}
}
# Step 2: Sync posts from Obsidian to Hugo content folder using Robocopy
Write-Host "Syncing posts from Obsidian..."
if (-not (Test-Path $sourcePath)) {
Write-Error "Source path does not exist: $sourcePath"
exit 1
}
if (-not (Test-Path $destinationPath)) {
Write-Error "Destination path does not exist: $destinationPath"
exit 1
}
# Use Robocopy to mirror the directories
$robocopyOptions = @('/MIR', '/Z', '/W:5', '/R:3')
$robocopyResult = robocopy $sourcePath $destinationPath @robocopyOptions
if ($LASTEXITCODE -ge 8) {
Write-Error "Robocopy failed with exit code $LASTEXITCODE"
exit 1
}
# Step 3: Process Markdown files with Python script to handle image links
Write-Host "Processing image links in Markdown files..."
if (-not (Test-Path "images.py")) {
Write-Error "Python script images.py not found."
exit 1
}
# Execute the Python script
try {
& $pythonCommand images.py
} catch {
Write-Error "Failed to process image links."
exit 1
}
# Step 4: Build the Hugo site
Write-Host "Building the Hugo site..."
try {
hugo
} catch {
Write-Error "Hugo build failed."
exit 1
}
# Step 5: Add changes to Git
Write-Host "Staging changes for Git..."
$hasChanges = (git status --porcelain) -ne ""
if (-not $hasChanges) {
Write-Host "No changes to stage."
} else {
git add .
}
# Step 6: Commit changes with a dynamic message
$commitMessage = "New Blog Post on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
$hasStagedChanges = (git diff --cached --name-only) -ne ""
if (-not $hasStagedChanges) {
Write-Host "No changes to commit."
} else {
Write-Host "Committing changes..."
git commit -m "$commitMessage"
}
# Step 7: Push all changes to the main branch
Write-Host "Deploying to GitHub Master..."
try {
git push origin master
} catch {
Write-Error "Failed to push to Master branch."
exit 1
}
# Step 8: Push the public folder to the hostinger branch using subtree split and force push
Write-Host "Deploying to GitHub Hostinger..."
# Check if the temporary branch exists and delete it
$branchExists = git branch --list "hostinger-deploy"
if ($branchExists) {
git branch -D hostinger-deploy
}
# Perform subtree split
try {
git subtree split --prefix public -b hostinger-deploy
} catch {
Write-Error "Subtree split failed."
exit 1
}
# Push to hostinger branch with force
try {
git push origin hostinger-deploy:hostinger --force
} catch {
Write-Error "Failed to push to hostinger branch."
git branch -D hostinger-deploy
exit 1
}
# Delete the temporary branch
git branch -D hostinger-deploy
Write-Host "All done! Site synced, processed, committed, built, and deployed."
We did it!
!