Integrate Paragon Theme Support in Tutor

Context

After the effort to release version 23 of Paragon, which incorporates the use of design tokens via style-dictionary, and based on the information regarding the migration of MFEs to Paragon design tokens and CSS variables (detailed in the link Migrating MFEs to Paragon design tokens and CSS variables), the need arose to make this process more “user-friendly” for those working with the Tutor tool (overhangio/tutor). The goal is to streamline the workflow and ensure a smoother transition to the new design token structure.


Summary

The proposed solution involves designing a plugin, tentatively named tutor-paragon-plugin, which will integrate a simplified version of the existing build-tokens command from the openedx/paragon (Releases · openedx/paragon). The plugin will primarily use the following options: source (to specify the source directory for design tokens) and themes (to select which themes to include in the token build). The build directory will always be fixed to a specific path, where Tutor will serve the generated files, typically in the directory tutor/data/paragon/themes/<theme_name>/*.css.

The second part of the proposal involves modifying the behavior of Tutor from the plugin. The first change is the addition of a flag to define whether the files should be served by Tutor. If enabled, Tutor will update its Caddy configuration to serve the generated files and include the theme folder in the corresponding images. Furthermore, if a theme named “default” exists, the paths to that theme will default to the values specified in the PARAGON_THEME_URLS settings.


Approach

Generating Style Files

A Tutor plugin named tutor-paragon-plugin would be developed, providing a build-tokens command that internally executes Paragon’s npx build-tokens.

The command, paragon build-tokens --source ./<<folder_with_tokens>> --build-dir ./<<TUTOR_ROOT>>/data/paragon --themes theme1 theme2 light, would be used with the following parameters:

  • –source: The directory where the design tokens are located for the build process.
  • –themes: A list of themes to be included in the build.
  • –build-dir: This will always point to <<TUTOR_ROOT>>/data/paragon/ for consistency in file storage.
  • –source-tokens-only: Include only source design tokens in the build.

The users will be able to pass the values either through the command line or by defining them in the Tutor configuration file.

PARAGON_THEMES_PATH = “<>” and PARAGON_THEMES = [<>].

Implementing the build-tokens command

To integrate the build-tokens command into the Tutor plugin, which will execute the Paragon command (a Node.js package), two approaches are presented: subprocess and Docker

  • Docker

Advantages: Isolation and consistency of the environment.

  • Subprocess: The Paragon command is executed directly from Python using the subprocess module.

Advantages: Simple and no additional infrastructure needed.

Disadvantages: Depends on Node.js and Paragon being properly installed in the environment.

Hosting the Files

A flag will be added in Tutor to define whether the files should be served locally. If enabled, Tutor will:

  • Include the theme folder inside the Tutor LMS image.
  • Add configurations in caddy to expose the static files (https://lms.site/static/paragon/…).
  • paths to those themes will be the default values in PARAGON_THEME_URLS

Aquí tienes un posible “Call to Action” para agregar a tu discusión en la comunidad Open edX:


Call to Action

We would love to hear from the Open edX community to ensure that this plugin is built in the most effective and user-friendly way possible. Your feedback is crucial in shaping the approach and refining the implementation details.

To structure the discussion, we propose the following review cycles:

  • First Feedback Cycle: Open until February 27, 2025. During this period, we will gather insights and suggestions from the community.
  • Revision Phase: Based on the feedback received, we will make the necessary adjustments and refinements.
  • Second Feedback Cycle: From March 7 to March 20, 2025, we will open another review phase to validate the changes and ensure the plugin meets the community’s needs.

Please share your thoughts, concerns, and suggestions in this discussion. We are especially interested in your opinions on:

  • The approach to integrating the build-tokens command in Tutor.
  • The best way to handle file hosting and serving.
  • Any additional features or modifications that would improve usability.

Your feedback will help us develop a solution that benefits the entire community. Looking forward to your input! :rocket:

2 Likes

Why should we have a new plugin for this? Paragon design tokens are used in all the MFEs, this to me makes it fall in the tutor-mfe plugin space.

I don’t see this being user friendly at all. It is even worse than using paragon directly as it would require a whole new tutor plugin to be installed.


I also think more context would make it more understandable for folks who have never heard of paragon23 or style tokens.
In essence, paragon 23 takes all the sass variables that used to define thinks like color, border, radius, … and migrates them to a new tech called CSS vars.
With CSS vars it is possible to define a very small file 1k lines of code that contains the majority of the branding. This file can be hot swapped by the MFEs or the old school UI via any means of configuration (including the mfe-config api). As this is a small file, it is very fast to build.
People looking to apply the first layer of theming: their brand colors, typography and all (which is almost everybody planning to actually use openedx in a real internet facing site with real learners) will be able to use this.


IMHO this is a feature for tutor-mfe and the command should be as simple as tutor mfe build-styles or something like this. It should take all the configs from the available configs and build the file as well as placing it in a location that can be hosted with the same caddy/nginx server that is used for the built mfe files. If you want to make it even better, the command should return the location where the file is accesible in the web and instructions on how to configure it in the mfe-config api.

1 Like

Based on @Felipe message, I understand that we are transitioning from SASS to CSS. My understanding of design tokens is that they are essentially JavaScript variables that store values for colors, padding, background colors, etc and these will applied to our style files.

  1. I am unclear on the need for hosting the generated files. Which users need to host these files? There are two ways to apply styles in my context. Those who have installed styles locally and the second those who have hosted CSS files somewhere on CDN.
  2. Could you please clarify whether the plugin is specifically for LMS legacy pages or MFE (Micro-Frontend) styling purposes?
  3. I understand the concept of creating a Tutor plugin and running the build command; however, I am unclear about the purpose of running this command by user. I am expecting that the command will run if user has custom theme not the edx-default theme. Could you explain it more in this context?
  4. Could you please provide a step-by-step flow of how themes are typically built and applied with the updated paragon without tutor? For example:
  • What is the standard workflow for building a theme?
  • Does it involve writing SASS files, updating design tokens, running a build command to generate CSS files, hosting those files, and linking them to HTML pages or a React app?
  • Is this the workflow that ultimately applies the theme?
  1. The current communication seems to mix different use cases. Could you provide separate clarifications for the following scenarios:
  • If I am a user wanting to use a different theme, what steps should I follow?
  • Are the steps mentioned in the message related to building the default edX Paragon theme, or are they meant for users who wish to apply/customize their own themes?

Answers to these questions will help me determine whether creating a separate plugin (e.g., tutor-paragon-plugin) is necessary, or if we can accommodate this functionality within the existing tutor-mfe plugin.

1 Like

Motivations

I’d like to add some context here that will hopefully help clarify some of the motivations behind this.

One complaint that has been raised with the current (pre-design tokens) MFE architecture is long build times. This is notably painful because of the need to rebuild every MFE when making theme changes.

This is mentioned in Scaling Paragon’s styles architecture with design tokens.

CSS Variables

Moving from SCSS variables to CSS variables makes runtime theming possible, but the values for the CSS variables still need to be loaded in from somewhere.

If the somewhere that CSS variable values are loaded from is the MFE bundle, then theme changes will still require rebuilding MFEs. However, if the CSS variable values are loaded from outside the MFE bundle, site operators will be able to change them “on the fly.”

Design Tokens

While it will absolutely be possible for site operators to define custom themes by manually creating .css files setting values for the CSS variables, that is not the recommended workflow.

Instead, we recommend site operators use design tokens, which the new Paragon CLI can transform into .css (using Style Dictionary).

2 Likes

Just wanted to drop a link to another related resource about design tokens’ motivations, etc.: paragon/docs/decisions/0019-scaling-styles-with-design-tokens.rst at release-23.x · openedx/paragon · GitHub

Also, adding to the discussion regarding using Paragon’s styles via local imports or external CDN hosting…

Support for locally importing Paragon styles

As described by @brian.smith, while I believe the hope is to have the externally hosted Paragon styles be the default, the above suggestion to an option for hosted vs. local styles in Tutor seems reasonable. Were you thinking configurable on a per-MFE basis, or across all MFEs within Tutor?

Integrating design tokens & CSS variables with frontend-base

With the forthcoming architectural changes with frontend-base’s notion of projects (application shells), etc., I figure there would likely be less need for external hosting to mitigate the challenges described by @brian.smith in the future, as the application shell would likely be responsible for locally importing Paragon’s styles, whereby the styles are inherited by the orchestrated child MFEs within the shell.

I believe this is largely the intent with Paragon v22 in the current frontend-base implementation, where Paragon’s SCSS entrypoint is imported in the shell’s styles (source).

tl;dr; I’d recommend keeping in mind the forthcoming changes to the MFE architecture via frontend-base when considering Paragon theme support in Tutor as well, should it have any broader implications :slight_smile:

I’ll do my best to answer these questions. If anyone on this thread notices something incorrect in my responses please correct me!


  1. I am unclear on the need for hosting the generated files. Which users need to host these files? There are two ways to apply styles in my context. Those who have installed styles locally and the second those who have hosted CSS files somewhere on CDN.

We would like to move away from relying on Paragon styles being baked into MFE bundles, and instead have MFEs load these styles from a URL. Ideally site operators would be able to choose to use an external CDN to host these files, or (by default) have them hosted within Tutor.

  1. Could you please clarify whether the plugin is specifically for LMS legacy pages or MFE (Micro-Frontend) styling purposes?

This would be for MFEs.

  1. I understand the concept of creating a Tutor plugin and running the build command; however, I am unclear about the purpose of running this command by user. I am expecting that the command will run if user has custom theme not the edx-default theme. Could you explain it more in this context?

My understanding is that the command would do a combination of things. If we assume a site operator has developed a theme using design tokens, the command would:

  • Use the Paragon CLI to transform the design tokens into CSS
  • Place the CSS files in an appropriate location to be hosted by Tutor
  1. Could you please provide a step-by-step flow of how themes are typically built and applied with the updated paragon without tutor?

This is a bit of an oversimplification, but

  1. Create a theme defined using design tokens
  2. Use the Paragon CLI to transform the theme into CSS
  3. Host the CSS somewhere
  4. Point the MFEs to the URL where the CSS is hosted
  1. The current communication seems to mix different use cases. Could you provide separate clarifications for the following scenarios:
  • If I am a user wanting to use a different theme, what steps should I follow?
  • Are the steps mentioned in the message related to building the default edX Paragon theme, or are they meant for users who wish to apply/customize their own themes?

While the goal is to have both the Paragon base styles and any custom themes hosted separately from the MFE bundles, the steps should only apply to site operators that wish to use non-default themes.

Ideally, the Paragon base styles would automatically be built and hosted in a way that MFEs can consume them without any input from the site operator.

Custom themes would require the steps outlined in my responses to 3 and 4.


Hopefully this helps clarify the goals here a bit. I’m more than happy to try to answer any other questions you may have!

3 Likes

The plan is to use the existing PARAGON_THEME_URLS setting to define the themes to be used. Since this setting applies globally, it would affect all MFEs within Tutor rather than being configurable on a per-MFE basis.

That’s a great point, and we’ll definitely keep the upcoming changes to frontend-base in mind. However, this proposal is primarily intended for users who want to use custom themes, as they will be generating their own CSS files, which need to be imported accordingly. By hosting these styles externally, it also becomes possible to set different themes for different tenants using technologies like eox-tenant, providing more flexibility in multi-tenant environments

1 Like

Is there a sense of what the plan for moving forward with this is?

If there are unanswered questions holding this back I’d be happy to try to answer them!

A plugin is needed because, although Paragon is present in every MFE, each MFE remains independent. What we aim to achieve with this plugin is to centralize and compile the design token variables to generate the theme files consistently across all MFEs. This ensures a unified application of the design without the need to replicate configurations in each individual MFE.

I understand your point, but running a command to build the tokens will always be necessary. However, we can reduce the number of parameters since we already know the expected location of the tokens and where the generated files should be exported for Tutor to host them. This allows us to have a simple command like tutor paragon build-tokens. The difference is that if you want to do this manually with Paragon, you would need to install npm, install Paragon, create the necessary folder to reference in your command, run the command, copy the generated files to the Tutor folder, and so on. The plugin streamlines this process and makes it more efficient.