Skip to content

docs: Improve custom listing using raw HTML #1677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 35 additions & 9 deletions docs/websites/website-listings-custom.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ In addition to the 3 built in types of listings, you can also build a completely

## Listing Templates

To build a custom listing display, you create an [EJS template](https://ejs.co) that will be used to generate the HTML for a set of items that are passed to the template. EJS templates allow you to generate HTML using plain javascript, making it easy to loop through items and output their values in your custom HTML.

To build a custom listing display, you create an [EJS template](https://ejs.co) that will be used to generate the HTML for a set of items that are passed to the template. EJS templates allow you to generate HTML using plain JavaScript, making it easy to loop through items and output their values in your custom HTML.

To use a custom template, pass it in the `template` option for a listing:

Expand All @@ -26,22 +25,40 @@ listing:
template: gallery.ejs
```

A simple template for outputing a list of documents might look like:
A simple template for outputting a list of documents might look like:

``` html
````markdown
```{=html}
<ul>
<% for (const item of items) { %>
<li><a href="<%- item.path %>"><%= item.title %></a></li>
<% } %>
</ul>
```
````

which produces simple HTML output like:

![](images/listing-custom-output.png){.border}

When rendered, the above template will receive an array of listing items called `items`. When the contents of a listing are loaded from a list of documents, each of those items will be populated with the fields described in [Listing Fields](website-listings.qmd#listing-fields). In addition, any other fields included in a documents metadata will be passed as a property of the item, making it possible to use custom metadata in your documents and the listing display.

Because the EJS templates are processed by Quarto, the templates are intrinsically Markdown documents.
For example, if you want your listing `title` (*e.g.*, `My **bold** title`) to support Markdown formatting, you need to change the above simple template into:

````markdown
```{=html}
<ul>
<% for (const item of items) { %>
<li><a href="<%- item.path %>">
```
<%= item.title %>
```{=html}</a></li>
<% } %>
</ul>
```
````

::: {.callout-note}

Note that Quarto uses `lodash` to render the EJS templates. The `lodash` uses different syntax for HTML escaping text in templates.
Expand Down Expand Up @@ -71,7 +88,7 @@ listing:

could be rendered using:

```` html
````markdown
```{=html}
<ul>
<% for (const item of items) { %>
Expand Down Expand Up @@ -115,13 +132,17 @@ where the contents of `items.yml` is:
Portions of this website are built using custom listings. The best place to start is with [our gallery](/docs/gallery/index.qmd), which is a listing built using a custom template and a metadata file. You can view the source code used to create the gallery page in our [Github repository](https://github.com/quarto-dev/quarto-web).

| File | Description |
|-------------------------------------|-----------------------------------|
|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------|
| [gallery.yml](https://github.com/quarto-dev/quarto-web/blob/main/docs/gallery/gallery.yml) | The metadata that controls what items are displayed in the gallery listing. |
| [gallery.ejs](https://github.com/quarto-dev/quarto-web/blob/main/docs/gallery/gallery.ejs) | The template used to display the items on the page. |
| [index.qmd](https://github.com/quarto-dev/quarto-web/blob/main/docs/gallery/index.qmd) | The Quarto document that configures and positions the listing in the `#gallery` div. |

: {tbl-colwidths="\[30,70\]"}

::: {.callout-note}
Note that the `gallery.ejs` template does not allow its content to be read as Markdown.
:::

## Sorting, Filtering, and Pagination

By default, sorting, filtering, and pagination are disabled for custom listings templates, but with some simple changes to your template and listing options, you can add this capability to your custom listing. To do this, you need to include the following three things in your custom template:
Expand All @@ -134,7 +155,8 @@ By default, sorting, filtering, and pagination are disabled for custom listings

For example, we can modify the above `custom.ejs` template as follows:

``` html
````markdown
```{=html}
<ul class="list">
<% for (const item of items) { %>
<li <%= metadataAttrs(item) %>>
Expand All @@ -144,6 +166,7 @@ For example, we can modify the above `custom.ejs` template as follows:
<% } %>
</ul>
```
````

Once you have included these items in your template, you can then enable the options in your listing:

Expand Down Expand Up @@ -218,8 +241,10 @@ listing:

Template parameters can then be accessed in your template using `<%= templateParams.param1 %>`. For example, we can modify the above `custom.ejs` template as follows:

``` html
<h3><%= templateParams.param1 %></h3>
````markdown
### <%= templateParams.param1 %>

```{=html}
<ul class="pub-list list">
<% for (const item of items) { %>
<li <%= metadataAttrs(item) %>>
Expand All @@ -228,3 +253,4 @@ Template parameters can then be accessed in your template using `<%= templatePar
<% } %>
</ul>
```
````
Loading