<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Schotime.net &#187; dotLess</title>
	<atom:link href="http://schotime.net/blog/index.php/tag/dotless/feed/" rel="self" type="application/rss+xml" />
	<link>http://schotime.net/blog</link>
	<description>All Things .Net and Me</description>
	<lastBuildDate>Sun, 20 Nov 2011 01:44:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Dynamic Dot Less Css With Asp.net MVC 2</title>
		<link>http://schotime.net/blog/index.php/2010/07/02/dynamic-dot-less-css-with-asp-net-mvc-2/</link>
		<comments>http://schotime.net/blog/index.php/2010/07/02/dynamic-dot-less-css-with-asp-net-mvc-2/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 14:33:27 +0000</pubDate>
		<dc:creator>Schotime</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[dotLess]]></category>

		<guid isPermaLink="false">http://schotime.net/blog/index.php/2010/07/02/dynamic-dot-less-css-with-asp-net-mvc-2/</guid>
		<description><![CDATA[I have been having a look at the best way to theme a asp.net mvc website in the last few weeks. I heard about dot less css late last year but hadn’t had time to integrate it into a project until now. Integrating dot less css is pretty easy by default, as shown on its [...]]]></description>
			<content:encoded><![CDATA[<p>I have been having a look at the best way to theme a asp.net mvc website in the last few weeks. I heard about <a href="http://dotlesscss.com" target="_blank" onclick="pageTracker._trackPageview('/outgoing/dotlesscss.com?referer=');">dot less css</a> late last year but hadn’t had time to integrate it into a project until now. </p>
<p>Integrating dot less css is pretty easy by default, as shown on its home page however I wanted something that could be configured by application users. We want to be able to specify the link html tag like the following.</p>
<table cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400"> 
<pre class="code"><span style="color: blue">&lt;</span><span style="color: #a31515">link </span><span style="color: red">href</span><span style="color: blue">=&quot;/public/css/sites.less&quot; </span><span style="color: red">rel</span><span style="color: blue">=&quot;stylesheet&quot; </span><span style="color: red">type</span><span style="color: blue">=&quot;text/css&quot; /&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p>There are few steps involved in the solution I have come up with so bare with me as I go through them. Firstly we’ll start with the web.config:</p>
<table style="background: black" cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code"><span style="background: black; color: white">        &lt;</span><span style="background: black; color: #cc7832">compilation</span><span style="background: black; color: white">&gt;
            &lt;</span><span style="background: black; color: #cc7832">buildProviders</span><span style="background: black; color: white">&gt;
                &lt;</span><span style="background: black; color: #cc7832">add </span><span style="background: black; color: white">extension=&quot;</span><span style="background: black; color: #a5c25c">.lessx</span><span style="background: black; color: white">&quot; type=&quot;</span><span style="background: black; color: #a5c25c">System.Web.Compilation.PageBuildProvider</span><span style="background: black; color: white">&quot; /&gt;
            &lt;/</span><span style="background: black; color: #cc7832">buildProviders</span><span style="background: black; color: white">&gt;
        &lt;/</span><span style="background: black; color: #cc7832">compilation</span><span style="background: black; color: white">&gt;</span></pre>
</td>
</tr>
</tbody>
</table>
<p>Insert the builderProviders block inside the compilation section. The compilation section will be under the system.web section. This will enable us to use code blocks in our lessx files.</p>
<p>Secondly, is the routing.</p>
<table style="background: black" cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code"><span style="background: black; color: white">        </span><span style="background: black; color: gray">//Special Route for css so that images are relative to it
        </span><span style="background: black; color: white">routes.MapRoute(</span><span style="background: black; color: #a5c25c">&quot;css&quot;</span><span style="background: black; color: white">,
                           </span><span style="background: black; color: #a5c25c">&quot;public/css/{filename}.less&quot;</span><span style="background: black; color: white">,
                           </span><span style="background: black; color: #cc7832">new </span><span style="background: black; color: white">{ controller = </span><span style="background: black; color: #a5c25c">&quot;Css&quot;</span><span style="background: black; color: white">, action = </span><span style="background: black; color: #a5c25c">&quot;Index” </span><span style="background: black; color: white">},
                           </span><span style="background: black; color: #cc7832">new</span><span style="background: black; color: white">[] { </span><span style="background: black; color: #a5c25c">&quot;eLearning.Controllers&quot; </span><span style="background: black; color: white">});</span></pre>
</td>
</tr>
</tbody>
</table>
<p>This specifies that any url matching /public/css/{filename}.less should be routed to the CssController passing the filename as the parameter to the Index method.</p>
<table style="background: black" cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code"><span style="background: black; color: white">    </span><span style="background: black; color: #cc7832">public class </span><span style="background: black; color: #ffc66d">CssController </span><span style="background: black; color: white">: </span><span style="background: black; color: #ffc66d">BaseController
    </span><span style="background: black; color: white">{
        [</span><span style="background: black; color: #ffc66d">OutputCache</span><span style="background: black; color: white">(Duration = </span><span style="background: black; color: #6897bb">10</span><span style="background: black; color: white">, VaryByParam = </span><span style="background: black; color: #a5c25c">&quot;&quot;</span><span style="background: black; color: white">)]
        </span><span style="background: black; color: #cc7832">public </span><span style="background: black; color: #ffc66d">ActionResult </span><span style="background: black; color: white">Index(</span><span style="background: black; color: #cc7832">string </span><span style="background: black; color: white">filename)
        {
            </span><span style="background: black; color: #cc7832">if </span><span style="background: black; color: white">(</span><span style="background: black; color: #cc7832">string</span><span style="background: black; color: white">.IsNullOrEmpty(filename))
                </span><span style="background: black; color: #cc7832">throw new </span><span style="background: black; color: #ffc66d">ArgumentException</span><span style="background: black; color: white">(</span><span style="background: black; color: #a5c25c">&quot;A filename must be supplied&quot;</span><span style="background: black; color: white">);

            ViewData[</span><span style="background: black; color: #a5c25c">&quot;baseColor&quot;</span><span style="background: black; color: white">] = </span><span style="background: black; color: #a5c25c">&quot;#aabbcc&quot;</span><span style="background: black; color: white">;

            </span><span style="background: black; color: #cc7832">var </span><span style="background: black; color: white">less = RenderViewToString(filename + </span><span style="background: black; color: #a5c25c">&quot;.lessx&quot;</span><span style="background: black; color: white">, </span><span style="background: black; color: #cc7832">null</span><span style="background: black; color: white">);
            </span><span style="background: black; color: #cc7832">var </span><span style="background: black; color: white">css = </span><span style="background: black; color: #ffc66d">LessCss</span><span style="background: black; color: white">.Generate(less, </span><span style="background: black; color: #cc7832">true</span><span style="background: black; color: white">);
            </span><span style="background: black; color: #cc7832">return </span><span style="background: black; color: white">Content(css, </span><span style="background: black; color: #a5c25c">&quot;text/css&quot;</span><span style="background: black; color: white">);
        }
    }

    </span><span style="background: black; color: #cc7832">public static class </span><span style="background: black; color: #ffc66d">LessCss
    </span><span style="background: black; color: white">{
        </span><span style="background: black; color: #cc7832">public static string </span><span style="background: black; color: white">Generate(</span><span style="background: black; color: #cc7832">string </span><span style="background: black; color: white">less, </span><span style="background: black; color: #cc7832">bool </span><span style="background: black; color: white">minify)
        {
            </span><span style="background: black; color: #cc7832">var </span><span style="background: black; color: white">lessEngine = </span><span style="background: black; color: #cc7832">new </span><span style="background: black; color: white">EngineFactory();
            lessEngine.Configuration.MinifyOutput = minify;
            </span><span style="background: black; color: #cc7832">var </span><span style="background: black; color: white">output = lessEngine.GetEngine().TransformToCss(less, </span><span style="background: black; color: #cc7832">null</span><span style="background: black; color: white">);
            </span><span style="background: black; color: #cc7832">return </span><span style="background: black; color: white">output;
        }
    }</span></pre>
</td>
</tr>
</tbody>
</table>
<p>This is the css controller class. It receives the filename as the input, finds the corresponding .lessx file and returns the file with appropriate view data replaced. Is then takes the less formatted string and runs it through the dot less parser to return a css string. This is then returned to the browser with the appropriate content-type. One method I have not shown is the RenderViewToString() and how the .lessx file is located. This method is located on the base controller class that the css controller inherits from. I have also turned Caching on so that it will cache the result for 10seconds.</p>
<table style="background: black" cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code"><span style="background: black; color: white">        </span><span style="background: black; color: #cc7832">protected string </span><span style="background: black; color: white">RenderViewToString(</span><span style="background: black; color: #cc7832">string </span><span style="background: black; color: white">viewName, </span><span style="background: black; color: #cc7832">object </span><span style="background: black; color: white">model)
        {
            </span><span style="background: black; color: #cc7832">if </span><span style="background: black; color: white">(</span><span style="background: black; color: #cc7832">string</span><span style="background: black; color: white">.IsNullOrEmpty(viewName))
                viewName = ControllerContext.RouteData.GetRequiredString(</span><span style="background: black; color: #a5c25c">&quot;action&quot;</span><span style="background: black; color: white">);

            ViewData.Model = model;

            </span><span style="background: black; color: #cc7832">using </span><span style="background: black; color: white">(</span><span style="background: black; color: #ffc66d">StringWriter </span><span style="background: black; color: white">sw = </span><span style="background: black; color: #cc7832">new </span><span style="background: black; color: #ffc66d">StringWriter</span><span style="background: black; color: white">())
            {
                </span><span style="background: black; color: #ffc66d">ViewEngineResult </span><span style="background: black; color: white">viewResult = </span><span style="background: black; color: #ffc66d">ViewEngines</span><span style="background: black; color: white">.Engines.FindView(ControllerContext, viewName, </span><span style="background: black; color: #cc7832">null</span><span style="background: black; color: white">);
                </span><span style="background: black; color: #ffc66d">ViewContext </span><span style="background: black; color: white">viewContext = </span><span style="background: black; color: #cc7832">new </span><span style="background: black; color: #ffc66d">ViewContext</span><span style="background: black; color: white">(ControllerContext, viewResult.View, ViewData, TempData, sw);
                viewResult.View.Render(viewContext, sw);

                </span><span style="background: black; color: #cc7832">return </span><span style="background: black; color: white">sw.GetStringBuilder().ToString();
            }
        }</span></pre>
</td>
</tr>
</tbody>
</table>
<p>
  <br />This method finds the .lessx file and returns the result as a string. Now usually the view engine will take controller name and method name and by convention look in the /Views/css/index.aspx file. It doesn’t quite make sense to put it in the views folder so I have overridden the default web forms view engine so that they can be placed in the /Public/Css folder. This can be configured to your liking (convention).</p>
<table style="background: black" cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code"><span style="background: black; color: white">    </span><span style="background: black; color: #cc7832">public class </span><span style="background: black; color: #ffc66d">CustomViewEngine </span><span style="background: black; color: white">: </span><span style="background: black; color: #ffc66d">WebFormViewEngine
    </span><span style="background: black; color: white">{
        </span><span style="background: black; color: #cc7832">public </span><span style="background: black; color: white">CustomViewEngine()
        {
            </span><span style="background: black; color: #cc7832">var </span><span style="background: black; color: white">locs = </span><span style="background: black; color: #cc7832">new </span><span style="background: black; color: #ffc66d">List</span><span style="background: black; color: white">&lt;</span><span style="background: black; color: #cc7832">string</span><span style="background: black; color: white">&gt;(</span><span style="background: black; color: #cc7832">base</span><span style="background: black; color: white">.ViewLocationFormats);
            locs.Add(</span><span style="background: black; color: #a5c25c">&quot;~/Public/{1}/{0}&quot;</span><span style="background: black; color: white">); </span><span style="background: black; color: gray">//My personal choice
            </span><span style="background: black; color: white">locs.Add(</span><span style="background: black; color: #a5c25c">&quot;~/Views/{1}/{0}&quot;</span><span style="background: black; color: white">);  </span><span style="background: black; color: gray">//An alternative choice
            </span><span style="background: black; color: #cc7832">base</span><span style="background: black; color: white">.ViewLocationFormats = locs.ToArray();
        }
    }</span></pre>
</td>
</tr>
</tbody>
</table>
<p>Once your Custom View Engine has been overridden, you will need to add it to the ViewEngines.Engines collection in the application start method in the global.asax.cs.</p>
<table style="background: black" cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code"><span style="background: black; color: white">        </span><span style="background: black; color: #ffc66d">ViewEngines</span><span style="background: black; color: white">.Engines.Clear();
        </span><span style="background: black; color: #ffc66d">ViewEngines</span><span style="background: black; color: white">.Engines.Add(</span><span style="background: black; color: #cc7832">new </span><span style="background: black; color: #ffc66d">CustomViewEngine</span><span style="background: black; color: white">());</span></pre>
</td>
</tr>
</tbody>
</table>
<p>This will then allow us to write a *.lessx file like the following; you can also pass a strongly typed model to the .lessx file if you so wish in the same way you would to a regular aspx view.</p>
<table cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code">&lt;%@ Page Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewPage&quot; %&gt;

@basecolor: &lt;%= ViewData[&quot;baseColor&quot;] %&gt;;

body {
    background: @basecolor;
}</pre>
</td>
</tr>
</tbody>
</table>
<p>Which will be rendered to the browser as:</p>
<table cellspacing="0" cellpadding="2" width="400" border="1">
<tbody>
<tr>
<td valign="top" width="400">
        </p>
<pre class="code">body {
    background: #aabbcc;
}</pre>
</td>
</tr>
</tbody>
</table>
<p>And that’s it. I’m still working on the finer details but I am liking how it works at the moment. If you have any thoughts or suggestions, please leave a comment.</p>
<p>Adam</p>
]]></content:encoded>
			<wfw:commentRss>http://schotime.net/blog/index.php/2010/07/02/dynamic-dot-less-css-with-asp-net-mvc-2/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

