How do I let the user overwrite theme colors dynamically?

Desired result:
User can select primary and secondary colour (perhaps more later) that will overwrite the default theme colours. This will be applied to their own subdomain (saas structure)

Example with where I’m stuck:

  1. Primary default colour is pink image

  2. User in their admin panel sets it to blue for their subdomain (school.site.com , this is saved in the database

  3. I set up logic that on every page load it checks if the current subdomain exists, if yes then it’ll load the blue color code

  4. At this point I have an ejs code: <%=get_school_customisation[0].school_primary_color%> (using server side data with node)

5. How can I overwrite the theme manager colours? From what I understand the bootstrap css is compiled by the theme manager on deploy.

1 Like

You can’t use dynamic data there in the theme manager as the theme css is not generated on page load. The theme css file is generated from within Wappler UI when the generate button is clicked.

You can add some dynamic class to your page body, and style the elements on the page using this class.

Example:

<body dmx-bind:class="your_dynamic_value">

then in the CSS style the elements for this class accordingly.

1 Like

Thanks @Teodor!

That way I still have to predefine those classes in CSS, which means I can let the user choose from “green, blue, etc.” but not let them input their own color code.

Any way I can give them more customisation?

My idea was:

But that still gets overwritten by bootstrap

Alternatively @Teodor can we hook into the compiling? If we can have different bootstrap files for each subdomain that would also work. In general users will change this ONCE and leave it for a long time

I tried to reverse engineer the theme manager this week, but I can’t find out how the theme.json is being parsed and compiled :frowning:

I plan to do it all in css with css variables and some simple JavaScript…

@Antony can you share a bit more about your plan?

You’ll use bootstrap still? What is the high level logic?

Thanks!!

@karh have you tried adding an ejs partial that adds an internal style in the head that overrides the css classes? You could store the user css in DB and read it when loading the partial on server-side.

If you don’t want to read from DB you could create a custom css file for each user with the custom classes and load it also from a partial. You may need to create a custom module to write to file.

You can set specific styles dynamically like this:

dmx-style:background-color="bgColorInDatabase"

Hmm interesting, so you’re saying:

  1. Create partial that functions as a dynamic css file loading variables from the database
  2. Including partial on page

How would the partial look like? It would have to be like this?:

<body style="[overwriting styles here]"></body>

But this wouldn’t overwrite, would it?

@sitestreet The issue with this is having to overwrite many elements with different variables, I’m not sure if this approach is maintainable. Do you use this approach?

I do use this approach but not for site-wide styling like it looks like you're after. I built a paint website and show the colours in a swatch and use that to change the background colour on each repeat. But if you were looking to globally change something then it's probably not the best solution.

1 Like

Sorry I meant internal CSS(not inline).

You would add the partial in the head tag.

<head>
   <%- await include('../partials/userstyle'); %>
</head>

And for your partial userstyle.ejs you need to handle on server-side the content of the style tag by bringing it from DB or file.

<style>
   :root {
     --primary-color: blue !important;
   }
</style>
1 Like

Thanks great idea. I think I can figure something out with that and css variables!

1 Like