Feature proposal: Import user-defined SCSS files

Importing ‘variables.scss’ has already been possible in Discourse for a long time.

However, there is no way in one theme stylesheet to import user-defined variables, functions and mixins from another SCSS file no matter it belongs to a different theme component or is just a device specific stylesheet.

Updates

It seems that importing desktop.scss or mobile.scss in the same theme has already been supported.

I created a PR just now to support importing from other theme components.

7 Likes

I like this feature, but I think it is a bit too limiting as currently implemented for theme authors cause id is not stable across installs.

Ideally we want themes to have a “unique” id that a theme author can set. That way a theme author can ship a suite of themes with inter dependencies. Eg:

  • Main Theme 1
  • Main Theme 2
  • Common CSS for both Theme 1 and 2

@Johani can you describe the problem you hit here and your current workarounds?

7 Likes

Using variables across different sections of the same theme:

If you define

$color: red;

In the common section of a theme and you try to use that variable in the common section like so:

body {
    background: $color;
}

Everything works as expected.


if you define

$color: red;

in the common section and then use it in the other sections of the theme like desktop and mobile, it works as well but you get an error in the editor:

Error: Undefined variable: "$color".
        on line 3 of theme_field.scss
>>     background: $color;
   ----------------^

However, this error is ignored by the compiler and the styles are applied anyway. If other “legit” errors are present, they will replace the false error.

So, the workaround for this is to simply ignore the error, but that will only happen if you know why it’s there.

Everything above also applies to imported sheets that you import in the common section. For example you can import core variables in the common section like so:

@import "common/foundation/variables";

And use variables like this in the mobile section

body {
    background: $primary-low;
}

then you get the same result. The styles are applied but the error is still there.

Error: Undefined variable: "$primary-low".
        on line 3 of theme_field.scss
>>     background: $primary-low;
   ----------------^

Variables defined in either the mobile or desktop sections are only available to their respective sections. This is sort of expected. So, no problems here.


Using variables across different themes

This has a lot to do with load order. If you define:

$color: red

in theme A and try to use it in theme B, it won’t work…

…unless theme B is a theme component of theme A. Then the variables will work, but you also get the same false error from earlier.

If you load theme A after theme B, it won’t work and you get a legit undefined error.


the desktop section in theme B will have access to variables declared in both the desktop and common sections of theme A

The mobile section in theme B will have access to variables declared in the mobile and common sections of theme A

The common section in theme B will have access to variables declared in the common section of theme A. It will also have access to variables in the current desktop / mobile view.

What that means is that if you’re on the mobile view in theme A, then the common section of theme B will have access to variables declared there. If you’re on the desktop view in theme A, then the common section in theme B will have access to variables declared in the desktop section of theme A.


The workaround for all of this is to declare your variables early, preferably in the main parent theme and also do it in the common section.

That way you can have as many different theme components under that parent theme and they could all share the variables declared in it.


Possible improvements

Fix the false error:

I think a very important thing to do is to eliminate that false error that says the variables are not defined even though they are.

Import / require themes:

I am a very big fan of the idea of building some sort of theme dependency structure.

As @sam pointed out, theme ids are relative the install you’re on. So while theme id “3” on meta can be the material design theme" on a different install, theme id “3” might be an empty new theme.

One (long term) possibility for remote themes:

Since remote themes are hosted on Github and Github doesn’t allow duplicate repository names on the same account, it might possible to piggyback on that and use the unique portion (/account_name/repo_name) of the theme’s url to generate a secondary unique universal id for it

image

This universal id can be used by theme authors to declare dependencies

We already use base62 for file names. So, (/account_name/repo_name) would become:

44ChYLUBte08Byd35IiJiH2Kwgg7viS5

And this is guaranteed to be a unique id for the theme.

This obviously won’t work for non-remote themes and I have no idea of the amount of work needed to make this work (probably A LOT) but I mentioned it because it’s related.

8 Likes

Should it look up for parent themes to catch variables, or any undefined variable should be seen as a false error to be ignored?

Adding to this — anything that causes a SCSS error in /customize breaks Theme CLI uploading (e.g. using core variables like $primary). So it would be nice if we could get these updates in.

7 Likes