13

I'm looking to add some basic theme support to my web application, with users being able to customise various parts of the look. These include things like colours, text sizes, fonts, other basic things. I will be storing these in the database and loading them each time a page is accessed.

My question is, how do I go about generating a dynamic CSS file based upon these database values?

I would prefer to do something that is cache-able, but extensible so that if I want to add more editable styles then it wouldn't be a bit issue.

1 Answer 1

24

I think the simplest way would be to add something like the following action method to a controller:

public class CssController : Controller {
    public ActionResult GetCss() {
        StringBuilder sb = new StringBuilder();
        Dictionary<string, string> cssValues = new Dictionary<string, string>();
        // populate dictionary with values from your database
        sb.AppendLine(".myDivClass {");
        foreach (var entry in cssValues) {
            sb.AppendLine(entry.Key + ": " + entry.Value);
        }
        sb.AppendLine("}");
        return Content(sb.ToString(), "text/css");
    }
}

Now in your page you can reference it like so:

<link href="<%: Url.RouteUrl(new { controller=  "CssController", action = "GetCss" }) %>" rel="stylesheet" type="text/css" />

OP EDIT: I made some small changes to the method, but the general premise remains. This is the version I used:

public class CssController : Controller
{
    public ContentResult GetTheme()
    {
        var builder = new StringBuilder();
        IDictionary<string, IDictionary<string, string>> css = new Dictionary<string, IDictionary<string, string>>();

        /* Populate css object from the database */

        foreach (var selector in css)
        {
            builder.Append(selector.Key);
            builder.Append(" { ");
            foreach (var entry in selector.Value)
            {
                builder.Append(string.Format("{0}: {1}; ", entry.Key, entry.Value));
            }
            builder.AppendLine("}");
        }

        return Content(builder.ToString(), "text/css");
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I took your idea and just made it a bit more generic. Also you were missing the ; from the end of the entry. Thanks a bunch for your answer, it was really really helpful.
sorry i like to know what css file name should show in href for this link <link href="<%: Url.RouteUrl(new { controller= "CssController", action = "GetCss" }) %>" rel="stylesheet" type="text/css" />
@AlastairPitts If using the ContentResult version, what needs to be added to the view to use the generated content? Particularly for a view that uses a layout?
Well this will read the CSS from DB but how will we save it to DB first? Any example on that?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.