Setting up Hugo Link to heading

Install Hugo Link to heading

Prerequisites Link to heading

Install Hugo Link to heading

Link: https://gohugo.io/installation/

Download a Hugo Theme Link to heading

  • Find themes from this link: https://themes.gohugo.io/
    • follow the theme instructions on how to download. The BEST option is to install as a git submodule

Initialize a git repository (Make sure you are in your Hugo website directory) Link to heading

 1git init
 2
 3## Set global username and email parameters for git
 4
 5git config --global user.name "Your Name"
 6git config --global user.email "your.email@example.com"
 7
 8
 9## Install a theme (we are installing the Terminal theme here). Once downloaded it should be in your Hugo themes folder
10## Find a theme ---> https://themes.gohugo.io/
11
12git submodule add -f https://github.com/luizdepra/hugo-coder.git themes/hugo-coder

Adjust Hugo settings Link to heading

  • Most themes you download will have an example configuration you can use. This is usually the best way to make sure Hugo works well and out of the box.
  • For the hello-friend-ng theme, they gave this example config below.
  • We will edit the hugo.toml file to make these changes. —-> nano hugo.toml (Linux/Mac) or notepad hugo.toml (Windows) or code hugo.toml (All platforms).
 1baseurl = "http://www.example.com"
 2title = "johndoe"
 3theme = "hugo-coder"
 4languagecode = "en"
 5defaultcontentlanguage = "en"
 6
 7
 8[pagination]
 9pagerSize = 20
10
11[services]
12[services.disqus]
13shortname = "yourdiscussshortname"
14
15[markup.highlight]
16style = "github-dark"
17
18[params]
19  author = "John Doe"
20  info = "Full Stack DevOps and Magician"
21  description = "John Doe's personal website"
22  keywords = "blog,developer,personal"
23  avatarurl = "images/avatar.jpg"
24  #gravatar = "john.doe@example.com"
25
26  faviconSVG = "/img/favicon.svg"
27  favicon_32 = "/img/favicon-32x32.png"
28  favicon_16 = "/img/favicon-16x16.png"
29
30  since = 2019
31
32  enableTwemoji = true
33
34  colorScheme = "auto"
35  hidecolorschemetoggle = false
36
37  # customCSS = ["css/custom.css"]
38  # customSCSS = ["scss/custom.scss"]
39  # customJS = ["js/custom.js"]
40
41[taxonomies]
42  category = "categories"
43  series = "series"
44  tag = "tags"
45  author = "authors"
46
47# Social links
48[[params.social]]
49  name = "Github"
50  icon = "fa-brands fa-github fa-2x"
51  weight = 1
52  url = "https://github.com/johndoe/"
53[[params.social]]
54  name = "Gitlab"
55  icon = "fa-brands fa-gitlab fa-2x"
56  weight = 2
57  url = "https://gitlab.com/johndoe/"
58[[params.social]]
59  name = "Twitter"
60  icon = "fa-brands fa-x-twitter fa-2x"
61  weight = 3
62  url = "https://twitter.com/johndoe/"
63
64# Menu links
65[[menu.main]]
66  name = "Blog"
67  weight = 1
68  url  = "posts/"
69[[menu.main]]
70  name = "About"
71  weight = 2
72  url = "about/"

Test Hugo Link to heading

1## Verify Hugo works with your theme by running this command
2
3hugo server -t themename

Walking Through the Steps Link to heading

NOTE: There is a SCRIPT later in this blog that will do everything in one go.

Syncing Obsidian to Hugo Link to heading

Windows Link to heading

1robocopy sourcepath destination path /mir

Mac/Linux Link to heading

1rsync -av --delete "sourcepath" "destinationpath"

Add some frontmatter Link to heading

1---
2title: blogtitle
3date: 2024-11-06
4draft: false
5tags:
6  - tag1
7  - tag2
8---

Transfer Images from Obsidian to Hugo Link to heading

Windows Link to heading

 1import os
 2import re
 3import shutil
 4
 5# Paths (using raw strings to handle Windows backslashes correctly)
 6posts_dir = r"C:\Users\chuck\Documents\chuckblog\content\posts"
 7attachments_dir = r"C:\Users\chuck\Documents\my_second_brain\neotokos\Attachments"
 8static_images_dir = r"C:\Users\chuck\Documents\chuckblog\static\images"
 9
