Skip to content
Merged
Changes from 2 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
225 changes: 140 additions & 85 deletions plugins/tutor-contrib-paragon/README.rst
Original file line number Diff line number Diff line change
@@ -1,151 +1,206 @@
Paragon plugin for `Tutor <https://docs.tutor.edly.io>`__
###########################################################
.. _tutor_contrib_paragon:

Facilitates the generation and static hosting of Paragon-based CSS themes for Open edX Micro-Frontend (MFE) applications using `Paragon <https://openedx.github.io/paragon/>`__.
#####################
Tutor Paragon Plugin
#####################

This plugin provides a local folder structure to manage **design token-based theme source files** (see `Paragon Design Tokens <https://github.com/openedx/paragon/?tab=readme-ov-file#design-tokens>`__) and compile them into CSS, enabling flexible customization of Open edX MFEs via Tutor.
.. contents:: Table of Contents
:local:

Introduction
============

What is the Tutor Paragon Plugin?
---------------------------------

The **Tutor Paragon Plugin** (`tutor-contrib-paragon`) enables developers and operators to compile Paragon design tokens into CSS themes using the Paragon CLI and serve those themes to Open edX Micro-Frontends (MFEs) via Tutor.

It wraps the Paragon CLI build process, manages token source directories and output paths, and exposes compiled themes through Tutor's static hosting infrastructure.

What problem does it solve?
---------------------------

This plugin simplifies MFE theme customization by:

* Standardizing how Paragon tokens are compiled.
* Automatically placing output files in a consistent, hostable location.
* Enabling static delivery of CSS files for MFE consumption.
* Supporting tenant-based theme overrides with flexible configuration.

Target Audience
---------------

* Open edX developers customizing MFE themes.
* Operators managing theming at scale.
* Designers experimenting with visual tokens in real-time environments.

Prerequisites
=============

* A working Tutor environment with Docker.
* Familiarity with Paragon design tokens and MFE architecture.
* Basic understanding of Tutor’s plugin system and configuration management.
* Tutor Plugin MFE installed and enabled.


Version Compatibility
=====================

To use this plugin, ensure you're running compatible versions of Open edX and its dependencies:

* **Paragon 23+**
* **Open edX "Teak" release (or Tutor 20+)**
* **Tutor 20+**
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these say "greater than or equal to"? Do we think this plugin will stop working on Tutor 21 or Paragon 24?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My read was that the + implied >=, but I can see how someone might read that as 23.x or 20.x.

The pyproject.toml file currently has a tutor version requirement of tutor>=19.0.0,<21.0.0, and a tutor-mfe requirement of tutor-mfe @ git+https://github.com/overhangio/tutor-mfe.git@release.

The tutor-mfe version requirement should be updated once overhangio/tutor-mfe#267 and overhangio/tutor-mfe#264 make it into releases (as of writing the latest tutor-mfe release is v20.0.0 from June 27th).

I think for the README it makes sense to clearly imply >=, as we should expect to support this plugin beyond Paragon 23 and Tutor 20. That being said, major versions can include breaking changes, so it is quite possible this plugin will need to be updated to support any Tutor 21 or Paragon 23 changes.


.. note::
Design token functionality is available starting from Paragon 23 and Open edX "Teak". Earlier versions may not be compatible.

Installation
************
============

.. code-block:: bash
.. note::
A future version may be available via PyPI. For now, use the development installation method.

pip install git+https://github.com/openedx/openedx-tutor-plugins.git#subdirectory=plugins/tutor-contrib-paragon
Development Install
-------------------

For development:
Clone the repository and install in editable mode:

.. code-block:: bash

git clone https://github.com/openedx/openedx-tutor-plugins.git
cd openedx-tutor-plugins/plugins/tutor-contrib-paragon
pip install -e .

Enable the plugin:
Enable the Plugin
-----------------

Use Tutor to enable the plugin:

.. code-block:: bash

tutor plugins enable paragon

Directory Structure
*******************
Verify Installation
-------------------

