Files
Portfolio_Site/CUSTOMIZATION.md
2026-04-01 10:33:28 +05:45

542 lines
11 KiB
Markdown

# Hugo + PaperMod Customization Guide
This guide covers how to customize your Hugo portfolio site using the PaperMod theme.
---
## Table of Contents
1. [Project Structure](#project-structure)
2. [Development Workflow](#development-workflow)
3. [Configuration (hugo.yaml)](#configuration-hugoyaml)
4. [Adding Content](#adding-content)
5. [Creating New Sections](#creating-new-sections)
6. [Customizing Styles (CSS)](#customizing-styles-css)
7. [Overriding Layouts](#overriding-layouts)
8. [Common Customizations](#common-customizations)
9. [Deployment](#deployment)
---
## Project Structure
```
MyPortfolio/
├── archetypes/ # Templates for new content
├── assets/
│ └── css/
│ └── extended/
│ └── custom.css # YOUR custom CSS (this gets merged)
├── content/
│ ├── posts/ # Long-form articles
│ │ └── _index.md # Section config
│ ├── notes/ # Short notes/TILs
│ │ └── _index.md # Section config
│ └── search.md # Search page
├── layouts/
│ ├── index.html # Custom home page (no recent posts)
│ ├── partials/ # Override theme partials
│ │ ├── footer.html # Custom footer
│ │ └── templates/
│ │ └── schema_json.html # Fixed JSON-LD schema
│ ├── posts/
│ │ └── list.html # Custom posts list (compact style)
│ └── notes/
│ └── list.html # Custom notes list (compact style)
├── static/
│ └── files/ # Static files (CV.pdf, images, etc.)
├── themes/
│ └── PaperMod/ # Theme (git submodule - DON'T edit)
├── hugo.yaml # Main configuration
└── .gitignore # Ignores public/, etc.
```
### Key Principle: Never Edit the Theme Directly
The `themes/PaperMod/` folder is a git submodule. To customize:
- **CSS**: Add to `assets/css/extended/custom.css`
- **Layouts**: Copy the file from `themes/PaperMod/layouts/` to `layouts/` and modify
- **Config**: Everything in `hugo.yaml`
---
## Development Workflow
### Local Development
```bash
# Start dev server (watches for changes)
hugo serve
# With drafts visible
hugo serve -D
# Build for production (outputs to public/)
hugo build --minify
```
### Why `public/` is Gitignored
- `public/` is generated output - it's rebuilt fresh every time
- Your CI/CD (GitHub Actions) builds it during deployment
- Never commit build artifacts to git
### Git Workflow
```bash
# After making changes
git add .
git commit -m "Add new post about X"
git push origin master # Triggers deployment
```
---
## Configuration (hugo.yaml)
### Key Sections
#### Site Basics
```yaml
baseURL: "/" # Use "/" for relative URLs (works on localhost + prod)
relativeURLs: true # Makes all URLs relative
title: Saurav Dhakal
languageCode: en-us
theme: ["PaperMod"]
```
#### Menu (Header Navigation)
```yaml
menu:
main:
- identifier: posts # Internal ID
name: Posts # Display name
url: /posts/ # URL path
weight: 10 # Order (lower = first)
- identifier: notes
name: Notes
url: /notes/
weight: 20
- identifier: tags
name: Tags
url: /tags/
weight: 30
- identifier: search
name: Search
url: /search/
weight: 40
```
#### Home Page Info
```yaml
params:
homeInfoParams:
Title: "Hi there 👋, I'm Saurav!"
Content: >
I'm a software engineer...
```
#### Social Icons
```yaml
params:
socialIcons:
- name: github
url: "https://github.com/yourusername"
- name: linkedin
url: "https://linkedin.com/in/yourusername"
- name: x
url: "https://x.com/yourusername"
```
Available icons: github, linkedin, x, twitter, email, rss, youtube, instagram, facebook, stackoverflow, etc.
---
## Adding Content
### New Post
```bash
hugo new posts/my-new-post.md
```
Or manually create `content/posts/my-new-post.md`:
```markdown
---
title: "My New Post"
date: 2025-08-20
summary: "A brief description for the list view"
tags: ["tag1", "tag2"]
categories: ["Category"]
draft: false
ShowToc: true
TocOpen: false
---
Your content here...
```
### New Note
Create `content/notes/my-note.md`:
```markdown
---
title: "Quick TIL"
date: 2025-08-20
summary: "Today I learned about X"
tags: ["til"]
---
Short content here...
```
### Front Matter Options
| Field | Description |
|-------|-------------|
| `title` | Post title |
| `date` | Publication date (YYYY-MM-DD) |
| `summary` | Short description for list views |
| `tags` | Array of tags |
| `categories` | Array of categories |
| `draft` | If `true`, won't be published |
| `ShowToc` | Show table of contents |
| `TocOpen` | TOC expanded by default |
| `ShowReadingTime` | Override global setting |
| `ShowWordCount` | Override global setting |
| `cover.image` | Cover image path |
---
## Creating New Sections
### Example: Adding a "Projects" Section
1. **Add to menu** in `hugo.yaml`:
```yaml
menu:
main:
# ... existing items
- identifier: projects
name: Projects
url: /projects/
weight: 25
```
2. **Create content directory**:
```bash
mkdir -p content/projects
```
3. **Create section index** `content/projects/_index.md`:
```markdown
---
title: "Projects"
description: "Things I've built"
---
```
4. **Add project pages** `content/projects/my-project.md`:
```markdown
---
title: "My Cool Project"
date: 2025-01-15
summary: "A brief description"
tags: ["golang", "cli"]
---
Project description...
```
5. **(Optional) Custom layout** - If you want projects to look different, create `layouts/projects/list.html`
---
## Customizing Styles (CSS)
### Where to Add CSS
**Only edit**: `assets/css/extended/custom.css`
PaperMod automatically includes this file. You don't need to import it anywhere.
### CSS Variables (Theme Colors)
PaperMod uses CSS variables. Override them in your custom.css:
```css
:root {
/* Light mode */
--primary: #282828; /* Main text */
--secondary: #3c3836; /* Secondary text */
--tertiary: rgb(214, 214, 214); /* Borders, etc */
--theme: rgb(255, 255, 255); /* Background */
--entry: rgb(255, 255, 255); /* Card background */
}
:root[data-theme="dark"] {
/* Dark mode */
--primary: #fbf1c7;
--secondary: #ebdbb2;
--theme: #181818;
--entry: rgb(46, 46, 51);
}
```
### Common CSS Customizations
#### Change fonts
```css
@import url("https://fonts.googleapis.com/css2?family=Your+Font&display=swap");
body {
font-family: "Your Font", sans-serif;
}
```
#### Style links
```css
main a {
text-decoration: underline;
text-decoration-color: var(--green);
}
main a:hover {
background-color: var(--green);
color: white;
}
```
#### Customize post cards
```css
main .post-entry {
border: 2px solid #383838;
background-color: var(--entry);
border-radius: 8px;
}
```
---
## Overriding Layouts
### How Layout Override Works
Hugo looks for templates in this order:
1. `layouts/` (your overrides)
2. `themes/PaperMod/layouts/` (theme defaults)
### To Override a Template
1. Find the file in `themes/PaperMod/layouts/`
2. Copy it to the same path in `layouts/`
3. Modify your copy
### Common Files to Override
| File | Purpose |
|------|---------|
| `layouts/partials/header.html` | Site header/nav |
| `layouts/partials/footer.html` | Site footer |
| `layouts/partials/post_meta.html` | Post metadata (date, read time) |
| `layouts/_default/list.html` | List pages (posts, tags) |
| `layouts/_default/single.html` | Individual post/page |
### Example: Simpler Footer
Your `layouts/partials/footer.html` already overrides the theme's footer.
### Section-Specific Layouts
Create `layouts/SECTION_NAME/list.html` for a custom list layout for that section.
**Current custom layouts:**
- `layouts/index.html` - Home page with just intro + social icons (no recent posts)
- `layouts/posts/list.html` - Compact list: `# Title` + date + 2-line description
- `layouts/notes/list.html` - Compact list: `# Title` + date (no description)
---
## Common Customizations
### Disable Reading Time for a Section
In the section's `_index.md`:
```markdown
---
title: "Notes"
ShowReadingTime: false
---
```
Or per-post in front matter.
### Add a Static Page (About, Contact)
Create `content/about.md`:
```markdown
---
title: "About"
layout: "single"
url: "/about/"
---
About me content...
```
Add to menu:
```yaml
menu:
main:
- identifier: about
name: About
url: /about/
weight: 50
```
### Add Favicon
1. Place favicon files in `static/`:
- `static/favicon.ico`
- `static/favicon-16x16.png`
- `static/favicon-32x32.png`
- `static/apple-touch-icon.png`
2. Update `hugo.yaml`:
```yaml
params:
assets:
favicon: "/favicon.ico"
favicon16x16: "/favicon-16x16.png"
favicon32x32: "/favicon-32x32.png"
apple_touch_icon: "/apple-touch-icon.png"
```
### Enable Comments (Disqus)
```yaml
params:
comments: true
disqusShortname: "your-disqus-shortname"
```
### Add Google Analytics
Already configured in your `hugo.yaml`:
```yaml
googleAnalytics: "G-XXXXXXXXXX"
```
---
## Deployment
### Current Setup (GitHub Actions → SSH/SCP)
Your `.github/workflows/deploy.yml`:
1. Triggers on push to `master`
2. Builds site with `hugo build --minify`
3. Deploys `public/` via SCP to your server
### Required GitHub Secrets
Set these in your repo's Settings → Secrets:
- `SSH_HOST` - Your server hostname/IP
- `SSH_USER` - SSH username
- `SSH_KEY` - Private SSH key
- `SSH_PORT` - SSH port (usually 22)
### Alternative: GitHub Pages
If you want to use GitHub Pages instead:
1. Change workflow to use `peaceiris/actions-gh-pages`
2. Set `baseURL` to `https://yourusername.github.io/repo-name/`
### Alternative: Netlify/Vercel
These platforms auto-detect Hugo and build for you:
1. Connect your GitHub repo
2. Set build command: `hugo --minify`
3. Set publish directory: `public`
---
## Quick Reference
### Useful Commands
```bash
# Local dev
hugo serve -D # Serve with drafts
# Create content
hugo new posts/title.md # New post
hugo new notes/title.md # New note
# Build
hugo build --minify # Production build
# Debug
hugo config # Show full config
hugo list all # List all content
```
### File Locations
| What | Where |
|------|-------|
| Config | `hugo.yaml` |
| Custom CSS | `assets/css/extended/custom.css` |
| Posts | `content/posts/` |
| Notes | `content/notes/` |
| Static files | `static/` |
| Layout overrides | `layouts/` |
---
## Troubleshooting
### Links Go to Production URL in Dev
Fixed by setting:
```yaml
baseURL: "/"
relativeURLs: true
```
### Changes Not Showing
1. Hard refresh browser (Ctrl+Shift+R)
2. Clear `public/` folder: `rm -rf public/`
3. Restart hugo serve
### Theme Not Loading
```bash
git submodule update --init --recursive
```
### Search Not Working
Ensure `hugo.yaml` has:
```yaml
outputs:
home:
- HTML
- RSS
- JSON # Required for search
```
---
## Resources
- [Hugo Documentation](https://gohugo.io/documentation/)
- [PaperMod Wiki](https://github.com/adityatelange/hugo-PaperMod/wiki)
- [PaperMod Demo](https://adityatelange.github.io/hugo-PaperMod/)