-
-
Notifications
You must be signed in to change notification settings - Fork 21
Open
Labels
enhancementNew feature or requestNew feature or requesthelp wantedExtra attention is neededExtra attention is needed
Milestone
Description
Feature request
What is motivation or use case for adding/changing the behavior?
Efficient mass generation of homogeneous pages (e.g., gallery albums) from content files with front matter is a common need. At present, each entry typically requires its own template wiring, manual sorting, and manual pagination, which is repetitive, error‑prone, and difficult to scale. A first‑class “collections” facility would automate this flow: point to a content directory, define a data schema, sorting and pagination rules, and obtain fully rendered entry pages plus index pages.
Example album entry in Markdown with front matter:
---
layout: @src/layouts/album.html
title: Album title
description: album description.
image: ./entry-image.png
image_alt: The best entry image
gallery:
- image: ./image-1.png
alt: image 1 description
- image: ./image-2.png
alt: image 2 description
meta:
description: Album meta description.
socialImage: ./album-social-image.png
tags:
- Cool
- Easy
- Fast
publishDate: 2014-08-27 12:50:00
slug: album-1
---
Entry textDescribe the solution you'd like
Add integrated “collections” support to HtmlBundlerPlugin so the plugin can:
- Scan a content directory and parse front matter from Markdown/HTML.
- Generate entry pages using the layout declared in front matter.
- Build collection index pages (with pagination) from a designated template.
- Provide configurable sorting, pagination, data validation via a schema, and slug generation.
- Optionally source entries from an external API (e.g., WordPress REST API) instead of local files.
Proposed configuration shape:
new HtmlBundlerPlugin({
test: /\.html$/i,
entry: {
"gallery/index": {
import: "src/pages/gallery/index.html",
collection: {
// Sorting for collection entries
sort: (entries) => customSorting(entries),
// Pagination: number per page or a custom function
pagination: 10, // or (entries) => paginate(entries, { perPage: 10 })
// Data source and processing rules
content: {
test: /\.md$/,
path: "./src/content/gallery", // path to dir with entry files
schema: (data) => customDataValidator(data), // e.g., zod
slug: (entry) => customSlugFunction(entry), // default: derived from filename with limax
layout: "@src/views/layout/album.html"
},
// Template context (illustrative):
// collections.gallery.entries, collections.gallery.all, page.current, page.total, page.prev, page.next
},
},
});Expected behavior:
- A page is generated for each discovered entry file, using a path derived from slug (or filename).
- The gallery index is rendered from the index template, e.g.,
/gallery/, with pagination at/gallery/page/2,/gallery/page/3, etc. - Template context includes:
- collections.gallery.entries (entries for the current page),
- collections.gallery.all (all entries, if needed),
- page (current page number, total pages, prev/next links),
- all front matter fields (title, image, tags, publishDate, etc.).
- An external data source option enables static site generation directly from APIs (e.g., WordPress REST API) without intermediary scripts, bringing an experience comparable to Astro’s content collections and pagination.
Illustrative index template:
<!-- ./src/pages/gallery/index.html -->
<ul>
<% for (const entry of collections.gallery.entries) { %>
<li>
<a href="/gallery/<%= entry.slug %>/"><%= entry.title %></a>
<time datetime="<%= entry.publishDate %>"><%= entry.publishDate %></time>
</li>
<% } %>
</ul>
<nav>
<% if (page.prev) { %><a href="<%= page.prev.href %>">Prev</a><% } %>
<span>Page <%= page.current %> of <%= page.total %></span>
<% if (page.next) { %><a href="<%= page.next.href %>">Next</a><% } %>
</nav>Describe alternatives you've considered
- Astro content collections with built‑in sorting and pagination; trade‑off: switching from the current Webpack‑based pipeline.
- Custom scripts/loaders for parsing front matter, route generation, and pagination; trade‑off: bespoke maintenance and weaker integration with HtmlBundlerPlugin.
- Static site generators (Gatsby/Next SSG/Nuxt/Eleventy); trade‑off: ecosystem change and migration overhead.
- Manual lists, sorting, and pagination; trade‑off: time‑consuming, error‑prone, and hard to scale.
Appreciation for the useful project
- After the feature is implemented, do not forget to give a star ⭐
webdiscus
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requesthelp wantedExtra attention is neededExtra attention is needed