Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

To create a new theme targeting the new features in Totara 13, you will need to create files in both the server and client directories. The naming convention for your custom theme must follow these rules:

  1. The name should start with one or more lowercase alpha characters (a-z).

  2. If there are any underscores:

    1. All characters before the first underscore need to be lowercase alpha characters (a-z).

    2. The character directly following the first underscore needs to be lowercase alpha (a-z), the following characters can be any combination of underscores and lowercase alphanumeric values.

  3. The name should end with lowercase alphanumeric values (a-z, 0-9).

The files you'll need are:

...

server/theme/mytheme/version.phpphp (copy from the Ventura version.php and update the version and component fields)

If you want to enable the Theme Settings page for your custom theme, you'll also need to copy the following files from Ventura and update them to match your theme's name:

  • index.php

  • lib.php

  • settings.php

That takes care of the files in the server directory, but if we want to apply customisations to the Tui styling or components, we also need to create a folder in the client/component directory with the right files.

...

After completing the instructions above, you can add your theme customisations in the following places:

  • client/component/my_theme/global_styles/_variables.scss (variable overrides)

  • client/component/my_theme/global_styles/static.scss (global CSS rules)

You can also break up your variables or global CSS rules into multiple files and use the @import syntax to include them. @import 'my_theme/xyz' maps to client/component/my_theme/global_styles/xyz. You can see this in action at client/component/tui/src/global_styles/_variables.scss.

Overriding component styles

...

or functionality

Any Vue component can be extended in a theme by creating a file in the right folder.

The pattern for override files isclient/component/theme_(themename)/src/(subfolder)/overrides/(original client/component/* subfolder)/(rest of path)

For example, if the component you want to extend is: tui/components/buttons/Button, you would create create client/src/theme_mytheme/components/overrides/tui/buttons/Button.vue

This component will replace the original one, unless it only contains a <style lang="scss"> block, in which case the original component will continue to be loaded.

Expand
titleT13-T18

In T13-T18, partial component overrides were possible. In T18 these were deprecated.

Modifying SCSS

To customise the styling, add a new <style lang="scss"> block. Styles defined here are in addition to styles defined in the original component, they do not replace them.

Modifying template

To modify the template, add a <template> block to the override file. This will replace the original template, but the original logic will remain and you will get access to any data or methods exposed by the component.

Modifying JavaScript

It's also possible to replace the logic of the component by adding a <script> block to the override file. This will replace the entire component definition however, so you must define your own template and strings blocks. Styles will still apply.

If you want to use a component in your custom template that was not used in the original template, you'll need to override the script block as well to add the component to the 'components' object. Normally this would entirely replace the original script block, but you can use <script extends> to instead define a component that extends the original JS, retaining all its functionality. You should only use this to add components to the definition, if you want to extend the functionality, you should define a regular script block.

Code Block
languagexml
<script extends>
import Popover from 'tui/components/popover/Popover';

export default {
  components: {
    Popover,
  },
};
</script>

Modifying strings

You can request extra strings in the overrides by defining a <lang-strings> block. The content of this block will be merged with the original component.

It's recommended to list any strings you're using in the template here even if they are already specified in the base component, as an update to the original may remove strings that are not in use by the original's template.

Tips

  • When adding a <script> block to an overridden component, this will disable inheritance - both the script and the template will not be inherited from the parent component. In order to keep inheriting, add an extends attribute to the script tag: <script extends>. This is mostly useful for adding new components to the 'components' object. If you do this, as per usual do not call any private methods on the component you are inheriting from - this is not a supported use case.

  • Overriding individual code blocks within a Single File Component does carry a maintenance risk, as the underlying Vue component you are overriding may be deprecated. Read our deprecation guidelines for some more information on this use case.

Variable usage

In general, variables used by components are defined in Tui core or plugins and can then be overridden by themes.

...

Processing variables in this way provides a replacement for the now unsupported SCSS functions (Darken(), Lighten(), mix(), button-variant() etc.), as they do not operate on CSS Variables.

...

CSS is included in the following order:

  1. Legacy CSS.

  2. SCSS variables in the same order as below (typically not present as we prefer CSS variables for their greater flexibility).

  3. CSS variables and CSS from Tui core.

  4. CSS variables and CSS from each Tui component.

  5. CSS variables and CSS from each Tui theme.

  6. Theme customisations via UI - CSS variable overrides.

  7. Theme customisations - user-defined custom CSS.

Tips and known limitations

  • CSS class names - as with custom components, if you are defining an entirely new component it is recommended that you use a prefix other than tui- in the class names to avoid collisions.

  • If you are entirely replacing a component (new template, style, and script), you will probably find it easier to use a new CSS class name to avoid collisions with the old styling.

    When adding a <script> block to an overridden component, this will disable inheritance - both the script and the template will not be inherited from the parent component. In order to keep inheriting, add an extends attribute to the script tag: <script extends>. This is mostly useful for adding new components to the 'components' object. If you do this, as per usual do not call any private methods on the component you are inheriting from - this is not a supported use case
  • Overriding TUI Core or other TUI Plugin code blocks from inside another plugin other than a theme is not currently supported, due to the risk of third-party plugins detrimentally overriding code.

  • When using a custom theme no customisations of the parent theme settings are applied to the custom theme. Child themes inherit only from the default parent theme settings.

Recommended reading

Totara publishes an Example Theme to demonstrate the structure of a custom theme, including both features from the Tui framework, and features from earlier versions of Totara (useful when upgrading your custom theme to use Tui).