The plugin will create the following structure inside your Tutor environment:
Check that the plugin is listed and enabled:

.. code-block::

tutor/env/plugins/paragon/
├── theme-sources/ # Place your Paragon-based theme folders here (e.g., theme-xyz/)
└── compiled-themes/ # Output CSS files are generated here and ready for static hosting
.. code-block:: bash

Only themes listed in `PARAGON_ENABLED_THEMES` will be compiled.
tutor plugins list | grep paragon

Themes placed in `theme-sources/` are compiled into CSS using `Paragon's theme build process <https://github.com/openedx/paragon/?tab=readme-ov-file#paragon-cli>`_. The resulting CSS files in `compiled-themes/` are intended to be served statically and can be linked using the `PARAGON_THEME_URLS` setting.
Build the Paragon Image
-----------------------

This structure is optimized for design token–based themes (see `Paragon Design Tokens <https://github.com/openedx/paragon/?tab=readme-ov-file#design-tokens>`__), but it is also flexible. If site operators need to include small amounts of additional CSS (not handled via tokens), we recommend doing so via extensions in the theme source directory, so they are included during the Paragon build—rather than manually editing the compiled output.
Before compiling tokens, build the Docker image used by the plugin:

.. note::
.. code-block:: bash

A link to the official Open edX or Paragon documentation will be added here once it is published.
tutor images build paragon-builder

Configuration
*************
=============

All configuration variables can be overridden via `tutor config save`:
Core Plugin Settings
--------------------

.. code-block:: yaml
All configuration variables are defined via Tutor:

PARAGON_THEME_SOURCES_PATH: "env/plugins/paragon/theme-sources"
PARAGON_COMPILED_THEMES_PATH: "env/plugins/paragon/compiled-themes"
PARAGON_ENABLED_THEMES:
- theme-1
- theme-2
PARAGON_SERVE_COMPILED_THEMES: true
PARAGON_BUILDER_IMAGE: "paragon-builder:latest"
+----------------------------+--------------------------------------------------------------+-------------------------------+
| Variable | Description | Default Value |
+============================+==============================================================+===============================+
| `PARAGON_THEMES_PATH` | Base path for theme sources and compiled output | `env/plugins/paragon/themes` |
+----------------------------+--------------------------------------------------------------+-------------------------------+
| `PARAGON_THEMES` | List of theme folders to compile and serve | `['light', 'dark']` |
+----------------------------+--------------------------------------------------------------+-------------------------------+
| `MFE_HOST_EXTRA_FILES` | Whether to serve compiled themes via Tutor’s MFE web server | `true` |
+----------------------------+--------------------------------------------------------------+-------------------------------+

You may customize paths or theme names to suit your deployment.
Sample Configuration
--------------------

Usage
*****
.. code-block:: yaml

Prerequisites
-------------
PARAGON_THEMES_PATH: "{{ TUTOR_ROOT }}/env/plugins/paragon/themes"
PARAGON_THEMES:
- light
- dark
MFE_HOST_EXTRA_FILES: true

- A built Paragon CLI image:
Theme Directory Structure
-------------------------

.. code-block:: bash
.. code-block:: text

tutor images build paragon-builder
{{ TUTOR_ROOT }}/env/plugins/paragon/themes/
├── core/ # Shared base design tokens
├── light/ # Light theme tokens
└── dark/ # Dark theme tokens

- The ``PARAGON_THEME_SOURCES_PATH`` directory structured as follows:
Only themes listed in `PARAGON_THEMES` will be compiled and served. The `core/` directory is required and provides base styles shared across all themes.

.. code-block:: text
Usage
=====

<PARAGON_THEME_SOURCES_PATH>/
├── core/
│ └── ... (token files)
└── themes/
├── light/ # example theme variant
│ └── ... (light theme token files)
└── dark/ # example theme variant
└── ... (dark theme token files)
Build All Themes
----------------

In this structure:
To compile all themes listed in `PARAGON_THEMES`:

