Salin dan Bagikan
Hugo Page Bundles: Asset Management Modern untuk Content - Panduan lengkap Hugo Page Bundles untuk asset management modern. Organize images, files, dan …

Hugo Page Bundles: Asset Management Modern untuk Content

Hugo Page Bundles: Asset Management Modern untuk Content

Page Bundles adalah fitur powerful di Hugo untuk mengorganisir content dan assets bersama-sama dalam satu folder. Ini adalah best practice untuk modern content management.

Apa itu Page Bundles?

Definisi

Page Bundle adalah folder yang berisi file content Markdown (biasanya index.md) bersama dengan assets terkait (images, files, data) dalam satu lokasi.

Why Page Bundles?

  1. Co-location: Assets bersama dengan content
  2. Resource Management: Akses ke Hugo image processing
  3. Clarity: Struktur yang jelas dan terorganisir
  4. Portability: Mudah move content dengan assets-nya
  5. Version Control: Track changes untuk content + assets

Types of Page Bundles

1. Leaf Bundle (index.md)

Single page dengan resources:

content/posts/my-awesome-post/
├── index.md           # Content file
├── featured.jpg       # Featured image (page resource)
├── gallery/
│   ├── image-1.jpg
│   ├── image-2.jpg
│   └── image-3.jpg
├── diagram.png
└── attachment.pdf

Frontmatter di index.md:

---
title: "My Awesome Post"
date: 2026-02-03T10:00:00+07:00
draft: false
resources:
  - name: featured
    src: featured.jpg
    params:
      credits: "Photo by John Doe"
  - name: gallery
    src: gallery/**
---

Content goes here...

2. Branch Bundle (_index.md)

Section dengan content dan sub-pages:

content/blog/              # Branch bundle
├── _index.md            # Section content
├── _index.jpg           # Section featured image
├── my-post-1/           # Leaf bundle
│   ├── index.md
│   └── featured.jpg
└── my-post-2/           # Leaf bundle
    ├── index.md
    └── featured.jpg

_index.md:

---
title: "Blog"
description: "Latest articles and tutorials"
cascade:
  featured_image: _index.jpg
---

Welcome to our blog!

Resource Management

1. Accessing Resources in Templates

Single resource:

{{ $image := .Resources.GetMatch "featured.jpg" }}
{{ if $image }}
  {{ $resized := $image.Resize "800x" }}
  <img src="{{ $resized.RelPermalink }}" alt="{{ .Title }}">
{{ end }}

Multiple resources (glob patterns):

{{ $images := .Resources.Match "gallery/*.jpg" }}
<div class="gallery">
  {{ range $images }}
    {{ $thumb := .Resize "300x200" }}
    <img src="{{ $thumb.RelPermalink }}" loading="lazy">
  {{ end }}
</div>

By name:

{{ $featured := .Resources.Get "featured" }}
{{ $gallery := .Resources.Match "gallery/**" }}

2. Resource Properties

{{ $image := .Resources.GetMatch "*.jpg" }}
{{ if $image }}
  <figure>
    <img src="{{ $image.RelPermalink }}"
         width="{{ $image.Width }}"
         height="{{ $image.Height }}"
         alt="{{ $image.Title }}">
    <figcaption>
      {{ $image.Params.credits }}
      ({{ $image.Width }}x{{ $image.Height }}px, {{ div $image.Size 1024 }}KB)
    </figcaption>
  </figure>
{{ end }}

3. Image Processing

{{ $image := .Resources.GetMatch "featured.jpg" }}
{{ if $image }}
  {{ $original := $image }}
  {{ $resized := $image.Resize "800x webp" }}
  {{ $small := $image.Resize "400x webp q60" }}
  {{ $large := $image.Resize "1200x webp" }}

  <picture>
    <source media="(min-width: 800px)" srcset="{{ $large.RelPermalink }}">
    <source media="(min-width: 400px)" srcset="{{ $resized.RelPermalink }}">
    <img src="{{ $small.RelPermalink }}" alt="{{ .Title }}">
  </picture>
{{ end }}

Frontmatter Resource Definitions

1. Named Resources

---
title: "Post Title"
resources:
  - name: "header"
    src: "images/header.jpg"
    title: "Header Image"
    params:
      credits: "Photo by Jane Doe"

  - name: "diagram"
    src: "diagram.png"
    params:
      alt: "System architecture diagram"

  - name: "downloads"
    src: "downloads/*"
---

2. Resource Parameters

{{ $header := .Resources.Get "header" }}
{{ if $header }}
  {{ with $header.Params.credits }}
    <p class="photo-credits">Photo: {{ . }}</p>
  {{ end }}
{{ end }}

3. Glob Patterns

---
resources:
  - name: "gallery"
    src: "gallery/*.jpg"

  - name: "all-images"
    src: "**/*.jpg"

  - name: "documents"
    src: "*.pdf"
---

Practical Examples

Example 1: Blog Post dengan Gallery

Content structure:

content/posts/bali-travel-guide/
├── index.md
├── featured.jpg
├── gallery/
│   ├── beach-1.jpg
│   ├── beach-2.jpg
│   ├── temple.jpg
│   └── sunset.jpg
└── map.pdf

index.md:

---
title: "Bali Travel Guide: 7 Days Itinerary"
date: 2026-02-03
draft: false
resources:
  - name: "featured"
    src: "featured.jpg"
    params:
      caption: "Beautiful sunset at Uluwatu"

  - name: "gallery"
    src: "gallery/**"
    ---

Explore Bali with this comprehensive 7-day itinerary...

## Photo Gallery

{{ < gallery > }}

## Download Map

[Download Detailed Map]({{ < resource "map.pdf" > }})

Gallery shortcode:

