How to reference to an image by name specified in setting?

in a theme component, which shows an image (hat) on screen

to use an image in scss, it works with its asset name directly like this,
these images are defined in about.json

{
  "name": "christmas-decorations",
  "about_url": "",
  "license_url": "",
  "author": "",
  "assets": {
    "red-hat1": "assets/decorations/red-hat1.png",
    "red-hat2": "assets/decorations/red-hat2.png",
    "squirrel2": "assets/decorations/squirrel2.png",
  }
}

to use these images in scss, it works well if use the asset name directly as this

background: transparent url($red-hat1) top left no-repeat;

I want to add a setting to pick an image.
in settings.yml, I have this, to select a hat image to show on screen

hat_type:
  default: red-hat1
  type: enum
  choices:
    - red-hat1
    - red-hat2
    - squirrel2

I could do if else in the scss to use the image, but this if else block could be too long …

    @if $hat_type == "red-hat1" {
      background: url($red-hat1) no-repeat center;  
    } @else if $hat_type == "red-hat2" {
      background: url($red-hat2) no-repeat center;  
    } @else if $hat_type == "squirrel2" {
      background: url($squirrel2) no-repeat center;  
    } 

I tried to use a function in scss

 background: url(get_image($hat_type)) no-repeat center;  

@function get_image($name){
  @return "assets/decorations/" + $name + ".png"
}

but this get a url as
https://www.domain.com/stylesheets/assets/decorations/squirrel2.png
this doe not work, it should be resolved as this instead…
https://www.domain.com/uploads/db9860/original/3X/9/1/91d36fdb030047c6390f9ca85604fdbfd2e3fc12.png

could someone give a hint, thanks a lot :slight_smile:

I believe you can use the setting directly using interpolation.

background: transparent URL("$#{$hat_type}") top left no-repeat;

thanks Arkshine.

with this syntax, I picked sequirrel2 for the hat_type in settings.

background: transparent url("$#{$hat_type}") top left no-repeat;

in the web page, checked the styles, it is converted into this…
image

guess
inside the function url(), it needs to be a variable $squirrel2,
while “$#{$hat_type}”, this gives a string $squirrel2… ?


and I tried this

background: transparent url("assets/decorations/#{$decoration_image}.png") top left no-repeat;

it is rendered as this, still not right
image

Try adding a / to the beginning of that assets path.

thanks @Firepup650
tried to add a / before assets, it does not fly either, it adds a / in the middle,
but it does not convert it into the real url, should be something like
https://www.domain.com/uploads/db9860/original/3X/9/1/91d36fdb030047c6390f9ca85604fdbfd2e3fc12.png

You’re right; I thought it worked on my side, but I guess not. :thinking:

Here an alternative: setting a custom CSS property via js.

document.documentElement.style.setProperty(
  "--hat-url",
  `url(${settings.theme_uploads[settings.hat_type]}`
);
body {
  background: var(--hat-url);
}

settings.theme_uploads will contain a list of your uploads.
For example:

Then, based on your setting, you set the custom property.

Note that, from my testing, it doesn’t work doing url(var(--hat-url)), that’s why I passed the url() directly in the custom property.