- The ``core/`` directory contains base design tokens common across all themes.
- The ``themes/`` directory contains subdirectories for each theme variant (e.g., ``light``, ``dark``), each with tokens specific to that theme.
.. code-block:: bash

Building Themes
---------------
tutor local do paragon-build-tokens

Build Specific Themes
---------------------

Invoke the build process via Tutor:
To compile only selected themes:

.. code-block:: bash

tutor local do paragon-build-tokens [OPTIONS]
tutor local do paragon-build-tokens --themes light,dark

For more information about available options, refer to the `Paragon CLI documentation <https://github.com/openedx/paragon/?tab=readme-ov-file#paragon-cli>`__.
Pass Additional CLI Options
---------------------------

Examples
--------
You can pass extra options to the Paragon CLI:

.. code-block:: bash

# Compile all themes listed in PARAGON_ENABLED_THEMES
tutor local do paragon-build-tokens

# Compile only specific themes
tutor local do paragon-build-tokens --themes theme-1,theme-2

# Pass any other Paragon CLI options as needed
tutor local do paragon-build-tokens --paragon-option value
tutor local do paragon-build-tokens --paragon-option value

Output
------

Artifacts will be written to the directory specified by ``PARAGON_COMPILED_THEMES_PATH`` (default: ``env/plugins/paragon/compiled-themes``).
Compiled CSS files (minified `.min.css`) are written to:
{{ TUTOR_ROOT }}/env/plugins/paragon/themes/<theme>/<theme>.min.css

Troubleshooting
***************
Static Hosting
==============

- **No custom themes built or only default tokens generated**
Ensure that your custom theme directories exist under ``PARAGON_THEME_SOURCES_PATH`` and that their names exactly match those in ``PARAGON_ENABLED_THEMES`` or passed via ``--themes``. If no custom tokens are found, Paragon will fall back to its built-in defaults.
If `MFE_HOST_EXTRA_FILES` is set to `true`, the plugin:

- **Themes are not picked up when using --themes:**
The value for ``--themes`` must be a comma-separated list (no spaces), e.g. ``--themes theme-1,theme-2``.
* Leverages the static file hosting capability provided by the `tutor-mfe` plugin to serve the compiled CSS files.
* Makes the themes accessible via standard static URLs for use in LMS and MFEs.

- **Write permission denied**
Verify that Docker and the Tutor process have write access to the path defined by ``PARAGON_COMPILED_THEMES_PATH``. Adjust filesystem permissions if necessary.
Example URLs:

- **Error: "Expected at least 4 args"**
This occurs when the build job is invoked directly inside the container. Always run via Tutor:
* Local LMS: `http://local.openedx.io/static/paragon/themes/light/light.min.css`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Local LMS: `http://local.openedx.io/static/paragon/themes/light/light.min.css`
* Local LMS: `http://<MFE_HOST>/static/paragon/themes/light/light.min.css`

Now that the plugin leverages the tutor-mfe host extra files feature, the local URLs should point to the MFE host (by default: apps.local.openedx.io).

* Dev server: `http://localhost:<PORT>/static/paragon/themes/dark/dark.min.css`

.. code-block:: bash
Each theme listed in `PARAGON_THEMES` is automatically exposed for use in MFEs.

tutor local do paragon-build-tokens [OPTIONS]
Troubleshooting
===============

- **Other issues**
Re-run the build with ``--verbose`` to obtain detailed logs and identify misconfigurations or missing files.
* **Themes not compiled**: Ensure theme folders exist and match names in `PARAGON_THEMES`.
* **Permission errors**: Verify Docker and Tutor have write access to the themes directory.
* **Missing core tokens**: Ensure the `core/` folder exists and contains valid token files.
* **Error: "Expected at least 4 args"**: Always run builds via `tutor local do`, not inside containers.
* **Other issues**: Re-run with `--verbose` for detailed logs.

License
*******
=======

This software is licensed under the terms of the AGPLv3.
This software is licensed under the terms of the **AGPLv3**.