Quarkus Roq FrontMatter
Quarkus Roq FrontMatter is a Quarkus extension that create a website from your Markdown/Asciidoc/Html pages using FrontMatter headers (url, layout, seo, data).
Roq FrontMatter is already included as part of the Roq Static Site Generator extension io.quarkiverse.roq:quarkus-roq , Follow Standalone installation section to use it standalone.
|
Getting started
By default, your site should be located in the project directory, or in the resources (i.e. src/main/resources/
).
The default directory structure is:
Qute and FrontMatter
All templates can use the awesome type-safe Qute template engine.
Templates for layout, documents and pages can declare a FrontMatter (referred as FM data) header delimited by two ---
.
This header contains yaml data used to configure many things such as:
-
Routing
-
Data for the templates
-
Content generation
-
Pagination
Layouts and Partials
For your site, you will have one or more kind of pages, this is what we call "layouts", located by default in templates/layouts/
. For example:
-
main
: the base layout for all kind of pages -
page
: the layout of normal pages -
post
: the layout for blog posts -
recipe
: the layout for recipes or whatever
A layout can be included in pages and documents through the layout
FrontMatter key (e.g. layout: page
).
You can also prepare partial templates. They are located by default in templates/partials/
. For example:
-
pagination.html
-
head.html
if you don’t already have layouts and partials in your project, Install a theme or create your own templates (example templates). |
Install a theme
To install a theme, simply add the dependency to your pom.xml. Example with Roq’s default theme:
<dependency>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-theme-default</artifactId>
<version>1.0.0.CR2</version>
</dependency>
It will provide templates, scripts and styles for your site. To use a layout, refer to it with :theme/
prefix (there is an in the next part).
Site index template
Your site index template is required and should be located in content/index.html
.
---
title: Hello Roqers (1)
description: It is time to start Roqing 🎸!
layout: :theme/main (2)
---
<h1>Hello fellow Roqers 🤘</h1>
<p>
With Roq, it is very easy to a link to another.
<a href="{site.url('/roq-bottom')}">page</a>. (3)
</p>
1 | The index.html also describe your site information through a FrontMatter header. |
2 | The layout to use (in this case :theme/main which refers to the main layout from the theme). |
3 | We use the {site.url(path)} using Qute to resolve site urls, in this case it doesn’t exist yet… |
Variables
You can use Qute to access site and pages data. For this use the site
and page
variables:
-
The
site
variable allow to access site global info from any page, document, layout or partial.Show attributes
Variable Type Description Example site.url
RoqUrl
The Roq site URL
site.imagesUrl
RoqUrl
Directory to resolve images URL (e.g. /static/images)
site.data
JsonObject
The site FM data (declared in the index.html)
{"title": "My Site", "description": "A description"}
site.pages
java.util.List<NormalPage>
All the pages in this site (without the documents)
[Page1, Page2, Page3]
site.collections
RoqCollections
All the collections in this site (containing documents)
{"collection1": Collection1, "collection2": Collection2}
site.title
String
The site title
My Site
site.description
String
The site description
A description
site.img
RoqUrl
The site image URL if present
site.url(Object path, Object… others)
RoqUrl
Shortcut for site.url.resolve(path)
site.url.resolve("/about") ⇒ http://example.com/my-roq-site/about
-
The
page
variable is available in pages, documents, layouts, and partials. It contains the info for the page it is used from.Show attributes
Variable Type Description Example page.url
RoqUrl
The URL to this page
page.info
PageInfo
The page info (file name, …)
page.data
JsonObject
The FM data of this page
{"title": "About Us", "description": "This is the about us page."}
page.paginator
Paginator
The paginator if any
Paginator{currentPage=1, totalPages=5}
page.collection
String
The collection id if this a document
posts
page.title()
String
The title of the page (shortcut from FM)
About Us
page.description()
String
The description of the page (shortcut from FM)
This is the about us page.
page.img()
RoqUrl
The image URL of the page if present
page.date()
ZonedDateTime
The publication date of the page
2023-10-01T12:00:00Z
Pages
Any directory without the _
prefix in the site directory will be scanned for pages content.
Let’s create your first page and spice things up a bit by using Markdown.
---
title: Roq Bottom
description: When you hit Roq bottom, try Roq to climb back up!
layout: :theme/page
link: /climb-back-up (1)
the-rope: You Roq! (2)
---
# Roq Bottom
If you thought you hit Roq Bottom, take this 🪢 because :
__{page.data.the-rope}!__ (3)
1 | you can use link to give this page a custom link (by default it will use the file-name). |
2 | you can add other FM data. |
3 | FM data is available through page.data . |
Asciidoc support
We will soon introduce support for asciidoc, this will be available by adding an extension to the pom.xml: https://github.com/quarkiverse/quarkus-roq/issues/169
Collections
Collections are a great way to group related content such as blog posts, recipes, member of a team or talks at a conference. Once created you can easily iterate and link to them.
By default, Roq is configured with a posts
collection using the content/posts
directory. Let’s create our first post:
---
title: Roq bad puns
description: Roq is very good for bad puns 🤭
layout: :theme/post (1)
tags: (2)
- funny
- ai
img: 2024/10/roq-solid.jpg
---
# {page.title} (3)
Here is a list of puns suggested by Chat GPT:
1. Roq and Rule – A play on “rock and roll,” implying dominance or success.
2. Between a Roq and a Hard Place – Classic pun meaning stuck in a difficult situation.
3. Roq Solid – Something that is extremely reliable or stable.
4. You Roq! – A compliment, suggesting someone is awesome or does something well.
5. Roq Bottom – Referring to the lowest possible point, often used metaphorically.
6. Roq the Boat – To cause trouble or disturb the status quo.
7. Roq Star – A person who excels or stands out in their field.
8. Let’s Roq – Slang for getting started or doing something exciting.
9. Roq On! – An enthusiastic way to say “keep going” or “stay awesome.”
10. Roqy Road – Could be literal (the type of road) or metaphorical for a difficult journey.
11. Roq of Ages – A historical reference, often implying something long-standing and unchanging.
12. Roq the Cradle – Can be literal or a pun about nurturing or starting something new.
13. Roqy Relationship – A tumultuous or unstable relationship.
14. Heavy as a Roq – Something burdensome or difficult to manage.
15. Stone Cold Roq – Referring to something very cool or emotionless.
1 | This time we use the post layout from the theme. |
2 | You can define tags (see Plugins to create pages for tags). |
3 | You have shortcut on the page to access title and description . |
Then let’s edit our index page to show the list of posts:
---
title: Hello Roqers
description: It is time to start Roqing 🎸!
layout: main
---
<h1>Hello fellow Roqers 🤘</h1>
{#for post in site.collections.posts} (1)
<article class="post">
{#if post.img}
<a class="post-thumbnail" style="background-image: url({post.img})" href="{post.url}"></a> (2) (3)
{/if}
<div class="post-content">
<h2 class="post-title"><a href="{post.url}">{post.title}</a></h2>
<p>{post.description}</p>
<span class="post-date">{post.date.format('yyyy, MMM dd')} — </span> (4)
<span class="post-words">
{post.readTime} minute read (5)
</span>
</div>
</article>
{/for}
1 | You can use site.collections.[collection id] to access the full list of documents (it is also possible to paginate. |
2 | post.img is smart and is already resolved to the image url (as a RoqUrl). |
3 | post.url contains the post url (as a RoqUrl), you could also use post.url.absolute to get the absolute url. |
4 | post.date returns a ZonedDateTime and can be formatted the way you want. |
5 | post.readTime is a Qute template extension which compute the read time based on the post content. |
Styles and Javascript
The Quarkus Web Bundler is included by default with the Roq extension. |
You can add css and scripts in your static directory or bundle them.
To use bundling scripts (js, ts) and styles (css, scss) should be located in src/main/web/app/
. To include the generated bundle in your template, specify the bundle tag in the html>head
tag:
<head>
...
{#bundle /}
</head>
It will be rendered with the relevant <script>
and <style>
tags to include your bundle.
You may also consume and bundle npm dependencies among other cool things. For more info, read the Quarkus Web Bundler documentation.
Pagination
Adding pagination to your Roq site is an easy way to improve content navigation. Let’s walk through how to implement pagination and customize its behavior in your site.
Step 1: Iterate on the paginated collection
First, include the following in your FrontMatter header on the page which will iterate on the paginated collection:
paginate: posts
Next, in your template, loop through the paginated posts using:
{#for post in site.collections.posts.paginated(page.paginator)} (1)
<article class="post">
...
</article>
{/for}
{#include includes/pagination.html/}
Step 2: Including Pagination Controls
To add pagination controls, use the provided fm/pagination.html
in your own _includes/pagination.html
:
{#include fm/pagination.html}
{#newer}<i class="fa fa-long-arrow-left" aria-hidden="true"></i>{/newer}
{#older}<i class="fa fa-long-arrow-right" aria-hidden="true"></i>{/older}
{/include}
If you want to write your own controls, find inspiration in the FM sources fm/pagination.html. |
Just by doing so, Roq will generate a bunch of pages based on the pagination setting. For example with a pagination size of 4 and with 9 posts, you would get:
-
index.html
(posts 1 to 4) -
posts/page-2
(posts 5 to 8) -
posts/page-3
(post 9)
the first page uses the declaring page link. |
You can further customize your pagination by setting the page size and link format:
paginate:
size: 4
collection: posts
link: posts/page-:page
With these steps, you can create a flexible pagination system to improve your site’s navigation.
SEO
Incorporating search engine optimization (SEO) is as simple as inserting this tag into your <head>
section:
<head>
{#seo page site /}
</head>
It will automatically use the FrontMatter data to fill the tags.
<title>My Blog Post</title>
<meta name="author" content="ia3andy" />
<meta name="generator" content="Quarkus Roq v1.0.0" />
<meta property="article:author" content="ia3andy" />
<meta property="article:published_time" content="2024-09-23T12:00Z[Etc/UTC]" />
<meta property="og:image" content="https://images.unsplash.com/photo.webp" />
<meta property="og:locale" content="en-US" />
<meta property="og:type" content="article" />
RSS
Incorporating and RSS feed of your posts is as simple as inserting this tag into your <head>
section:
<head>
{#rss site /}
</head>
It will automatically use the FrontMatter data generate an RSS feed link.
<link rel="alternate" type="application/rss+xml" title="Your Blog" href="/rss.xml"/>
It will automatically utilize the Frontmatter data from all your blog posts to generate a valid Atom RSS feed link at rss.xml
. Ensure you create an rss.xml
file at the root of your site and include this single line of code:
{#include fm/rss.html}
Standalone installation
It is included as part of the Roq Static Site Generator extension io.quarkiverse.roq:quarkus-roq . You can also use it standalone.
|
If you want to use this extension standalone, you need to add the io.quarkiverse.roq:quarkus-roq-frontmatter
extension first to your build file.
For instance, with Maven, add the following dependency to your POM file:
<dependency>
<groupId>io.quarkiverse.roq</groupId>
<artifactId>quarkus-roq-frontmatter</artifactId>
<version>1.0.0.CR2</version>
</dependency>
Extension Configuration Reference
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Configuration property |
Type |
Default |
---|---|---|
The root path of your site (e.g. /blog) relative the quarkus http root path. This is to be used only when the site is living next to a Quarkus application. Use Environment variable: |
string |
|
the base hostname & protocol for your site, e.g. http://example.com Environment variable: |
string |
|
The order of the route which handles the templates. <p> By default, the route is executed before the default routes (static resources, etc.). Environment variable: |
int |
|
Configuration property fixed at build time - All other configuration properties are overridable at runtime
Configuration property |
Type |
Default |
---|---|---|
The ignored files in the Roq site directory (you can use glob expressions). Environment variable: |
list of string |
|
The files to use as raw templates (n the Roq site directory (you can use glob expressions)), Environment variable: |
list of string |
|
Files to serve as static in the Roq site directory (you can use glob expressions) Environment variable: |
list of string |
|
The directory containing layouts in the Roq site directory (dir name). Environment variable: |
string |
|
When enabled it will select all FrontMatter pages in Roq Generator Environment variable: |
boolean |
|
Show future pages Environment variable: |
boolean |
|
The public path containing pages and posts images (relative to the site path) Environment variable: |
string |
|
This will be used to replace Environment variable: |
string |
|
Show draft pages Environment variable: |
boolean |
|
Format for dates Environment variable: |
string |
|
The default timezone Environment variable: |
string |
|
If this collection is enabled Environment variable: |
boolean |
|
If true, the collection won’t be available on path but consumable as data. Environment variable: |
boolean |
|