10# Step 1: Process each markdown file in the posts directory
11for filename in os.listdir(posts_dir):
12    if filename.endswith(".md"):
13        filepath = os.path.join(posts_dir, filename)
14        
15        with open(filepath, "r", encoding="utf-8") as file:
16            content = file.read()
17        
18        # Step 2: Find all image links in the format ![Image Description](/images/Pasted%20image%20...%20.png)
19        images = re.findall(r'\[\[([^]]*\.png)\]\]', content)
20        
21        # Step 3: Replace image links and ensure URLs are correctly formatted
22        for image in images:
23            # Prepare the Markdown-compatible link with %20 replacing spaces
24            markdown_image = f"![Image Description](/images/{image.replace(' ', '%20')})"
25            content = content.replace(f"[[{image}]]", markdown_image)
26            
27            # Step 4: Copy the image to the Hugo static/images directory if it exists
28            image_source = os.path.join(attachments_dir, image)
29            if os.path.exists(image_source):
30                shutil.copy(image_source, static_images_dir)
31
32        # Step 5: Write the updated content back to the markdown file
33        with open(filepath, "w", encoding="utf-8") as file:
34            file.write(content)
35
36print("Markdown files processed and images copied successfully.")

Mac/Linux Link to heading

 1import os
 2import re
 3import shutil
 4
 5# Paths
 6posts_dir = "/Users/networkchuck/Documents/chuckblog/content/posts/"
 7attachments_dir = "/Users/networkchuck/Documents/neotokos/Attachments/"
 8static_images_dir = "/Users/networkchuck/Documents/chuckblog/static/images/"
 9
10# Step 1: Process each markdown file in the posts directory
11for filename in os.listdir(posts_dir):
12    if filename.endswith(".md"):
13        filepath = os.path.join(posts_dir, filename)
14        
15        with open(filepath, "r") as file:
16            content = file.read()
17        
18        # Step 2: Find all image links in the format ![Image Description](/images/Pasted%20image%20...%20.png)
19        images = re.findall(r'\[\[([^]]*\.png)\]\]', content)
20        
21        # Step 3: Replace image links and ensure URLs are correctly formatted
22        for image in images:
23            # Prepare the Markdown-compatible link with %20 replacing spaces
24            markdown_image = f"![Image Description](/images/{image.replace(' ', '%20')})"
25            content = content.replace(f"[[{image}]]", markdown_image)
26            
27            # Step 4: Copy the image to the Hugo static/images directory if it exists
28            image_source = os.path.join(attachments_dir, image)
29            if os.path.exists(image_source):
30                shutil.copy(image_source, static_images_dir)
31
32        # Step 5: Write the updated content back to the markdown file
33        with open(filepath, "w") as file:
34            file.write(content)
35
36print("Markdown files processed and images copied successfully.")

Setup GitHub Link to heading

  • Create an account
  • Then create a repo

Authenticate yourself Link to heading

1## Generate an SSH key (Mac/Linux/Windows)
2
3ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
4
5## Test your authentication using
6ssh -T git@github.com

Push to GitHub Link to heading

From the blog folder do the following commands:

  • git remote add origin git@github.com:USERNAME/repository.git
  • git add .
  • git commit -m “comment here
  • git push -u origin master

The Mega Script Link to heading

Windows (PowerShell) Link to heading

  1# PowerShell Script for Windows
  2
  3  
  4
  5# Set variables for Obsidian to Hugo copy
  6
  7$sourcePath = "C:\Users\path\to\obsidian\posts"
  8$destinationPath = "C:\Users\path\to\hugo\posts"
  9
 10  
 11
 12# Set Github repo
 13
 14$myrepo = "reponame"
 15
 16  
 17
 18# Set error handling
 19
 20$ErrorActionPreference = "Stop"
 21
 22Set-StrictMode -Version Latest
 23
 24  
 25
 26# Change to the script's directory
 27
 28$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
 29
 30Set-Location $ScriptDir
 31
 32  
 33
 34# Check for required commands
 35
 36$requiredCommands = @('git', 'hugo')
 37
 38  
 39
 40# Check for Python command (python or python3)
 41
 42if (Get-Command 'python' -ErrorAction SilentlyContinue) {
 43
 44    $pythonCommand = 'python'
 45
 46} elseif (Get-Command 'python3' -ErrorAction SilentlyContinue) {
 47
 48    $pythonCommand = 'python3'
 49
 50} else {
 51
 52    Write-Error "Python is not installed or not in PATH."
 53
 54    exit 1
 55
 56}
 57
 58  
 59
 60foreach ($cmd in $requiredCommands) {
 61
 62    if (-not (Get-Command $cmd -ErrorAction SilentlyContinue)) {
 63
 64        Write-Error "$cmd is not installed or not in PATH."
 65
 66        exit 1
 67
 68    }
 69
 70}
 71
 72  
 73
 74# Step 1: Check if Git is initialized, and initialize if necessary
 75
 76if (-not (Test-Path ".git")) {
 77
 78    Write-Host "Initializing Git repository..."
 79
 80    git init
 81
 82    git remote add origin $myrepo
 83
 84} else {
 85
 86    Write-Host "Git repository already initialized."
 87
 88    $remotes = git remote
 89
 90    if (-not ($remotes -contains 'origin')) {
 91
 92        Write-Host "Adding remote origin..."
 93
 94        git remote add origin $myrepo
 95
 96    }
 97
 98}
 99
