This is a notes page for how this blog was created. It is in reference to the NetworkChuck Blog Video
I have added some additional notes to clarify some areas that I originally stumbled on to get everything working. I also removed some unnecessary steps.
Prepare Obsidian
- Download and Install Obsidian
- Create a ‘posts’ folder in Obsidian root
- Create an ‘images’ directory in Obsidian root
- Open Obsidian Settings to Tell Obsidian to use the new ‘images’ directory to store and reference images.
Add Some Frontmatter to a Page
This allows the template to display meta data about your blog post. It should be placed at the top of your Obsidian note. To add this ‘Frontmatter’ meta data, put the Obsidian note page into ‘Source mode’ by using the 3 dots menu at the top right of the page.
---
title: blogtitle
date: 2024-11-06
draft: false
tags:
- tag1
- tag2
---
Install and Configure Hugo and GitHub Repo
Install Hugo
sudo apt install hugo
Verify Hugo works
hugo version
Create a new Hugo site
hugo new site websitename
cd websitename
Install and Configure a GitHub Repo
Create a new repository for your project
git init
Add all files in website directory to git
git add .
Commit the files
git commit -m "Initial commit"
Download the Terminal Theme as a Git Submodule
git submodule add -f https://github.com/panr/hugo-theme-terminal.git themes/terminal
Update the ‘hugo.toml’ file at the root of the hugo site Note: The config on the github fails since it is looking for a module. The NetworkChuck code works, but the 6th line needs to be replaced with ‘pagerSize = 5’
baseurl = "/"
languageCode = "en-us"
# Add it only if you keep the theme in the `themes` directory.
# Remove it if you use the theme as a remote Hugo Module.
theme = "terminal"
pagerSize = 5
[params]
# dir name of your main content (default is `content/posts`).
# the list of set content will show up on your index page (baseurl).
contentTypeName = "posts"
# if you set this to 0, only submenu trigger will be visible
showMenuItems = 2
# show selector to switch language
showLanguageSelector = false
# set theme to full screen width
fullWidthTheme = false
# center theme with default width
centerTheme = false
# if your resource directory contains an image called `cover.(jpg|png|webp)`,
# then the file will be used as a cover automatically.
# With this option you don't have to put the `cover` param in a front-matter.
autoCover = true
# set post to show the last updated
# If you use git, you can set `enableGitInfo` to `true` and then post will automatically get the last updated
showLastUpdated = false
# Provide a string as a prefix for the last update date. By default, it looks like this: 2020-xx-xx [Updated: 2020-xx-xx] :: Author
# updatedDatePrefix = "Updated"
# whether to show a page's estimated reading time
# readingTime = false # default
# whether to show a table of contents
# can be overridden in a page's front-matter
# Toc = false # default
# set title for the table of contents
# can be overridden in a page's front-matter
# TocTitle = "Table of Contents" # default
[params.twitter]
# set Twitter handles for Twitter cards
# see https://developer.twitter.com/en/docs/tweets/optimize-with-cards/guides/getting-started#card-and-content-attribution
# do not include @
creator = ""
site = ""
[languages]
[languages.en]
languageName = "English"
title = "Terminal"
[languages.en.params]
subtitle = "A Hobo Theme"
owner = ""
keywords = ""
copyright = ""
menuMore = "Show more"
readMore = "Read more"
readOtherPosts = "Read other posts"
newerPosts = "Newer posts"
olderPosts = "Older posts"
missingContentMessage = "Page not found..."
missingBackButtonLabel = "Back to home page"
minuteReadingTime = "min read"
words = "words"
[languages.en.params.logo]
logoText = "Terminal"
logoHomeLink = "/"
[languages.en.menu]
[[languages.en.menu.main]]
identifier = "services"
name = "Professional Services"
url = "/services"
[[languages.en.menu.main]]
identifier = "photography"
name = "Photography"
url = "/photography"
Images.py Script
Create a file in the project root called ‘images.py’ and place this code:
import os
import re
import shutil
# Paths
# posts_dir is the site's post directory, not Obsidians
posts_dir = "/path/to/blog/posts"
attachments_dir = "/path/to/obsidian/images"
static_images_dir = "/path/to/blog/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") as file:
content = file.read()
# Step 2: Find all image links in the markdown
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"[Image Description](/images/{image.replace(' ', '%20')})"
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") as file:
file.write(content)
print("Markdown files processed and images copied successfully.")
MEGA SCRIPT
Create a file in the project root called ‘megascript.sh’ and place this code:
#!/bin/zsh
set -euo pipefail
# Change to the script's directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Set variables for Obsidian to Hugo copy
sourcePath="/path/to/obsidian/posts"
destinationPath="/path/to/blog/content/directory"
# Set GitHub Repo
myrepo="reponame"
# Check for required commands
for cmd in git rsync python3 hugo; do
if ! command -v $cmd &> /dev/null; then
echo "$cmd is not installed or not in PATH."
exit 1
fi
done
# Step 1: Check if Git is initialized, and initialize if necessary
if [ ! -d ".git" ]; then
echo "Initializing Git repository..."
git init
git remote add origin $myrepo
else
echo "Git repository already initialized."
if ! git remote | grep -q 'origin'; then
echo "Adding remote origin..."
git remote add origin $myrepo
fi
fi
# Step 2: Sync posts from Obsidian to Hugo content folder using rsync
echo "Syncing posts from Obsidian..."
if [ ! -d "$sourcePath" ]; then
echo "Source path does not exist: $sourcePath"
exit 1
fi
if [ ! -d "$destinationPath" ]; then
echo "Destination path does not exist: $destinationPath"
exit 1
fi
rsync -av --delete "$sourcePath" "$destinationPath"
# Step 3: Process Markdown files with Python script to handle image links
echo "Processing image links in Markdown files..."
if [ ! -f "images.py" ]; then
echo "Python script images.py not found."
exit 1
fi
if ! python3 images.py; then
echo "Failed to process image links."
exit 1
fi
# Step 4: Build the Hugo site
echo "Building the Hugo site..."
if ! hugo; then
echo "Hugo build failed."
exit 1
fi
# Step 5: Add changes to Git
echo "Staging changes for Git..."
if git diff --quiet && git diff --cached --quiet; then
echo "No changes to stage."
else
git add .
fi
# Step 6: Commit changes with a dynamic message
commit_message="New Blog Post on $(date +'%Y-%m-%d %H:%M:%S')"
if git diff --cached --quiet; then
echo "No changes to commit."
else
echo "Committing changes..."
git commit -m "$commit_message"
fi
# Step 7: Push all changes to the main branch
echo "Deploying to GitHub Main..."
if ! git push origin main; then
echo "Failed to push to main branch."
exit 1
fi
# Step 8: Push the public folder to the hostinger branch using subtree split and force push
echo "Deploying to GitHub Hostinger..."
if git branch --list | grep -q 'hostinger-deploy'; then
git branch -D hostinger-deploy
fi
if ! git subtree split --prefix public -b hostinger-deploy; then
echo "Subtree split failed."
exit 1
fi
if ! git push origin hostinger-deploy:hostinger --force; then
echo "Failed to push to hostinger branch."
git branch -D hostinger-deploy
exit 1
fi
git branch -D hostinger-deploy
echo "All done! Site synced, processed, committed, built, and deployed."
# Display a notification on successful completion MAC OS ONLY
if [[ $? -eq 0 ]]; then
osascript -e 'display notification "MEGAScript completed successfully!" with title "Success" sound name "Funk"'
fi
Make the Script executable
chmod +x megascript.sh
Execute Script
./megascript.sh
Start Hugo Local Server
hugo server
Navigate to test locally or go to your site to see the changes live in production: http://localhost:1313/
Cheers! You’re done and your new blog should be deployed! 🥂
Generate your own Theme
- Go to terminal-css
- Download the generate CSS file.
- Replace file /themes/terminal/assets/css/terminal.css with the CSS file you downloaded.
Fixes if you get GIT merge errors or something weird happens with the data pipeline.
Delete Git Branch
git push -d <remote_name> <branchname> # Delete remote
git branch -d <branchname> # Delete local
Navigate to:Hostinger
Go to: Advanced > GIT > Under Manage Repositories > Delete the repository reference
Navigate to the public_html of your site and delete all the files that get generated. Be sure to delete hidden .git folders.
Run ./megascript.sh to save and sync everything and setup a new clean ‘hostinger’ branch.
Go back to the Hostinger GIT settings and add the reference to the new ‘hostinger’ branch.
Run ./megascript.sh again and it should sync all of your changes to your new blog.
Switching to TeXify theme
Create Hugo Site and GIT Init
hugo new site SITE_NAME && cd SITE_NAME && git init
Install theme GIT module
git submodule add https://github.com/michaelneuper/hugo-texify3.git themes/hugo-texify3
Install required Node.js packages
npm i -D postcss postcss-cli autoprefixer
Install postcss-import module
npm install --save-dev postcss-import
Install PostCSS
npm i -D postcss postcss-cli autoprefixer