# Umberto

## Installation
`npm install umberto`

## Building documentation of a single project
Note: The only documentation type supported at the moment is JSDoc.

**Step 1:** Create the `umberto.json` configuration file in the project's root directory or in the `docs` directory. This file will tell Umberto how to build documentation for this project.

You can also have a look at [CKEditor5](https://github.com/ckeditor/ckeditor5/tree/master/docs) as a reference.

### Example 1: `umberto.json`

```json
{
  "name": "CKEditor 5",
  "slug": "ckeditor5",
  "path": "docs",
  "startPage": "builds/guides/whats-new.html",
  "redirects": {
    "old-url": "new-url",
    "builds/guides/license-and-legal.html": "builds/guides/support/license-and-legal.html"
  },
  "googletagmanager": {
    "domains": [ "docs.ckeditor.com" ],
    "gtm": "GTM-XXXXXX"
  },
  "googleanalytics": {
    "domains": [ "docs.ckeditor.com" ],
    "config": { "trackingId": "U-XXX-Y" }
  },
  "feedbackWidget": {
	  "domains": [ "ckeditor.com" ],
	  "apiKey": "XXXXX"
  },
  "extraStyles": "assets/styles.css",
  "groups": [
    {
      "name": "API",
      "id": "api-reference",
      "sourceDir": "api",
      "slug": "api",
      "type": "jsdoc"
    },
    {
      "name": "Builds",
      "id": "builds",
      "slug": "builds",
      "categories": [
        {
          "name": "Guides",
          "id": "builds-guides",
          "slug": "guides",
          "categories": [
            {
              "name": "Integration",
              "id": "builds-integration",
              "slug": "integration",
              "order": 100
            },
            {
              "name": "Development",
              "id": "builds-development",
              "slug": "development",
              "order": 200
            }
          ]
        }
      ]
    }
  ],
  "items": [
    {
      "path": "packages/ckeditor5-autoformat",
      "prefix": "autoformat"
    }
  ],
  "github": {
    "url": "url/to/github/repo"
  },
  "scripts": {
    "snippet-adapter": "relative/path/to/snippetadapter",
    "precondition": "gulp docs:api"
  },
  "sitemap": {
    "hostname": "https://ckeditor5.github.io/docs/nightly",
    "excluded": [ "builds/guides/migrate.html" ],
    "extraUrlSettings": [
      {
        "url": "api/module_core_editor_editor-Editor.html",
        "priority": 0.8
      }
    ]
  },
  "canonicalUrlBeginning": "https://ckeditor.com/docs/",
  "variables": {
    "VARIABLE_NAME": "value"
  }
}

```

| Property  | Description  |
|---|---|
| `name` | Project name. |
| `slug` | Project slug to avoid name collisions. |
| `path` | Path where to look for documentation source files (Markdown files, images etc.). The path is relative to the location of `umberto.json`. |
| `startPage` | Path to page linked in drop down menu. If there is nothing provided, then `index.html` (from main project directory) is used. |
| `redirects` | Object where as a key is stored string representing `old-url` and as a value is stored string representing `new-url`. (_Currently redirects are used only in deployment scripts of big-bang docs._) |
| `googleoptimize` | `domains` - Array of whitelisted domains from which GO can be used; `id` - container ID |
| `googletagmanager` | `domains` - Array of whitelisted domains from which GA can be used; `gtm` - container ID |
| `googleanalytics` | `domains` - Array of whitelisted domains from which GA can be used; `config` - options passed to ga('create') method |
| `feedbackWidget` | `domains` - Array of whitelisted domains from which feedback widget can be used; `apiKey` - unique key for widget |
| `extraStyles` | Path to extra css relative to `path`. Accepts a string or an array of strings. Each project can append its own styles that way. |
| `groups` | A list of top-level groups into which the documentation is split. |
| `[group].name` | The name of a group. |
| `[group].id` | Group ID. For API docs it should always be `api-reference`. |
| `[group].sourceDir` | Directory inside of `path` where to look for this group's sources. |
| `[group].slug` | Human- and machine-readable name for this group to use when constructing URLs. |
| `[group].type` | For API docs it specifies the documentation tool used to generate docs from source comments. |
| `[group].categories` | Group's categories. |
| `items` | Sub-repositories. If not specified, it will be created automatically from `packages` directory. Source directory name can be changed by assigning a new string or an array of strings for the multiple directories to `config.packagesDir`, `'packages'` is default. |
| `[items].path` | Path to sub-repository. |
| `[items].prefix` | Sub-repository prefix. |
| `github.url` | Url to GitHub repository. Normally it is taken from `package.json` but can be specified here if needed. |
| `github.issueUrl` | An option which allows customizing the URL where user will be redirected after clicking the "Report an issue" button. An absolute URL should be provided. |
| `github.contributeUrl` | An option which allows customizing the URL where user will be redirected after clicking the "Contribute to this guide" button. An absolute URL should be provided. |
| `scripts` | External scripts and commands used by Umberto. |
| `scripts.snippet-adapter` | Function which generates live code snippets from {@snippet} tags. |
| `scripts.precondition` | Command to be executed before generating documentation. For example a gulp task running JSDoc on project's source code. |
| `sitemap` | Configuration object for sitemap.xml |
| `sitemap.hostname` | Hostname where documentation will be published. |
| `sitemap.excluded` | An array of urls to be excluded from the sitemap. |
| `sitemap.extraUrlSettings` | An array of settings per url. Currently only used to set custom priority per url. |
| `canonicalUrlBeginning` | String representing beginning of URL address added to canonical in html pages. Will be overwritten if defined in `umberto-main.json`. Default value: `https://ckeditor.com/docs/` |
| `variables` | Object contain list of macros which will replace its occurrence in documentation. More details in [variables](#variables) section. |

If Google Tag Manager is set then Google Analytics is not generated (as it is usually added into GTM).

Groups and categories can define the `order` in which the documentation will appear in the side navigation tree.

Make sure that documentation sources (e.g. API docs, JSON data) are stored in directories given by `umberto.json`.

Sample documentation setup for the example above:

```
<docs>
|---<api>
    |---*.json | (any JSON files generated by JSDoc in this case)
|---<builds>
    |---<guides>
        |---<development>
            |---*.md
        |---<integration>
            |---*.md
        |---*.md
    |---*.md
```

**Step 2:** Run Umberto:

`require ( 'umberto' ).buildSingleProject( options )`

* `skipApi` - skip building API docs,
* `skipSitemap` - skip building sitemap file,
* `skipThemes` - skip building themes,
* `skipValidation` - skip links validation,
* `skipLivesSnippets` - skip building live code samples,
* `snippetOptions` - options object passed to snippetAdapter building live code samples,
* `dev` - skip js minification, don't clear build directory when rebuilding docs, reuse unchanged files,
* `clean` - clear build directory before generating documentation,
* `verbose` - displays more information during generating documentation.
* `createSymLinks` - add symbolic links ('latest') to necessary projects in output folder.
* `watch` - activate watch mode in Umberto. Markdown files are rebuild and refreshed in destination directory without rebuilding rest of the documentation.
* `validateW3C` - activate validation of builded page with [The Nu Html Checker](https://github.com/validator/validator).

The documentation will be output to the `build/docs` directory.

## Combined documentation of multiple projects

`require ( 'umberto' ).buildMultiProjects( options )`

`umberto-main.json` is required in the root of a combined documentation project.

Example:

```
{
    "name": "CKEditor Ecosystem",
    "logo": "project-logo.svg",
	"projects": [
		"projects/ckeditor4",
		"projects/ckeditor5",
		"projects/ckfinder"
	],
	"ignoredProjects": [
		"ckeditor4",
		"ckfinder"
	],
	"additionalDocumentation": {
		"projects/ckeditor5": [
			"projects/ckeditor5-extra/extra-feature",
			"projects/ckeditor5-extra/new-features"
		],
		"projects/ckfinder": [
			"ckfinder-docs"
		]
	}
	"commonFilesPath": "common-files/",
	"canonicalUrlBeginning": "https://ckeditor.com/docs/"
}
```

| Property  | Description  |
|---|---|
| `name` | Project name to be displayed on the home page. |
| `logo` | Path to the logo image file to be displayed on the home page. |
| `projects` | An array of paths to documented project directories. These projects should contain umberto.json files and follow conventions of single project scenario. |
| `commonFilesPath` | Path to a directory containing files common for entire project. Example: robots.txt, index.md which is the home page. |
| `additionalDocumentation` | Object containing information about additional paths with documentation for given projects. |
| `additionalDocumentation.<Project_Name>` | Array of paths relative to `umberto-main.json` where additional documentation for `<Project_Name>` are stored. `<Project_Name>` is string used in `projects` section inside this config. |
| `canonicalUrlBeginning` | String representing beginning of URL address added to canonical in html pages. Value overwrites definition in `umberto.json`. Default value: `https://ckeditor.com/docs/` |
| `ignoredProjects` | String or Array of strings with slugs of projects which links won't be converted during docs generation. |
| `variables` | Object contain list of macros which will replace its occurrence in documentation. More details in [variables](#variables) section. Variables from umberto-main overwrites variables from project config. |

For the example above, project-logo.svg should be located in common files directory.

## Using a local version of Umberto

```
cd umberto
npm link            # Creates a global link.

cd ../bigbang-docs.ckeditor.com
npm link umberto    # link-install the package
```

## Shortcuts
Documentation created with umberto provides shortcut <kbd>Shift</kbd>+<kbd>D</kbd>, which allows on presentation longnames of API entries. Shortcut works as a toggle.
Current value is stored in local storage and it is preserved when user moves between documentation pages.

## Writing guides

### Location

All guides should be written in Markdown and placed in the `docs` directory of the documented project. Further directory structure does not matter for Umberto, because guides output location is determined by the guide category (see [category](https://github.com/cksource/umberto#category)). However, it is a recommended convention to put guides in a directory structure reflecting the category structure.

### File name

Every guide in the same directory or belonging to the same category should have a unique file name.

### Front-matter

Every guide should have a front-matter at the top, which looks like this:

```
---
layout: page [optional]
category: builds-guides
title: Overview [optional]
slug: overview [optional]
order: 10 [optional]
toc: false [optional]
toc-limit: 5 [optional]
badges: [ premium, ... ] [optional]
sitenav: false [optional]
feedback-widget: false [optional]
menu-title: Overview whatever [optional]
meta-title: <title> tag's exact content [optional]
meta-title-short: <title> tag's content. Automatic suffix will be added (e.g. "- CKEditor 5 Documentation") [optional]
meta-description: <meta name="description"> content [optional]
contributeUrl: [optional] {Boolean/String} If `undefined` or `true` then default URL is generated. If `false` then no URL is generated. Otherwise provided string is used as URL.
issuesUrl: [optional] {Boolean/String} If `undefined` or `true` then default URL is generated. If `false` then no URL is generated. Otherwise provided string is used as URL.
modified_at: [optional] {String} A date that should follow the format: YYYY-MM-DD. Represents the last editing of the guide. Starting from the date, in the project navigation will be displayed the indicator "🆕" over 90 days.
---
```

#### category

Each guide has to be assigned to a category (category ID). Categories are defined in the `umberto.json` file of the documented project. Category ID should be used in front-matter.

The category also defines the output location of a guide after processing by Umberto.

Example:

A guide named `overview.md` with the following front-matter:

```
---
category: builds-guides
---
```

in the [ckeditor5](https://github.com/ckeditor/ckeditor5) project, with [this](https://github.com/ckeditor/ckeditor5/blob/master/docs/umberto.json#L89) `umberto.json` file, will be written to `<PROJECT_BASE_PATH>/builds/guides/overview.html` because the `builds-guides` category has a slug `guides` and belongs to the `builds` category (categories can be nested).

Use `category: none` for pages not belonging to any category, e.g. 404 page. 404 page should also specify `layout: 404` in front matter.

#### title [optional]

If no `<h1>` heading is present in a guide, the title will be used to create the guide title automatically. It is recommended to put a `<h1>` heading in a guide and skip this option.

#### folded [optional]

If defined and set to `true`, the category will be folded.

#### slug [optional]

If `slug` is defined, the guide's file name after processing by Umberto will be changed to the slug.

#### order [optional]

Can be set to sort the guides within the same category. If skipped, guides are sorted alphabetically by title.

#### toc [optional]

If defined and set to `false`, table of contents will not be rendered.

#### toc-limit [optional]

If defined and set to `0` or greater integer, the table of contents will be limited to the defined depth (e.g. for value `2`, only `<h2>` and `<h3>` headings will be shown in the table of contents). Value `0` is an equivalent of using `toc: false`.

#### sitenav [optional]

If defined and set to `false`, there will be no left-side navigation and main content will be centered.

#### feedback-widget [optional]

If defined and set to `false`, feedback widget element will not be rendered at the end of page.

#### menu-title [optional]

Guide title to be displayed on the navigation tree (if it should be different from the original guide's title).

### Tags and other features

Tags are strings which can be used in guides and are replaced by Umberto with generated content (e.g. links, code snippets).

#### Links to API reference

Syntax:

```
{@link longname linkText}
```

Example:

```
{@link module:ui/template~Template#render Render method}
```

**Note:** If `longname` doesn't start with `module:`, please use `@linkapi` instead of `@link`.

Example links for CKEditor 4:

`{@linkapi CKEDITOR.config Configuration Reference}` -> https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_config.html

`{@linkapi CKEDITOR.dialog.definition.uiElement UI element definition}` -> https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_dialog_definition_uiElement.html

`{@linkapi CKEDITOR.dialog.definition#resizable resizable}` -> https://docs.ckeditor.com/ckeditor4/latest/api/CKEDITOR_dialog_definition.html#resizable

**Important:** Cross-project links `{@link @projectName longname linkText}` are no longer supported.

##### longname

The "path" to an API entity. It must begin with `module:` followed by the package name, module name and class name with a `~`.

Example:

Linking to [EditorConfig](https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/api/module_core_editor_editorconfig-EditorConfig.html) should be done like this:

```
{@link module:core/editor/editorconfig~EditorConfig Editor Config}
```

If you want to link to a specific property or method, type its ID after the `#`:

```
{@link module:core/editor/editorconfig~EditorConfig#plugins Editor Config}
```

##### linkText

The text that should appear as a link in the guide.

**Note:** When linking to package pages, please follow the convention below (Links to guides).

Example:

```
{@link api/ui UI Package Documentation}
```

#### Links to Examples in CKEditor4 project

Syntax:
```
{@linkexample exampleFileName linkText}
```

The `exampleFileName` is name of an **output file** without extension which present sample in CKEditor4 project. File is linked to content of `sdk` folder.

Example:
```
{@linkexample index CKEditor Example}
```
```
{@linkexample fileupload#uploading-dropped-and-pasted-images &#x201C;Uploading Dropped and Pasted Images&#x201D;}
```

#### Links to guides

Syntax:

```
{@link pathToGuide linkText}
```

The `pathToGuide` must be the physical path to the guide file from the `docs` directory.

Example:

A link to https://github.com/ckeditor/ckeditor5/blob/master/docs/builds/guides/overview.md should be:

```
{@link builds/guides/overview Builds overview}
```

**Note:** It is possible to link to a guide from a JSDoc comment using `{@glink}` tag (so that Umberto can distinguish it from a regular JSDoc's `{@link}` tag):

```
{@glink finalPathToGuide linkText}
```

**Important:** In this case `finalPathToGuide` **must be** a guide's final URL. Final URL may be different than guide's physical path (usually it's the same though)

Example:

```
{@glink builds/guides/migrate Migration guide}
```

**Important:** Cross-project links (`{@link @projectName pathToGuide linkText}` or `{@glink @projectName finalPathToGuide linkText}`) are no longer supported.

#### Links escaping

Umberto allows on link escaping, when curly brackets are preceed with backslash.
There are required 2 backslashes for regular text and single backslash inside code blocks.

Examples:
* `\\{@link path name\\}` will be transformed into `{@link path name}` in output page.
* `` `\{@link path name\}` `` will be transformed into `<code>{@link path name}</code>` in output page.

#### Importing a guide into another guide

It is possible to import a guide into another guide within the same project. This is useful when a guide needs to appear in different categories and user wants to avoid maintaining duplicated content.

Syntax:

```
{@importguide path/to/guide}
```

Example:

```
{@importguide builds/guides/overview}
```

#### Images

Syntax of the `{@img}` tag:

```
{@img pathToImg alt text}
```

It is possible to specify the image width as well:

```
{@img pathToImg width alt text}

// Example
{@img assets/img/feature-link.png 503 Simplified link dialog.}
```

The `pathToImg` must be a physical path to the image from the `docs` directory, including the file extension.

The `alt text` is the `alt` attribute of the `<img>` tag.

The `width` must be an integer that has at least two digits.

**Note:** Images can be added using standard HTML `<img>` tags, too:

```
<img src="%BASE_PATH%/path/to/image.png">
```

Note: `%BASE_PATH%` should be typed literally (it will be converted to something like `ckeditor5/0.10.0`).

The `path/to/image.png` is the path to the image relative to the `docs` directory.

#### Code snippets

Markdown syntax can be used for basic code snippets using the triple backtick (```):

``` html
<div class="foo">
<p>Lorem ipsum...</p>
</div>
```

#### The {@snippet} tag

Live Snippets are pieces of code generated by the Snippet Adapter. Every project provides its own Snippet Adapter to Umberto. [CKEditor5](https://github.com/ckeditor/ckeditor5) snippets are examples of actual editor so they require building before being inserted into a guide.

Syntax:

```
{@snippet pathToSnippet}
```

The `pathToSnippet` is a path relative to the `docs/_snippets` directory and ends with the snippet file name without extension.

Note: Every Live Snippet should be placed inside the `docs/_snippets` directory; it can be nested into more directories. HTML, JS, CSS (and other) files of the same snippet should have the same file name.

Example:

[ClassicEditor Sample](https://github.com/ckeditor/ckeditor5/blob/master/docs/_snippets/examples/classic-editor.html) is generated from the following tag:
```
{@snippet examples/classic-editor}`
```

If you need to add an image in a snippet, you can use:

```
<img src="%BASE_PATH%/path/to/image.png">
```

where `path/to/image.png` is the path to the image relative to the `docs` directory.

#### Notices

```
<info-box type>
Content
</info-box>
```

Notices can be used to highlight some important information.

Example [here](https://ckeditor5.github.io/docs/nightly/ckeditor5/latest/builds/guides/development/custom-builds.html#Forking-an-existing-build):

```
<info-box hint>
	If you do not want to fork the official build, you can just clone it. However, you will not be able to commit and push your customizations back to [GitHub](https://github.com).
</info-box>
```

Available box types:
* info (default)
* hint
* warning

#### Errors documentation

Use `{@errors}` tag to insert a list of errors into a guide.

#### Autolinker

By default, Hexo will replace all URLs with `HTMLAnchorElement`. In other words, if parser finds a URL-like string, it will become to `<a href="URL" target="_blank">URL</a>`.

In order to disable this option, you need to wrap your text in `{% raw %}` and `{% endraw %}` tags.

Examples:

```
Default behaviour:
ASP.NET => <a href="http://ASP.NET" target="_blank">ASP.NET</a>
```

```
Disable autolinker:
{% raw %}ASP.NET{% endraw %} => ASP.NET
```

### Link validation

If it is needed to have a link, which shouldn't be validated, add `data-skip-validation="true"` to the link.

## Writing Examples for CKEditor4

Umberto can transform html files formerly used in SDK repository, to proper Example page. However there is few important parts which need to be fulfilled to properly convert such document.

### Example content

Example content is generated from html element with class `sdk-contents`.
HTML Element with this class can also poses attribute `data-cke-preset` (e.g `data-cke-preset="full"`). Such content use CKEditor from CDN resources instead of locally build one.

### Meta tags

There are used few metatags, which control how Example is processed by Umberto:

| Meta tag name | Description |
| --- | --- |
| sdk-samples | Name of samples present as source codes at the end of page. If there is multiple samples, each title is separate with pipe character. |
| sdk-category | Name of category where belong given example page. |
| sdk-order | Order value, which determine how samples are sorted in navigation tree. |

### Other tags
Umberto also search for other tags with specific attributes, to properly render Exmpele page.

| Name of \<tag\>/attribute | Description |
| --- | --- |
| \<title\> | Content of this tag is used as name in navigation tree. |
| data-sample | Attribute added to multiple tags on page. Tags with the same number will be combined as one outputted source code. If given code might exists in multiple samples, then more values might be added after comma, eg ( `data-sample="1,2,4"` ). Number in data sample is related to position of title in meta tag `sdk-samples`. |
| data-sample-short | Content of text area is replaced with default short value. Content is defined in umberto.json as `shortEditorContent` under sdk category. |
| data-sample-preserve-whitespace | Preserves tabulator characters used in source code. |
| data-sample-strip-outer-tag | Removes outer tag when its content is used inside "Get source code" section on example's page. |
| data-sample-template | Name of template which is used to display "Get source code" section. Currently only `empty` parameter is supported, which prevents of using default template. |
| data-sample-highlighter | Name of syntax highlighter which should be used for given sample (default is used `html`). You can define other such as `js`, `jsx`, etc. List is based on currently supported syntax highlighter in Umberto. |
| type="template" | Content of such tag will be directly added to outputed code. It might be helpful to provide some links or scripts in samples, which you don't want to be loaded/executed on example page. E.g `&lt;link href="../template/theme/css/sdk-inline.css" rel="stylesheet" /&gt;`. `<` and `>` characters have to be encoded. |

### Macros:
In content might appear macros which will be replaced during samples building.

| Macro | Description |
| --- | --- |
| \{%CKEDITOR_VERSION%\} | CKEditor version used to build current samples, e.g. `4.11.1` |
| \{%CKEDITOR_EXAMPLES_SLUG%\} | Examples slug, path where are stored all examples in build docuemntation. E.g `examples` |

## Variables:
Umberto provides possibility to use customizable macros in documentation. Those values will be replace during documentation generation. To use this feature you need to define `variables` object in `umberto.json` and/or `umberto-main.json`. Variables provide in `umberto-main.json` takes precedence.

### Usage:
Variables have to be written in capital letters (also allowed characters are numbers and underscore). In text variables have to be used as macros surounded with `{%` and `%}` strings.

E.g.
* `umberto.json`
	```json
	{
		...
		"variables": {
			"VAR_1": "first",
			"VAR_2": "second"
		}
		...
	}
	```

* `umberto-main.json`
	```json
	{
		...
		"variables": {
			"MAIN_VARIABLE": "MAIN",
			"VAR_2": "Foo bar baz"
		}
		...
	}
	```

* `index.md`
	```md
	{%VAR_1%}
	{%VAR_2%}
	{%MAIN_VARIABLE%}
	```

* output html
	```html
	first
	Foo bar baz
	MAIN
	```

## Pre-rendering components

> ⚠️ **Warning**: This feature is only available with the Gloria theme.

### Overview

Pre-rendering components lets you use XML-like custom component syntax in Markdown files that gets converted to Pug templates. This allows for a more intuitive HTML-like syntax in documentation while leveraging the power of Pug mixins for rendering complex UI components. It also reduces CLS (First Contentful Paint) by pre-rendering components before the page is fully loaded and makes the site more accessible by adding aria attributes to the components.

The main implementation can be found in `/scripts/filter/before-post-render/gloria/prerender-xml-pug-components.js`.

### How It Works

The process works in two steps:

1. **Before markdown rendering**: Components are identified, processed, and replaced with markers
2. **After markdown rendering**: Markers are replaced with the fully rendered components

This approach prevents Markdown processors from misinterpreting HTML indentation and nested structures, avoiding unwanted paragraph breaks, incorrect formatting, or stripped content. It's also possible to use Markdown syntax inside the component content and place nested components in the content of the previously defined component.

The component syntax is defined with a prefix `ck:`. For example:

```html
<ck:banner variant="primary" label="Get started" href="https://example.com">
	This is a banner with a **link**.
	<ck:button-link variant="secondary" label="Learn more" href="https://example.com/learn-more" />
</ck:banner>
```

Is translated into:

```pug
+banner({ variant: 'primary', label: 'Get started', href: 'https://example.com' })
	| This is a banner with a **link**.
	+button-link({ variant: 'secondary', label: 'Learn more', href: 'https://example.com/learn-more' })
```

### Component Definition

Components are defined in the `COMPONENTS` array in the `prerender-xml-pug-components.js` file. Each component definition includes:

* `tag`: The XML-like tag to match in Markdown content
* `pug`: Configuration for rendering with Pug
  * `mixinName`: The name of the Pug mixin to call
  * `path`: Path to the Pug file containing the mixin
  * `allowMarkdownContent`: Whether to render markdown in the component content
  * `slots`: Optional array of child components that can be nested

Example component definition:

```javascript
{
	tag: 'ck:banner',
	mixinName: 'banner',
	requires: [ /* ... */ ],
	allowMarkdownContent: true
}
```

### Slot components

```html
<ck:tabs>
	<ck:tab id="desktop" label="Desktop" active="true">
		This is the desktop tab content.
	</ck:tab>

	<ck:tab id="mobile" label="Mobile">
		Use the **main menu button** in the upper-left corner to navigate through the documentation.
	</ck:tab>
</ck:tabs>
```

which is translated into:

```pug
+tabs
	+tab({ id: 'desktop', label: 'Desktop', active: true })
		| This is the desktop tab content.
	+tab({ id: 'mobile', label: 'Mobile' })
		| Use the **main menu button** in the upper-left corner to navigate through the documentation.
```

The `tab` components is child mixin of the `tabs` component. It's NOT globally available. It means that you cannot use `+tab` outside of the `tabs` component and it can modify internal state of the `tabs` component.

They can be defined as follows:

```pug
mixin tabs( options )
	- const tabs = {};

	mixin tab({ id, label, active } = {})
		-
			tabs[ id ] = {
				label,
				active
			}

	- block ? block() : undefined;

	.c-tabs
		each tab, id in tabs
			= tab.label

			//- ....
```

### Available Components

All available components can be found in the Gloria theme's components directory: `/themes/umberto/layout/gloria/_components`.

This directory contains all Pug mixins that can be used with the pre-rendering system. Each component typically has its own subdirectory containing:

1. The primary `index.pug` file with the mixin definition
2. Additional files for complex components
3. Sometimes SCSS styles in a separate file

Some of the most commonly used components include:

* `banner` - For promotional banners
* `button` - Button components
* `callout` - For information, warning, and error callouts (info-box)
* `code-switcher` - For tabs that switch between code samples
* `svg` - For inline SVG and spritesheet icons
* `tabs` - For tabbed content

To see all available components and their parameters, browse the directories within the `_components` folder. Each component's implementation can be studied to understand the available options and parameters.

## Pre-rendering icons

> ⚠️ **Warning**: This feature is only available with the Gloria theme.

Icons are implemented using an SVG spritesheet approach for better performance. It means that all icons are combined into a single SVG spritesheet tag somewhere in the document. This reduces the number of HTTP requests and improves loading times. Only used icons are included in the spritesheet. In order to use additional icon you need to preload it using `preload-spritesheet-svg` mixin.

### Icon Usage

There are three ways to use icons:

1. **Using plain svg mixins**
   ```pug
   +svg-icon({ icon: 'github', size: 'lg', title: 'GitHub' })
   //- or
   +svg({ file: 'icons/github', fill: 'currentColor' })
   ```

2. **Using bound component** (used in Markdown):
   ```html
   <ck:svg-icon icon="github" size="lg" title="GitHub"></ck:svg-icon>
   <!-- or -->-
   <ck:svg file="icons/github" fill="currentColor" />
   ```

3. **Web Component** (used in JavaScript):
   ```html
   <svg-icon icon="github" size="lg" title="GitHub"></svg-icon>
   ```

   Remember to preload the icon before using it in JavaScript!

### Preloading Icons

For icons that will be dynamically added via JavaScript and aren't initially visible on the page, you can preload them to ensure they're included in the spritesheet:

```html
<ck:preload-svg-spritesheet-icon icon="menu" />
<!-- or -->
<ck:preload-spritesheet-svg file="icons/menu" />
```

Or using the icon mixin:

```pug
+preload-svg-spritesheet-icon({ icon: 'menu' })
//- or
+preload-spritesheet-svg({ file: 'icons/menu' })
```

### How icons are loaded

1. During the build process, all icons used with `data-spritesheet-svg` are collected
2. A single SVG spritesheet is created with all these icons as `<symbol>` elements
3. The spritesheet is injected at the beginning of the `<body>` with `display: none`
4. When an icon is needed, it references the spritesheet using `<use href="#icon-id"></use>`

This approach significantly reduces HTTP requests and improves page performance when multiple icons are used.

The spritesheet generator is implemented in `/scripts/filter/after-render/gloria/spritesheet-svg.js`.

## Releasing the package

CircleCI automates the release process and can release both channels: stable (`X.Y.Z`) and pre-releases (`X.Y.Z-alpha.X`, etc.).

Before you start, you need to prepare the changelog entries.

1. Make sure the `#master` branch is up-to-date: `git fetch && git checkout master && git pull`.
1. Prepare a release branch: `git checkout -b release-[YYYYMMDD]` where `YYYYMMDD` is the current day.
1. Generate the changelog entries: `yarn run release:prepare-changelog`.
   * You can specify the release date by passing the `--date` option, e.g., `--date=2025-06-11`.
   * By passing the `--dry-run` option, you can check what the script will do without actually modifying the files.
   * Read all the entries, correct poor wording and other issues, wrap code names in backticks to format them, etc.
   * Add the missing `the/a` articles, `()` to method names, "it's" -> "its", etc.
   * A newly introduced feature should have just one changelog entry – something like "The initial implementation of the FOO feature." with a description of what it does.
1. Commit all changes and prepare a new pull request targeting the `#master` branch.
1. Ping the `@ckeditor/ckeditor-5-platform` team to review the pull request and trigger the release process.
