Create multiple pages
Generators allow creating multiple pages from one unique source file
It's possible to generate more than one page from the same source file with Lume. This is useful to generate pages programmatically using an external source like a database or an API.
Basic example
The way to generate pages in Lume is using Generators. Any page returning a generator function is treated by Lume as a special page that generates other pages.
In the following example, the content is a generator that yields 3 objects. Every element yielded will create a new page, with the URL and content. It's important that the URLs of the new pages to be unique:
// example.page.js
export default function* () {
yield {
url: "/page-1/",
content: "This is the first page",
};
yield {
url: "/page-2/",
content: "This is the second page",
};
yield {
url: "/page-3/",
content: "This is the third page",
};
}
Note that only formats that can export generators can be used to create pages. For example, you can use JavaScript, TypeScript or JSX/TSX. But it's not possible to generate pages from Markdown or Vento files.
Multiple pages with layouts
Every page is an object with the page data. In the previous example, every page has the url and content properties, to define the content and URL of every page. If you want to use a layout to generate the page content, you have to export the layout keyword with the layout name and the data that will be used in the layouts:
export default function* () {
yield {
url: "/page-1/",
layout: "layouts/article.vto",
title: "Article 1",
body: "Welcome to the article 1",
};
yield {
url: "/page-2/",
layout: "layouts/article.vto",
title: "Article 2",
body: "Welcome to the article 2",
};
yield {
url: "/page-3/",
layout: "layouts/article.vto",
title: "Article 3",
body: "Welcome to the article 3",
};
}
---
layout: layouts/base.vto
---
<article>
<h1>{{ title }}</h1>
<div>
{{ body |> md }}
</div>
</article>
Because the layout is the same for all pages, we can use a named export to define it once instead of duplicating it in every yielded page:
export const layout = "layouts/article.vto";
export default function* () {
yield {
url: "/page-1/",
title: "Article 1",
body: "Welcome to the article 1",
};
yield {
url: "/page-2/",
title: "Article 2",
body: "Welcome to the article 2",
};
yield {
url: "/page-3/",
title: "Article 3",
body: "Welcome to the article 3",
};
}
---
layout: layouts/base.vto
---
<article>
<h1>{{ title }}</h1>
<div>
{{ body |> md }}
</div>
</article>
Generate pages from other sources
This simple concept of using generators to generate pages is very flexible and can be used for many use cases. For example, we can generate pages from a Database or an API:
import database from "./my-database.ts";
export const layout = "layouts/article.vto";
export default function* () {
const articles = database.query("select * from articles");
for (const article of articles) {
yield {
url: `/articles/${article.slug}/`,
...article,
};
}
}
In this example, we use a database to get all articles and a generator to generate a new page per article. Each yielded article contains the URL and other properties (i.e. title, category, tag, body, etc.). We are exporting the layout value so all pages will be rendered with the same layout.
Another common use case is pagination. Go to Search and paginate for more info.