100  
101
102# Step 2: Sync posts from Obsidian to Hugo content folder using Robocopy
103
104Write-Host "Syncing posts from Obsidian..."
105
106  
107
108if (-not (Test-Path $sourcePath)) {
109
110    Write-Error "Source path does not exist: $sourcePath"
111
112    exit 1
113
114}
115
116  
117
118if (-not (Test-Path $destinationPath)) {
119
120    Write-Error "Destination path does not exist: $destinationPath"
121
122    exit 1
123
124}
125
126  
127
128# Use Robocopy to mirror the directories
129
130$robocopyOptions = @('/MIR', '/Z', '/W:5', '/R:3')
131
132$robocopyResult = robocopy $sourcePath $destinationPath @robocopyOptions
133
134  
135
136if ($LASTEXITCODE -ge 8) {
137
138    Write-Error "Robocopy failed with exit code $LASTEXITCODE"
139
140    exit 1
141
142}
143
144  
145
146# Step 3: Process Markdown files with Python script to handle image links
147
148Write-Host "Processing image links in Markdown files..."
149
150if (-not (Test-Path "images.py")) {
151
152    Write-Error "Python script images.py not found."
153
154    exit 1
155
156}
157
158  
159
160# Execute the Python script
161
162try {
163
164    & $pythonCommand images.py
165
166} catch {
167
168    Write-Error "Failed to process image links."
169
170    exit 1
171
172}
173
174  
175
176# Step 5: Add changes to Git
177
178Write-Host "Staging changes for Git..."
179
180$hasChanges = (git status --porcelain) -ne ""
181
182if (-not $hasChanges) {
183
184    Write-Host "No changes to stage."
185
186} else {
187
188    git add .
189
190}
191
192  
193
194# Step 6: Commit changes with a dynamic message
195
196$commitMessage = "New Blog Post on $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
197
198$hasStagedChanges = (git diff --cached --name-only) -ne ""
199
200if (-not $hasStagedChanges) {
201
202    Write-Host "No changes to commit."
203
204} else {
205
206    Write-Host "Committing changes..."
207
208    git commit -m "$commitMessage"
209
210}
211
212  
213
214# Step 7: Push all changes to the main branch
215
216Write-Host "Deploying to GitHub Master..."
217
218try {
219
220    git push origin master
221
222} catch {
223
224    Write-Error "Failed to push to Master branch."
225
226    exit 1
227
228}
229
230  
231
232Write-Host "All done! Site synced, processed, committed, built, and deployed."

Linux/Mac (BASH) Link to heading

  1#!/bin/bash
  2
  3set -euo pipefail
  4
  5  
  6
  7# Change to the script's directory
  8
  9SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 10
 11cd "$SCRIPT_DIR"
 12
 13  
 14
 15# Set variables for Obsidian to Hugo copy
 16
 17sourcePath="/Users/path/to/obsidian/posts"
 18
 19destinationPath="/Users/path/to/hugo/posts"
 20
 21  
 22
 23# Set GitHub Repo
 24
 25myrepo="reponame"
 26
 27  
 28
 29# Check for required commands
 30
 31for cmd in git rsync python3 hugo; do
 32
 33    if ! command -v $cmd &> /dev/null; then
 34
 35        echo "$cmd is not installed or not in PATH."
 36
 37        exit 1
 38
 39    fi
 40
 41done
 42
 43  
 44
 45# Step 1: Check if Git is initialized, and initialize if necessary
 46
 47if [ ! -d ".git" ]; then
 48
 49    echo "Initializing Git repository..."
 50
 51    git init
 52
 53    git remote add origin $myrepo
 54
 55else
 56
 57    echo "Git repository already initialized."
 58
 59    if ! git remote | grep -q 'origin'; then
 60
 61        echo "Adding remote origin..."
 62
 63        git remote add origin $myrepo
 64
 65    fi
 66
 67fi
 68
 69  
 70
 71# Step 2: Sync posts from Obsidian to Hugo content folder using rsync
 72
 73echo "Syncing posts from Obsidian..."
 74
 75  
 76
 77if [ ! -d "$sourcePath" ]; then
 78
 79    echo "Source path does not exist: $sourcePath"
 80
 81    exit 1
 82
 83fi
 84
 85  
 86
 87if [ ! -d "$destinationPath" ]; then
 88
 89    echo "Destination path does not exist: $destinationPath"
 90
 91    exit 1
 92
 93fi
 94
 95  
 96
 97rsync -av --delete "$sourcePath" "$destinationPath"
 98
 99  
