## Moodle Component Library

The Moodle UI component Library is built with the aim to provide a single repository
of Moodle UI components to be used for new and existing Moodle pages.

A Moodle UI component is a self-contained UI element originating from one source file
that can be used in different locations in core code, for example a button.

This plugin generates the documentation of the Moodle User Interface components. It
is build using the [Bootstrap](http://getbootstrap.com) docs and the [Hugo](https:://gohugo.io)
static site builder.

## Build the Component Library pages

After installing Node.js you can build the Component Library pages by running:

Grunt componentlibrary

When completed the Component Library will be available from Site Administration > Development > UI Component Library

Please note it is not possible to compile the component library html pages if the configuration option $CFG->admin is configured to have another value than 'admin'.

## How the Component Library was built

The Moodle grunt tasks were setup to include the node modules required for building a static site using
the hugo static site builder, the hugo-lunr-indexer for searching the component library and to prepare all the tasks
for building component library pages from Markdown files and the library styling using scss files. this way
all the build tasks for the library are included in Moodle's core grunt tasks

A new component library plugin was created inspired by the bootstrap docs system. The plugin serves HTML pages from
the docs folder in admin/tool/componentlibrary. The content of the docs folder is generated by running `grunt componentlibrary`.

### JS Files
When serving the HTML pages some additional JavaScript is loaded:
* clipboardwrapper.js and clipboard.js: This allows you to click a button to copy the contents of a code example to your clipboard so you can easily paste it in your code editor when you want to use the code example in your project

* search.js and lunr.js: When the component library docs folder is generated, the contents of the docs folder is indexed by the hugo-lunr-indexer npm module. This generates a json file in `/admin/tool/componentlibrary/hugo/site/data/my-index.json` containing page references to search words. The lunr.js amd module parses this search index and the search.js amd module interfaces the search input field with the lunr.js to show a dropdown with search results on user input

* mustache.js and jsrunner.js: The component library allows you to specify a core mustache template that should be loaded and displayed within the component library docs pages. The mustache.js module fetches the mustache template using a webservice call injecting it with custom variables for the templates if provided. the jsrunner.js fetches the JavaScript section of example code encapsulated in these tags {{#js}} custom js code {{/js}} and executes it. This way the component library can also fetch core js modules and render the result

### Example form
The component library includes an example moodle form in `/admin/tool/componentlibrary/classes/exampleform.php` that renders most form fields inside a component library page. Since the rendering of form fields require php the form fields cannot be included as mustache templates only. The example form does not contain all possible fields but enough to serve as a testing page when any of the form CSS changes

### A moodle icons page
The command line script `/admin/tool/componentlibrary/cli/fetchicons.php` was added to create a json file showing the list of available icons that can be called using the mustache {{#pix}} helper. The page showing the icons will show the FontAwesome icons and the old pix item that can still be used in custom themes.

### The hugo configuration
Hugo's configuration is stored in `/admin/tool/componentlibrary/config.yml`. It tells Hugo where to find the templates to create pages, how to handle syntax highlighting and more. For more information about the configuration options please visit the [Hugo](https:://gohugo.io) website

### The hugo templates
Hugo translates Markdown files into HTML files and wraps them in preconfigured templates. The templates define how the navigation for Hugo is rendered and can include Hugo specific syntax using partials and shortcodes. These translate syntax like {{< example >}} into a documentation block for code. See for `/admin/tool/componentlibrary/hugo/site/layouts/partials`

### The Bootstrap section of the component library
The component library include a selection of the documentation pages of the bootstrap project. The pages removed were the pages related to documentation of the Bootstrap project itself and all of the example pages where components are displayed. Any links to theme pages are changed to links to the original project using the docsref shortcode in `/admin/tool/componentlibrary/hugo/site/layouts/shortcodes/docsref.html`.

Removed docs pages were in these files and folders

* admin/tool/componentlibrary/content/bootstrap/getting-started/*
* admin/tool/componentlibrary/content/bootstrap/about/*
* admin/tool/componentlibrary/content/bootstrap/migration.md
* admin/tool/componentlibrary/content/bootstrap/extend/icons.md
* admin/tool/componentlibrary/content/bootstrap/browser-bugs.md

### Updating the bootstrap docs pages

For newer versions of Bootstrap download the most recent version of bootstrap from https://github.com/twbs/bootstrap

copy the contents of bootstrap/site/content/docs/{newversion} to
admin/tool/componentlibrary/content/bootstrap/

Remove any pages about the bootstrap project itself (see paragraph above).

Add a _index.md file in each subfolder of admin/tool/componentlibrary/content/bootstrap/, the contents of the _index.md file should look something like this:
---
title: "Components"
date: 2021-05-05T15:15:15Z
draft: true
weight: 20
---
Adding _index.md files ensures they show up as collapsable sections in the Component Library navigation

Copy changed files from bootstrap/site/data/ to admin/tool/componentlibrary/hugo/site/data/

Copy new files from bootstrap/site/layouts/shortcodes/ to admin/tool/componentlibrary/hugo/site/layouts/partials/. Leave changed files as is.

Try compiling the new component library pages using `grunt componentlibrary`. If anything is still missing from bootstrap you should see a message for more information.