{{ $images := .Page.Resources.Match "gallery/*" }}
<div class="masonry-grid">
  {{ range $images }}
    {{ $thumb := .Resize "400x300" }}
    {{ $full := .Resize "1200x800" }}
    <a href="{{ $full.RelPermalink }}" data-lightbox="gallery">
      <img src="{{ $thumb.RelPermalink }}" loading="lazy">
    </a>
  {{ end }}
</div>

Example 2: Tutorial dengan Code Files

content/tutorials/hugo-basics/
├── index.md
├── hugo.toml
├── config.yaml
└── tree.txt

index.md:

---
title: "Hugo Basics Tutorial"
type: "tutorial"
resources:
  - name: "config-toml"
    src: "hugo.toml"

  - name: "config-yaml"
    src: "config.yaml"
---

## Configuration

### TOML Format

{{ < code-file resource="config-toml" lang="toml" > }}

### YAML Format

{{ < code-file resource="config-yaml" lang="yaml" > }}

Example 3: Product Page dengan Assets

content/products/software-tool/
├── index.md
├── hero.jpg
├── features/
   ├── screenshot-1.jpg
   ├── screenshot-2.jpg
   └── screenshot-3.jpg
├── videos/
   └── demo.mp4
└── datasheet.pdf

index.md:

---
title: "Software Tool Pro"
price: 99
resources:
  - name: "hero"
    src: "hero.jpg"

  - name: "screenshots"
    src: "features/*.jpg"

  - name: "demo-video"
    src: "videos/demo.mp4"

  - name: "datasheet"
    src: "datasheet.pdf"
---

Product description here...

Cascade dengan Resources

Inheriting Resources di Sections

---
title: "Tutorials"
resources:
  - name: "section-banner"
    src: "banner.jpg"
cascade:
  resources:
    - name: "watermark"
      src: "../watermark.png"
---

Resources akan tersedia untuk semua pages dalam section.

Content Organization Best Practices

1. Naming Conventions

✅ GOOD:
content/posts/
├── 2026/
│   ├── 01-january/
│   │   └── my-post/
│   │       ├── index.md
│   │       └── featured.jpg
│   └── 02-february/
│       └── another-post/
│           ├── index.md
│           └── featured.jpg

❌ AVOID:
content/posts/my-post.md
static/images/my-post-image.jpg

2. Asset Organization

content/posts/
└── my-post/
    ├── index.md
    ├── featured.jpg
    ├── assets/
       ├── diagram-1.png
       ├── diagram-2.png
       └── chart.svg
    ├── downloads/
       ├── whitepaper.pdf
       └── checklist.pdf
    └── gallery/
        ├── photo-1.jpg
        ├── photo-2.jpg
        └── photo-3.jpg

3. Resource Metadata

---
resources:
  - src: "*.jpg"
    name: "photo-{{ .counter }}"
    params:
      photographer: "John Doe"
      license: "CC BY-SA"
---

Troubleshooting

Issue: “Resource not found”

Check:

  1. File extension case: .jpg.JPG
  2. Path relatif ke index.md
  3. File ada di folder page bundle
# Check resources untuk page
hugo server -D
# Buka: http://localhost:1313/__hugo/resrc/

Issue: “Cannot resize resource”

Pastikan:

  • Hugo Extended terinstall
  • File adalah image yang valid
  • Format supported (JPG, PNG, GIF, WebP)

Issue: “Glob pattern not working”

Gunakan pattern yang benar:

# Benar
resources:
  - src: "gallery/*.jpg"      # Semua JPG di gallery/
  - src: "**/*.jpg"           # Semua JPG di semua subfolder
  - src: "*.pdf"              # Semua PDF di root bundle

Performance Tips

1. Image Optimization

# hugo.toml
[imaging]
  quality = 80
  resampleFilter = "lanczos"

2. Lazy Loading

<img src="{{ $resized.RelPermalink }}"
     loading="lazy"
     decoding="async"
     alt="{{ .Title }}">

3. Resource Caching

# Hugo caches processed resources
# Clear cache jika perlu:
hugo --gc

Migration ke Page Bundles

From Traditional Structure

Before (Traditional):

content/posts/my-post.md
static/images/posts/my-post/
├── featured.jpg
└── gallery/
    └── images.jpg

After (Page Bundle):

# 1. Buat folder
mkdir content/posts/my-post

# 2. Move content
mv content/posts/my-post.md content/posts/my-post/index.md

# 3. Move images
mv static/images/posts/my-post/* content/posts/my-post/

# 4. Update image paths di content
# Ganti /images/posts/my-post/ dengan . (relative)

Script untuk Bulk Migration

#!/bin/bash
# migrate-to-bundles.sh

POSTS_DIR="content/posts"
IMAGES_DIR="static/images/posts"

for post in "$POSTS_DIR"/*.md; do
  basename=$(basename "$post" .md)

  # Buat bundle folder
  mkdir -p "$POSTS_DIR/$basename"

  # Move post
  mv "$post" "$POSTS_DIR/$basename/index.md"

  # Move images jika ada
  if [ -d "$IMAGES_DIR/$basename" ]; then
    mv "$IMAGES_DIR/$basename/"* "$POSTS_DIR/$basename/"
    rmdir "$IMAGES_DIR/$basename" 2>/dev/null
  fi
done

Kesimpulan

Page Bundles memberikan:

Organization: Assets bersama content
Portability: Move content dengan semua assets
Image Processing: Hugo resources API
Version Control: Track semua dalam Git
Clarity: Struktur yang jelas dan scalable

Gunakan page bundles untuk semua content baru dan pertimbangkan migrasi content existing untuk better asset management.

Artikel Terkait

Link Postingan : https://www.tirinfo.com/hugo-page-bundles-asset-management/

Hendra WIjaya
Tirinfo
6 minutes.
3 February 2026