문제

I've got a Django project spinning up where it would be great to have the UI in lots of color schemes based on the users' school colors. I have this fantasy of having a base variables.less file along with a bunch of other .less files that compile into style.css.

But once a user sets their school colors it generates a blue.variables.less file (if they've selected the blue preset) or school123.variables.less file (if they got all fancy and used the color picker to make their own color scheme) and then compiles everything to blue.style.css or school123.style.css and then that's the .css file we load when we serve the page.

I can imagine lots of ways for this to fall down. Like how do I reprocess all those files when I push an update to forms.less or layout.less.

Is there a better way to do this? I Googled my fingers raw but haven't found anyone attempting this madness.

도움이 되었습니까?

해결책

There are quite a few ways to accomplish your goal of being able to have user specific color schemes, but they each have their advantages / disadvantages.

I'm assuming you are using some framework like Bootstrap with the files that you name.

Option 1: Inline CSS for color-specific styles (Preferred)

This is my preferred option due to performance and simplicity. You can store each of the customized colors for each user, or even creating a model so you can reuse colors that represent a specific school. It's stored in the database and can scale to an very large number of color schemes without generating a lot of very similar files.

Create a snippet in your template code that has any style that uses the color variable.

base.html

{% include "color-snippet.css" with main-color="{{ user's main color }}" alt-color="{{ user's alt color }}" %}

color-snippet.css (note this file will be in your templates directory as it's being handled by your template engine

<style>
.some-style {
    color: {{ main-color }} !important;
}
</style>

So the big downside to this is you'll need to customize Bootstrap beyond the variables.less. You'll need to grep through the less files to find all the classes that would be generated, and copy the style to your snippet in css and not less. It'll take some investment up front and work when you want to upgrade to a newer Bootstrap, but it'll allow you to separate the color part of the styles to be derived dynamically at runtime.

I prefer this approach since you don't have to deal with compilation of less outside your collectstatic step.

Option 2: Client side compilation of LESS

You can have Django serve a file that is dynamically created and returns the variables you want. Then you can have less.js compile it on the client.

This would involve adding to your base template a url path that is handled by Django that isn't part of your static path (e.g. /style/variables), creating a handler in views and then returning text content that would be your less file variables.

Option 3: Server side compilation of LESS

I use Django Pipeline to do my server side compilation of less to css. It takes some setup to get working with your Django application. In development mode, Django Pipeline will compile on every request the associated less files into CSS files. In production mode, it'll point to the appropriate file path to the compiled file. It hooks into collectstatic so your less gets compiled when you collectstatic.

The biggest problem with this approach is that the mapping for your static files (what less + css files compile to css) is defined in your settings file. This requires a server restart when you update this. You could base your own server side less compilation off how Django Pipeline works but have logic for the mapping instead of defining it in something that requires a server restart.

It's a lot of work and the less compilation of Bootstrap is non-trivial to have to do on every request.

If you created your own mapping that doesn't require you to restart your Django server process, you could always just run collectstatic to create the new css files. This would avoid compilation at every request.

While this last approach is closest to what you mentioned, it seems a lot more work and error prone than just separating the color-specific styles and using django templating to customize it.

The last approach as well works well if your number of schemes is rather low since you can just create all the mappings ahead of time and not let people generate their own at runtime. They can suggest them and you can just update them at some regular cadence.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top