100
101# Step 3: Process Markdown files with Python script to handle image links
102
103echo "Processing image links in Markdown files..."
104
105if [ ! -f "images.py" ]; then
106
107    echo "Python script images.py not found."
108
109    exit 1
110
111fi
112
113  
114
115if ! python3 images.py; then
116
117    echo "Failed to process image links."
118
119    exit 1
120
121fi
122
123  
124
125# Step 4: Build the Hugo site
126
127echo "Building the Hugo site..."
128
129if ! hugo; then
130
131    echo "Hugo build failed."
132
133    exit 1
134
135fi
136
137  
138
139# Step 5: Add changes to Git
140
141echo "Staging changes for Git..."
142
143if git diff --quiet && git diff --cached --quiet; then
144
145    echo "No changes to stage."
146
147else
148
149    git add .
150
151fi
152
153  
154
155# Step 6: Commit changes with a dynamic message
156
157if git diff --cached --quiet; then
158
159    echo "No changes to commit."
160
161else
162
163    read -p "Enter the Commit message" commit_message
164
165    git commit -m "$commit_message"
166
167    echo "Committing changes..."
168
169fi
170
171  
172
173# Step 7: Push all changes to the main branch
174
175echo "Deploying to GitHub Main..."
176
177if ! git push origin main; then
178
179    echo "Failed to push to main branch."
180
181    exit 1
182
183fi
184
185  
186
187echo "All done! Site synced, processed, committed, built, and deployed."

Setting Up Hugo on Cloudflare Pages Link to heading

Follow this step-by-step guide to deploy your Hugo site using Cloudflare Pages.


1. Access Cloudflare Dashboard Link to heading

  1. Go to the Cloudflare Dashboard.
  2. Navigate to Workers & Pages.
  3. Click Create and select Pages.

2. Connect Your Git Repository Link to heading

  1. Click Connect Git.
  2. Add your GitHub account and authorize Cloudflare.
  3. Select your repository that contains your Hugo project.
  4. Proceed to Start Implementation.

3. Configure Project Settings Link to heading

  1. Project Name: Add a name for your project.
  2. Branch: Select the master (or main) branch.
  3. Framework Preset: Choose Hugo as the predefined structure.

4. Set Environment Variables Link to heading

Important: To ensure the deployment works, set the following environment variables. Link to heading

  1. Navigate to Settings > Environment Variables.
  2. Add the following variables:
    • HUGO_VERSION: Specify your Hugo version.
      To check your version:
      • Windows: Run hugo version in the terminal.
      • Linux/macOS: Run hugo version in the terminal.
      • Example:
        1hugo version
        2# Hugo Static Site Generator v0.139.3
        
        If your Hugo version is 0.139.3, set:
        1HUGO_VERSION = 0.139.3
        
    • HUGO_ENV: Set this to production.
      1HUGO_ENV = production
      

5. Deploy Your Site Link to heading

  1. Click Save & Deploy.
  2. Cloudflare will build and deploy your Hugo site.

6. Set Up a Webhook for Automatic Updates Link to heading

To keep the website always up to date, you can set up a webhook so that every time you update your GitHub repository, Cloudflare automatically grabs the updated code.

Steps to Configure the Webhook: Link to heading

  1. Go to your Cloudflare Pages configuration page.
  2. Find Deploy Hooks and click the plus sign (+).
  3. Add a name and click Save. Cloudflare will generate a webhook URL.
  4. Go to your GitHub repository:
    • Navigate to Settings > Webhooks.
    • Click Add Webhook.
    • Paste the webhook URL into the Payload URL field.
    • Click Add Webhook.

That’s it! Now, every time you push updates to your repository, Cloudflare will automatically deploy the new code.


7. Verify Deployment Link to heading

  1. Visit the provided URL to ensure your site is live.
  2. Check the build logs for any errors or warnings.

Notes Link to heading

  • Keep your Hugo version updated in Cloudflare when upgrading your local Hugo installation.
  • For more advanced configurations, refer to the Cloudflare Pages Documentation.