DotLessResult – MVC ActionResult for dotless

23/05/2011 § 2 Comments

I’ve recently had the need to generate dynamic css for a themable MVC web application. I considered using a basic homegrown templating mechanism, or repurposing Razor, but then found the dotless project on the interwebs.

With the NuGet package it was relatively easy to get up & running, and I’ve abstracted the clunky regex code into an ActionResult subclass, recorded here in case it’s useful for somebody else.

    public class DotLessResult : ActionResult
    {
        public IDictionary<string, string> Parameters { get; set;}
        public string Less { get; set; }
        public bool Minify { get; set; }

        public DotLessResult(string less, IDictionary<string, string> parameters = null, bool minify = false)
        {
            Less = less;
            Parameters = parameters ?? new Dictionary<string, string>();
            Minify = minify;
        }
        
        public DotLessResult(Stream stream, IDictionary<string, string> parameters = null, bool minify = false)
            : this(new StreamReader(stream).ReadToEnd(), parameters, minify) { }

        public override void ExecuteResult(ControllerContext context)
        {
            var output = Less;
            foreach (var key in Parameters.Keys)
            {
                output = Regex.Replace(output, @"\s*@" + key + @":\s*\S+;", "@" + key + ":" + Parameters[key] + ";");
            }
            var css = dotless.Core.Less.Parse(output, new DotlessConfiguration { MinifyOutput = Minify });
            context.HttpContext.Response.ContentType = "text/css";
            using (var writer = new StreamWriter(context.HttpContext.Response.OutputStream, Encoding.UTF8)) {
                writer.Write(css);
                writer.Flush();
            }
        }
    }

This can then be used from your action method like so:

        public ActionResult Styles(string id)
        {
            var stream = GetType().Assembly.GetManifestResourceStream(stylePath + id.Replace(".css", ".less"));
            if (stream == null)
            {
                return HttpNotFound();
            }
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            parameters["backgroundcolor"] = "#1f1400"; // continue for all replaceable parameters
            return new DotLessResult(stream, parameters, true);
        }

The .less source should be stored in your web assembly as an embedded resource, with configurable parameters declared using the syntax “@: <placeholderValue;". Then it's just a case of looping through the supplied parameters dictionary and changing the declaration in the .less source. In the example code here I’m looking for a .less resource with the same name as the requested .css file, but you can obviously use your imagination.

About these ads

Tagged: ,

§ 2 Responses to DotLessResult – MVC ActionResult for dotless

  • Scooletz says:

    What about caching, checking etags and handling If-Modified-Since? Have you considered these? Have you considered using IRouteHandler to make it even faster?

    • Sam says:

      Hi Scooletz,

      Yes, our implementation uses a basic Expires header for caching in addition to the MVC output caching. E-Tag/If-Modified-Since are a bit more difficult as the css source is conceptually spread over the .less files and records in the database.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

What’s this?

You are currently reading DotLessResult – MVC ActionResult for dotless at NSCoding.

meta

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: