Roq Advanced Stuff
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/}
1 | Calling .paginated(page.paginator) will resolve to the posts for the computed page. |
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}
Themes
Overriding theme layouts
In Roq, you can override theme layouts by inserting an extra layout layer. This allows you to override only specific sections of the theme layout, without duplicating the entire layout structure.
Roq layouts are leveraging Qute includes under the hood. It is possible to define insert sections which can define overridable default content. |
For example, let’s override the roq-default
theme’s main layout so that our customizations apply everywhere it is used.
---
layout: theme-layouts/roq-default/main (1)
---
{#insert /} (2)
{#description} (3)
Here I can override the description section
{/}
{#footer}
<footer>
And here the footer
</footer>
{/}
1 | Inherits from the theme layout: This layout uses the original theme layout (roq-default/main ) as a base. |
2 | Inheritance mechanism: {#insert /} ensures that this layout will inherit sections defined in the theme layout. |
3 | Override specific sections: You can override individual sections such as description and footer without affecting other parts of the layout. |
Now, everywhere layouts: :theme/main
(even in the theme), your override will be used.
Developing a theme
To develop a theme, create a Maven module which will contain the theme layouts, partials, scripts and styles.
.
└── main
├── resources
│ ├── application.properties
│ └── templates
│ ├── partials
│ │ └── roq-default (1)
│ │ ├── head.html
│ │ ├── pagination.html
│ │ ├── sidebar-about.html
│ │ ├── sidebar-contact.html
│ │ ├── sidebar-copyright.html
│ │ └── sidebar-menu.html
│ └── theme-layouts (2)
│ └── roq-default
│ ├── default.html
│ ├── index.html
│ ├── main.html
│ ├── page.html
│ ├── post.html
│ └── tag.html
└── web
├── roq.js
├── roq.scss
1 | You can add partials for your theme, they need to be located in a directory with the theme name. |
2 | Layouts needs to be declared in the theme-layouts so that they can be overridden by consuming websites. |
Same as for a site, script and styles can either be added to src/main/resoucres/META-INF/resources
or bundled using Maven esbuild plugin:
<plugin>
<groupId>io.mvnpm</groupId>
<artifactId>esbuild-maven-plugin</artifactId>
<version>0.0.2</version>
<executions>
<execution>
<id>esbuild</id>
<goals>
<goal>esbuild</goal>
</goals>
</execution>
</executions>
<configuration>
<entryPoint>roq.js</entryPoint> (1)
</configuration>
<dependencies> (2)
<dependency>
<groupId>org.mvnpm.at.fortawesome</groupId>
<artifactId>fontawesome-free</artifactId>
<version>6.6.0</version>
</dependency>
<dependency>
<groupId>org.mvnpm.at.fontsource</groupId>
<artifactId>pt-serif</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
</plugin>
1 | Add your esbuild entrypoint from src/main/resources/web |
2 | Add mvnpm or webjars dependencies |
This bundle will be available in /static/bundle/roq.js
and /static/bundle/roq.css
which can be used in your theme html <head>
Create an application.properties:
site.theme=roq-default (1)
1 | Thanks to this, all call to layout: :theme/… will automatically refer to this theme. |
Links & Urls
The output location of pages and documents is determined by the FrontMatter link
key. This link
value can include placeholders, which will be dynamically replaced with relevant values for routing.
Those links are also available in the Qute data to allow Creating links between your pages. |
Link placeholders
Type of page | Placeholder | Description | Example Output |
---|---|---|---|
All |
|
The file path of the page, slugified (converted to a URL-friendly format) without the extension. |
|
All |
|
The slugified title of the page, derived from the title. Defaults to the |
|
All |
|
The file extension with the dot. Empty for all files with html output (md, asciidoc, html, …). |
|
All |
|
Force the output file extension. |
|
All |
|
The year of the page’s date or the current year if the date is not available. |
|
All |
|
The month (formatted as two digits) of the page’s date or the current month if the date is not available. |
|
All |
|
The day (formatted as two digits) of the page’s date or the current day if the date is not available. |
|
Document |
|
Represents the collection to which the document belongs, such as a specific category or folder name. |
|
Paginated |
|
Represents the current page. |
|
Default link value:
-
for pages:
/:path:ext
. -
for documents:
/:collection/:slug/
. -
for paginated page:
/:collection/page:page/
.
You can define link in a layout to affect all the pages using that layout.
|
Creating links between your pages
The pages links are automatically converted to urls by Roq, they are available in the site.url
and the page.url
variables. This makes creating links very easy:
<a href="{site.url}">Back to main page</a>
or to get the next page url in a document:
<a href="{page.next.url}">{page.next.title}</a>
or when iterating on documents:
{#for post in site.collections.posts}
<a href="{post.url}">{post.title}</a>
{/for}
or also to manually retrieve a page url with site.page(sourcePath)
:
<a href="{site.page('foo.html').url}">{site.page('foo.html').title}</a>
By default, url will be rendered as relative from the site root. You can also get the full absolute url (i.e. from http(s):// ) by using absolute on any url (e.g. {site.url.absolute} ).
|
Site Configuration
Site configuration is done in config/application.properties
(or src/main/resources/application.properties
):
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 |
|
The ignored files in the site directory (you can use glob expressions). Environment variable: |
list of string |
|
The layout to use for normal html pages if not specified in FM. When empty, the page will not use a layout when it doesn’t specify it in FM. ":theme/" is removed if no theme is defined. Environment variable: |
string |
|
The directory which contains content (pages and collections) in the Roq site directory. Environment variable: |
string |
|
The directory (dir name) which contains static files to be served (with 'static/' prefix). Environment variable: |
string |
|
The directory which contains public static files to be served without processing (dir name) Environment variable: |
string |
|
The path containing static images (in the public directory) Environment variable: |
string |
|
When enabled it will select all FrontMatter pages in Roq Generator Environment variable: |
boolean |
|
Show future documents Environment variable: |
boolean |
|
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 |
|
Show future documents (overrides global future for this collection) Environment variable: |
boolean |
|
If true, the collection won’t be available on path but consumable as data. Environment variable: |
boolean |
|
The layout to use if not specified in FM data. When empty, the document will not use a layout when it doesn’t specify it in FM. ":theme/" is removed if no theme defined. Environment variable: |
string |