---
title: "Custom styles"
description: "Create custom styles for displaying the metadata of your Data Package."
order: 3
---

Flower comes with a number of
[built-in styles](/docs/design/interface/outputs.qmd#built-in-styles),
but it is also possible to create new styles that match your particular
use case. Custom styles can only be used with the `build` command and
not with `view`.

Creating a custom style involves making templates and using
configuration files to set the layout and structure of the documentation
generated from the `datapackage.json` file.

In this guide, you will walk through how to create a custom style that
generates one Markdown file for the Data Package as a whole and separate
Markdown files for each data resource. To demonstrate this custom style,
you will use the following Data Package about a (fake) study on flowers
and their growing conditions.

::: {.callout-tip collapse="true" appearance="minimal"}
## Expand to see the `datapackage.json` content

``` {.json filename="datapackage.json"}
{{< include /docs/includes/datapackage.json >}}
```
:::

At the end of this page and after completing all the steps, your file
structure will look like the below:

``` txt
flora/
├── datapackage.json
├── .flower.toml
└── templates/
    ├── sections.toml
    ├── package.qmd.jinja
    ├── contributors.qmd.jinja
    └── resource.qmd.jinja
└── docs/
    ├── index.qmd
    └── resources/
        ├── species_catalog.qmd
        └── growth_records.qmd
```

The first step is to set up the files within the `templates/` folder.

## Creating the templates

You can define a custom layout for your metadata (or part of your
metadata) using a
[Jinja2 template](https://jinja.palletsprojects.com/en/stable/). In this
template, you write out the structure of your desired output in your
target language (e.g., HTML, markdown, yaml, etc.), using placeholder
values for the metadata elements that will come from your
`datapackage.json`.

In this guide, you will create template files containing the Data
Package's general metadata, the contributor metadata, and metadata for
each resource contained in the Data Package. To start, create a new
directory for the templates and give it a descriptive name:

``` txt
flora/
├── datapackage.json
└── templates/
```

You can store your templates wherever it makes sense for your project;
in this example, call the template folder `templates/` and put it inside
the root of the Data Package folder. Inside the template folder, create
three files, one for each type of metadata listed above.

- `package.qmd.jinja` for the general metadata.
- `contributors.qmd.jinja` for the contributor metadata.
- `resource.qmd.jinja` for each resource's metadata.

The `.qmd.jinja` extension indicates that the file is a `jinja` template
that will create a `qmd` file. If you wanted to create an `html` file
instead, the extension would be `.html.jinja`.

Next, set your desired layout for the generated documentation in each
template. Since Flower uses Jinja2 as its templating engine, you need to
use Jinja syntax when accessing values from the Data Package metadata.

### `package.qmd.jinja`

Start with the `package.qmd.jinja` template. Define the layout for
package properties by writing a template that looks like:

``` {.djangotemplate filename="templates/package.qmd.jinja"}
---
title: "{{ package.title or package.name }}"
subtitle: "Version: {{ package.version }}"
date: "{{ package.created }}"
---

{{ package.description }}
```

Here, Jinja syntax is used to access properties on the metadata object
passed to the template as `package`. Double curly brackets `{{{...}}}`
are used to output the value of a variable or expression. In this
example, `{{{ package.title or package.name }}}` sets the title of the
generated document to the `title` property of the package metadata, or
to the `name` property if `title` is not available. You can use any name
for the metadata object passed to the template (e.g., `root` or
`data_package` instead of `package`); this variable name will be defined
in the `sections.toml` configuration file.

Jinja also provides built-in filters and functions for processing
values, as well as control flow statements such as conditionals and
loops. Below, you will extend `package.qmd.jinja` to include a list of
keywords that describe the Data Package. An `if` statement is used to
check if the `keywords` property exists in the package metadata. If it
does, it will output a line with the keywords joined by commas using the
built-in Jinja `join` filter. You can learn more about advanced Jinja
features in the
[Jinja documentation](https://jinja.palletsprojects.com/en/stable/templates/).

``` {.djangotemplate filename="templates/package.qmd.jinja"}
---
title: "{{ package.title or package.name }}"
subtitle: "Version: {{ package.version }}"
date: "{{ package.created }}"
---

{{ package.description }}

{% if package.keywords %}
**Keywords:** {{ package.keywords | join(", ") }}
{% endif %}
```

### `contributors.qmd.jinja`

In the `contributors.qmd.jinja` template, you will define the layout for
the contributors (using the variable name `contributors`). You could
include the contributors in the `package.qmd.jinja` template, but, to
show how to split content across templates, you will create a separate
template.

``` {.djangotemplate filename="templates/contributors.qmd.jinja"}
## Contributors

{%- if contributors %}
{% for contributor in contributors %}
### {{ contributor.title }}

{%- if contributor.organization %}
**Organization:** {{ contributor.organization }}
{% endif %}

{% if contributor.email -%}
**Email:** <{{ contributor.email }}>
{%- endif %}
{% endfor %}

{% else %}
No contributors listed.
{% endif %}
```

### `resource.qmd.jinja`

A Data Package can contain multiple data resources, and you may want to
display the metadata of each resource in a separate file with the same
layout. To do this, you can create a template that defines the layout
for a single resource and then use the `sections.toml` configuration
file to indicate that this template should be applied to each resource
in the Data Package. In the template, the variable name `resource` is
used to refer to the metadata of any single resource that will be
rendered with the template.

``` {.djangotemplate filename="templates/resource.qmd.jinja"}
---
title: "{{ resource.title or resource.name }}"
---

{{ resource.description }}

## Overview

- **Name:** `{{ resource.name }}`
{% if resource.path %}
- **Path:** `{{ resource.path }}`
{% endif %}

{%- if resource.schema and resource.schema.fields %}
- **Number of fields:** {{ resource.schema.fields | length }}
{% else %}
- **Number of fields:** 0
{% endif %}
```

::: callout-note
The template variable can reference any property or collection of
properties in the `datapackage.json` that is possible to select using
[JSON path notation](https://jg-rp.github.io/python-jsonpath/syntax/).
This JSON path will be defined in the `sections.toml` configuration
file.
:::

## Creating the configuration files

### Main configuration file

The main configuration file is used to set the template and output
folders for the documentation. Flower can read the main configuration
from the `.flower.toml` or the `pyproject.toml` file in the root of your
Data Package. In this guide, you will use `.flower.toml`.

Create a `.flower.toml` file in the root of your Data Package and add
the following settings:

``` {.toml filename=".flower.toml"}
# Point Flower to the folder containing your templates
template-dir = "templates/"
# Specify where the output files should be generated
output-dir = "docs/"
```

::: callout-note
The `style` field in the main configuration file is for specifying a
built-in style and should not be used when creating a custom style. If
you want to use a built-in style, leave `template-dir` unset and set
`style` to the name of your chosen built-in style.
:::

### `sections.toml` configuration file

The `sections.toml` file is used to define how many output files will be
created and which metadata will be displayed in each file. Documentation
is split into sections, where each section corresponds to one output
file (e.g., an index file) or a group of similar output files (e.g., a
file for each resource).

The `sections.toml` file must be stored in the template folder.

#### Adding `[[section]]`s

Create a `sections.toml` file in the `templates/` folder. Inside, add a
`[[section]]` for each output file or group of output files you want to
create:

``` {.toml filename="templates/sections.toml"}
# One output file at docs/index.qmd
[[section]]
output-path = "index.qmd"

# One output file for each resource in docs/resources/
[[section]]
output-path = "resources/"
```

::: callout-tip
To generate more than one output file for a section, `output-path` can
be set either to a folder (e.g., `resources/`) or to a file path with a
placeholder for the file name (e.g., `resources/{resource-name}.qmd`).
See the [`Section`](/docs/design/interface/config.qmd#section)
documentation for more details.
:::

#### Adding `[[section.contents]]`s

Each section contains one or more content items, with each content item
corresponding to a specific part of the metadata (e.g., the
contributors). A content item links this specific part of the metadata
to the template that will be used to render it. In the rendered output,
content items in the same section will be combined into the same output
file in the order they are defined.

Add content to each section, specifying the following fields:

- `jsonpath`: The JSON path to the metadata that will be sent to the
  template. The JSON path should be expressed using
  [JSON path syntax](https://jg-rp.github.io/python-jsonpath/syntax/).
- `template-path`: The path to the Jinja template file for this content
  item, relative to the template folder.
- `jinja-variable`: The variable name that will be used in the template
  to reference the selected metadata.
- `mode`: Whether to render the selected metadata item as one output
  file (`one`) or to render each item in the selected metadata
  collection as a separate output file (`many`).

``` {.toml filename="templates/sections.toml"}
[[section]]
output-path = "index.qmd"

[[section.contents]]
# Select the whole metadata object
jsonpath = "$"
# Render the selected metadata with this template
template-path = "package.qmd.jinja"
# Reference the selected metadata in the template with this
# variable name
jinja-variable = "package"
# Render the selected metadata item as one output file
mode = "one"

# The contents of this section will be appended to the contents
# of the previous section inside the `docs/index.qmd` file.
[[section.contents]]
jsonpath = "$.contributors"
template-path = "contributors.qmd.jinja"
jinja-variable = "contributors"
mode = "one"

[[section]]
output-path = "resources/"

[[section.contents]]
jsonpath = "$.resources"
template-path = "resource.qmd.jinja"
jinja-variable = "resource"
# Render each item in the selected metadata collection as a
# separate output file
mode = "many"
```

## Running the `build` command

To generate the documentation, run the `build` command in the Terminal
from the root of your Data Package:

``` {.bash filename="Terminal"}
seedcase-flower build
```

This will read the configuration files (`.flower.toml` and
`sections.toml`), populate the templates (in the `templates/` folder)
with metadata from `datapackage.json`, and output the generated
documentation files to the specified output directory (`docs/` in this
example).

Your file structure should now look like:

``` txt
flora/
├── datapackage.json
├── .flower.toml
└── templates/
    ├── sections.toml
    ├── package.qmd.jinja
    ├── contributors.qmd.jinja
    └── resource.qmd.jinja
└── docs/
    ├── index.qmd
    └── resources/
        ├── species_catalog.qmd
        └── growth_records.qmd
```
