Dotless dynamic server-side values

Using the dotless HttpHandler, we can easily start transforming our less files into rendered CSS. But if we want to manipulate variable values before it is processed, we have to do a bit of manual work. Let’s take a look at how this can be done.

In this example, we have a list-element using 2 colors declared as variables within the dotless stylesheet.

@gallery-ul-bg: #ff0000;
@gallery-li-bg: #0000ff;

#gallery {

	ul {
		background-color: @gallery-ul-bg;

		li {
			background-color: @gallery-li-bg;
		}
	}

}
#gallery ul {
  background-color: #ff0000;
}
#gallery ul li {
  background-color: #0000ff;
}

We have the benefits of declaring values in one place and using them many different places. These values are however still static. If the values of these variables are not known until run time then the default dotless HttpHandler will not do us any good.

Dynamic values

Instead of using the default dotless HttpHandler we can instead roll our own by using the dotless API while overriding the static values with dynamic ones. The custom HttpHandler below shows exactly how this can be achieved.

public class DynamicColorsLess : IHttpHandler
{
	private const string dbColor1 = "#C5C5C5";
	private const string dbColor2 = "#00009F";

	public void ProcessRequest(HttpContext context)
	{
		// Load less stylesheet body
		string localPath = context.Request.Url.LocalPath.Replace(".dynamic", "");
		string fileName = context.Server.MapPath(localPath);
		string fileContent = File.ReadAllText(fileName);

		// Append variable to override
		var sb = new StringBuilder(fileContent);
		sb.AppendLine("@gallery-ul-bg: " + dbColor1 + ";");
		sb.AppendLine("@gallery-li-bg: " + dbColor2 + ";");

		// Configure less to allow variable overrides
		var config = DotlessConfiguration.GetDefaultWeb();
		config.DisableVariableRedefines = true;

		// Parse with LESS and write to response stream
		context.Response.ContentType = "text/css";
		context.Response.Write(LessWeb.Parse(sb.ToString(), config));
	}

	public bool IsReusable
	{
		get { return true; }
	}
}
...
<handlers>
	<add name="DynamicColorsLess" verb="*" path="*.less.dynamic" type="MyAssembly.DynamicColorsLess,MyAssembly" />
</handlers>
...

In short the steps we take are the following

  • Read stylesheet body
  • Append variables declaration
  • Configure dotless as to allow variable redefines
  • Parse and write response

We are now able to request styles.less.dynamic which will contain the colors dynamically “inserted” rendering the following result.

#gallery ul {
  background-color: #c5c5c5;
}
#gallery ul li {
  background-color: #00009f;
}

Comments

  1. You have no idea how long I have been trying to figure out how to do this. Can’t believe it was so simple. Thank you!!

Speak Your Mind

*