= Antora Default UI
// Settings:
:hide-uri-scheme:
// URLs:
:url-antora: https://antora.org
:url-repo: https://gitlab.com/antora/antora-ui-default
:url-preview: https://antora.gitlab.io/antora-ui-default
:url-hbs: https://handlebarsjs.com
:url-gulp: https://gulpjs.com
:url-npm: https://npmjs.com
:url-node: https://nodejs.org
:url-nvm: https://github.com/creationix/nvm
:url-nvm-install: {url-nvm}#installation
:url-git: https://git-scm.com
:url-git-dl: {url-git}/downloads

This project produces the {url-preview}[default UI bundle] for documentation sites generated with {url-antora}[Antora].
It contains the UI assets (page templates, CSS, JavaScript, images, etc.) and a Gulp build script.
The build can be used to preview the UI locally (featuring live updates), or to package it for consumption by the Antora site generator.

This documentation explains how to use this project to set up, customize and manage a UI for a documentation site generated with Antora.
After reading it, you'll be able to:

* [x] Understand how an Antora UI project is structured.
* [x] Set up your environment to work on the UI project.
* [x] Launch a preview server to visually inspect the UI.
* [x] Adopt a development workflow to share and accept changes to the UI.
* [x] Package a UI for your documentation site that Antora can use.

== File type and technology overview

The Antora UI consists of the following file types that are used to structure and style the documentation site pages generated by Antora.

* Handlebars "`page`" templates (layouts, partials, and helpers)
* CSS (enhanced using PostCSS)
* JavaScript (UI scripts)
* Images / Graphics (specific to the UI)
* Fonts
* Sample content for previewing the UI (HTML and UI model)

To understand how the UI works, let's begin by surveying the primary technologies used by the UI.

Handlebars (file extension: `.hbs`)::
{url-hbs}[Handlebars] is a "`logic-less`" templating engine used to create HTML from template files.
Templates contain placeholders (i.e., mustache expressions like `+{{{page.title}}}+`) into which content is injected from a model.
They also accommodate simple logic expressions for repeating content or including it conditionally (e.g., `+{{#each navigation}}+`) as well as partials (e.g., `+{{> header}}+`).

Gulp (script file: [.path]_gulpfile.js/index.js_)::
{url-gulp}[Gulp] is a build tool for JavaScript projects.
It configures a collection of tasks that can be used to perform automated tasks such as compiling files, running a preview server, or publishing a release.

npm (command: `npm`)::
npm manages software packages (i.e., software dependencies) that it downloads from {url-npm}.
Software this project uses includes libraries that handle compilation as well as shared assets such as font files that are distributed as npm packages.
npm is part of Node.js.

package.json:::
This file keeps track of the dependencies (described using fuzzy versions) that npm (or Yarn) should fetch.

package-lock.json:::
This file contains a report of which dependencies npm resolved.
This information ensures that dependency resolution is reproducible.

node_modules/:::
A local cache of resolved dependencies that npm (or Yarn) fetches.

PostCSS::
This project does not use a CSS preprocessor such as Sass or LESS.
Instead, it relies on normal CSS which is enhanced by a series of postprocessors.
The most common postprocessor backports newer CSS features to older browsers by adding properties with vendor prefixes.

== UI project versus UI bundle

The [.term]*UI project*, which is comprised of the source files in the git repository, provides the recipe and raw materials for creating an Antora UI bundle.
It includes a build, source files, project files, and dependency information.
This is your development workspace.

The [.term]*UI bundle*, a distributable archive, provides pre-compiled (interpreted, consolidated, and/or minimized) files that are ready to be used by Antora.

=== UI project repository structure (default branch)

You should think of the UI project's default branch as your UI workspace.
It contains the recipe and raw materials for creating a UI, including a build, source files, project files, and dependency information.

Here's how the files are structured in the UI project:

[.output]
....
README.adoc
gulpfile.js/
  index.js
  lib/
  tasks/
