15

How can I use Razor in CSS files?

I'm using Razor View Engine for some time and I was curious about using it on style sheets. I can use Razor in <style> blocks of .cshtml files but I was wondering if I can use it in external .css files also (would like to have a .cscss format). So I googled it and found two things:

The first one is LESS: "The dynamic stylesheet language". It seems easy-to-use and powerful with all the features but I need Razor-C#, really.

The second is Dynamic CSS Using Razor Engine, a CodeProject article which is more like what I want but it has no caching or pre-compiling support (by "no support" I meant the writer didn't mention these aspects). I also would like to have some syntax highlighting in Visual Studio but this is secondary.

So, how can I write Razor in CSS files with minimum performance cost and preferably with syntax highlighting?

  • Is there a "more complete" project for that?
  • Can I improve the above project to achieve caching/compiling? If so, how?

As a side note:
I found a project called RazorJS. It's like the Javascript version of the same thing I want for CSS with its caching support. I'm mentioning this just to clarify my needs. I don't need to use Razor in Javascript currently but I guess if I make it out with CSS, doing the same thing with Javascript wouldn't be too hard.

jtate
  • 2,612
  • 7
  • 25
  • 35
Şafak Gür
  • 7,045
  • 5
  • 59
  • 96
  • You keep talking about syntax highlighting, this has nothing to do with razor. It is Visual Studio that does your editor. What is it you are trying to achieve, why do you want 'razor' in your css? – TJHeuvel Apr 23 '12 at 11:54
  • 3
    @TJHeuvel why do anyone want razor in their html? Why people use server-side scripting languages? Because they want their pages to be dynamic. This way they can store their data in a database instead of an html file. So why do I want razor in my css is because I want my css to be dynamic as well. I may keep design related data in my database (like background-color) and want to use it in my css. As for intellisense, visual-studio is one of this qustion's tags. I want to know how I can (if I can) use razor intellisense in css files and as I mentioned it's just a secondary thing to me. – Şafak Gür Apr 23 '12 at 12:50
  • @d4wn: Why do you want your CSS to be dynamic? There is quite a distinction between SASS/LESS and a view engine approach, in the latter case you're just sending the client non-cached stuff that could just be static... :S – Tamara Wijsman Apr 23 '12 at 13:18

1 Answers1

30

You could create a custom view engine:

public class CSSViewEngine : RazorViewEngine
{
    public CSSViewEngine()
    {
        ViewLocationFormats = new[] 
        { 
            "~/Views/{1}/{0}.cscss", 
            "~/Views/Shared/{0}.cscss" 
        };
        FileExtensions = new[] { "cscss" };
    }

    protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath)
    {
        controllerContext.HttpContext.Response.ContentType = "text/css";
        return base.CreateView(controllerContext, viewPath, masterPath);
    }
}

and also register it with a custom extension in Application_Start:

ViewEngines.Engines.Add(new CSSViewEngine());
RazorCodeLanguage.Languages.Add("cscss", new CSharpRazorCodeLanguage());
WebPageHttpHandler.RegisterExtension("cscss");

and inside web.config associate the extension with a build provider:

<compilation debug="true" targetFramework="4.0">
    <assemblies>
        ...
    </assemblies>

    <buildProviders>
        <add extension=".cscss" type="System.Web.WebPages.Razor.RazorBuildProvider, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
    </buildProviders>
</compilation>

[note, if you get an assembly binding error you might need to change the version number in the extension type to match your version of the Razor engine. You can check which version you are using by looking at the properties of your reference to the System.Web.WebPages.Razor assembly in your project]

And the last step is to have some controller:

public class StylesController : Controller
{
    public ActionResult Foo()
    {
        var model = new MyViewModel
        {
            Date = DateTime.Now
        };
        return View(model);
    }
}

and a corresponding view: (~/Views/Styles/Foo.cscss):

@model AppName.Models.MyViewModel

/** This file was generated on @Model.Date **/

body {
    background-color: Red;
}

which could now be included as a style in the Layout:

<link href="@Url.Action("Foo", "Styles")" rel="stylesheet" type="text/css" />
Simon P Stevens
  • 27,303
  • 5
  • 81
  • 107
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 3
    That's exactly what I was looking for, thank you. My next quest is to find how to make VS do some syntax higlighting (& intellisense) for **.cscss** files, I guess. – Şafak Gür Apr 23 '12 at 17:11
  • 1
    @Darin Dimitrov I have copied this code. And when I want to compile(F5) my asp.net mvc3 solution in VS I got this error: Error 136 Could not determine the code language for "~/Views/Styles/Test.cscss". AMS\AMS\ASPNETCOMPILER any idea why? – elranu Sep 19 '13 at 20:04
  • @Darin, the code's awesome but I'm wondering how it could be modified to serve a Less file since that involved an extra level of interpretation… thoughts? – ekkis Dec 03 '13 at 02:09