HUGO

Using a data file for SCSS variables

I am trying to use SCSS variables that are populated from a data file. Example:

data/settings.yml:

transitions:
  fast_transition: 0.2
  slow_transition: 0.8

sass/variables.scss

$fast: {{ .Site.Data.settings.transitions.fast_transition }}s;
$slow: {{ .Site.Data.settings.transitions.slow_transition }}s;
$anim-fast: $fast ease-in-out;
$anim-slow: $slow ease-in-out;

This unfortunately doesn’t work. I’ve tried following this page but I can’t get anything working.

My current setup:
<head>

{{ $sassTemplate := resources.Get "sass/template.scss" }}
{{ $style := $sassTemplate | resources.ExecuteAsTemplate "sass/main.scss" . | resources.ToCSS }}

/sass/main.scss

@import "variables";
@import everything else..

/sass/template.scss

$fast: {{ .Site.Data.settings.transitions.fast_transition }}s;

/sass/variables.scss

$anim-fast: $fast ease-in-out;

This setup just results in an error: Undefined variable: "$fast".
Am I supposed to add @import "template" to my main.css file? If I do that I get this error :` Invalid CSS after "$fast:": expected 1 selector or at-rule, was "{{ .Site.Data.setti"
Where am I going wrong?

If this is really what your data file looks like, you should be using this:

.Site.Data.settings.fast_transition

Instead of this:

.Site.Data.settings.transitions.fast_transition

Sorry that was a typo, I’ve just edited the question

It looks like you cannot use the ExecuteAsTemplate method on a Sass resource that will later be imported by another Sass file.

But you can do this…

data/settings.yml

transitions:
  fast_transition: 0.2
  slow_transition: 0.8

assets/sass/main.scss

// Set variables.
$fast: {{ .Site.Data.settings.transitions.fast_transition }}s;
$slow: {{ .Site.Data.settings.transitions.slow_transition }}s;
$anim-fast: $fast ease-in-out;
$anim-slow: $slow ease-in-out;

// Import.
@import "foo"

assets/sass/_foo.scss

.something {
  transition: width $anim-fast;
}

layouts/_default/baseof.html

{{ $scss := resources.Get "sass/main.scss" }}
{{ $scss = $scss | resources.ExecuteAsTemplate "main.scss" . }}
{{ $css := $scss | toCSS }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">
1 Like

If you want to keep the variables out of main.scss you can concatenate resources.

assets
└── sass/
    ├── _foo.scss
    ├── _variables.scss
    └── main.scss

assets/sass/main.scss

// Import.
@import "foo";   <-- note that we are NOT importing _variables.scss

assets/sass/_foo.scss

.something {
  transition: width $anim-fast;
}

assets/sass/_variables.scss

$fast: {{ .Site.Data.settings.transitions.fast_transition }}s;
$slow: {{ .Site.Data.settings.transitions.slow_transition }}s;
$anim-fast: $fast ease-in-out;
$anim-slow: $slow ease-in-out;

layouts/_default/baseof.html

{{ $scssVars := resources.Get "sass/_variables.scss"}}
{{ $scssVars = $scssVars | resources.ExecuteAsTemplate "variables.scss" . }}
{{ $scssMain := resources.Get "sass/main.scss" }}
{{ $scss := slice $scssVars $scssMain | resources.Concat "sass/main.scss" }}
{{ $css := $scss | toCSS (dict "targetPath" "assets/css/main.css") }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}">
2 Likes

If you are using custom properties in your SCSS and then define the variables in the header layout (no worries about messing up your site speed, it has no influence on the speed as only variables are set and no layout is built) you can keep your SCSS in order (lintable BEFORE build) and the system configurable.

That’s a better and cleaner way to make your design configurable, but it’s a little bit more work to start and set up. If you want a one-site theme then go with the solution by @jmooring above.

Thanks @jmooring! I tried both suggestions and they work perfectly, I ended up implementing the second. Thanks for your help, I appreciate it!

Thanks for the tip I appreciate it! I was trying to avoid adding styles outside of my SASS directory and @jmooring’s is the easy/clean solution I was looking for.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.