package.json
package-lock.json
src/
  css/
    base.css
    breadcrumbs.css
    ...
  helpers/
    and.js
    eq.js
    ...
  img/
    back.svg
    caret.svg
    ...
  layouts/
    404.hbs
    default.hbs
  partials/
    article.hbs
    breadcrumbs.hbs
    ...
  js/
    01-navigation.js
    02-fragment-jumper.js
    ...
    vendor/
      highlight.js
preview-src/
  index.html
  ui-model.yml
....

A Gulp build is used to compile and assemble the UI project files into a UI bundle.

=== UI bundle structure (releases)

The UI bundle--a distributable archive--provides files which are ready to be used by Antora.

When the UI project files are built by Gulp, they are assembled under the [.path]_public_ directory.
Since the [.path]_public_ directory is generated, it's safe to remove.

The contents of the UI bundle resembles the UI project's default branch contents, except the bundle doesn't contain any files other than the ones that make up the UI.
This is the content that is used by Antora.

[.output]
....
css/
  site.css
font/
  ...
helpers/
  and.js
  eq.js
  ...
img/
  back.svg
  caret.svg
  ...
layouts/
  404.hbs
  default.hbs
partials/
  article.hbs
  breadcrumbs.hbs
  ...
js/
  site.js
  vendor/
    highlight.js
....

Some of these files have been compiled or aggregated, such as the stylesheets and JavaScript.
The benefit of building the UI files is that the files can be optimized for static inclusion in the site without that optimization getting in the way of UI development.
For example, the UI build can optimize SVGs or add vendor prefixes to the CSS.
Since these optimizations are only applied to the pre-compiled files, they don't interfere with the web developer's workflow.

== UI compilation and generator consumption overview

The purpose of an Antora UI project is to assemble the UI files into a reusable distribution that Antora can use to compose the HTML pages and the assets they require.

The only required file in the UI bundle is the default Handlebars layout for pages (i.e., [.path]_layouts/default.hbs_).
If the 404 page is enabled, the Handlebars layout for the 404 page is also required (i.e., [.path]_layouts/404.hbs_).

The layout files must be located in the [.path]_layouts_ folder in the UI bundle.
The name of the layout is the stem of the file, which is the file's basename with a file extension (e.g., [.path]_layouts/default.hbs_ becomes `default`).

[.output]
....
layouts/
  404.hbs
  default.hbs
....

There are no other required files in a UI bundle.
Any additional files are only required because they are referenced by a layout, either when generating the HTML (partial or helper) or assets referenced by the HTML (CSS or JavaScript) that are served to the browser.
Antora does not copy layouts, partials, or helpers to the generated site.

If the layout looks for a partial, that partial must be located in the [.path]_partials_ directory.
The name of the partial is the stem of the file (e.g,. [.path]_partials/body.hbs_] becomes `body` and used as `> body`).
If the partial is inside a folder, the name of that folder is not used in the partial's name.
Additionally, any JavaScript files found in the [.path]_helpers_ directory are automatically registered as template helpers.
The name of the helper function matches the stem of the file (e.g., [.path]_helpers/concat.js_ becomes `concat`).

Here's how a UI would be structured if it had layouts, partials, and helpers:

[.output]
....
helpers/
  concat.js
layouts/
  404.hbs
  default.hbs
partials/
  body.hbs
....

The UI is served statically in a production site, but the UI's assets live in a source form in a UI project to accommodate development and simplify maintenance.
When handed off to the Antora pipeline, the UI is in an interim, pre-compiled state.
Specifically, the default branch of the git repository contains the files in source form while releases are used to distribute the files in pre-compiled form.

The responsibility of compiling the UI is shared between a UI project and Antora.
The UI project uses a local build to pre-compile (i.e., interpret, consolidate, and/or minimize) the files.
The pre-compiled files are agnostic to Antora's content model, relieving the generator from having to deal with this part.
It also allows the UI to be reused.

The UI project build then packages the UI into a bundle, which the UI Loader in Antora consumes.
Antora grabs the bundle, extracts it into a UI catalog, and takes compilation to completion by weaving the Antora's content model into the Handlebars templates to make the pages and auxiliary data files.
Antora then copies the remaining UI assets to the site output.

Now that you have an overview of the files that make up the UI and how it gets assembled, let's go over how to set up the project, build the UI, and preview it.
