tags:

views:

53

answers:

2

Assuming I have a .css file with the following line

body { background-image: url('../images/bg.png') }

My build process does some CSS magic and eventuall move this file from

~/Content/styles/styles.css

To

~/temp/styles.css

This invalidates the url statement in the file and needs re-written to ../Content/images/bg.png

This is my question - given the original file location, the new file location and the background-image url in the file is there a reusable way calculate a new relative path for the image?

In case someone doesn't know css urls should be relative to the css file it is contained within.

A: 

You might consider using less to describe the image-path in a variable (pre-generating this as part of the build). Then you only have one thing to update?

Marc Gravell
Doesn't really answer my question. The example has only 1 place I need to change the value anyway :-P.
kouPhax
A: 

Solution 1

If you use ASP.NET themes, you can work around this issue. However, it also means you will have to restructure the way your files are.

Simply add a an App_Themes folder and a folder below that with a theme name ('Default' would be a good choice for a site with only 1 theme).

Add your theme name to the <pages> element in web.config:

<pages theme="Default">

Then put your css file inside of the theme folder. REMOVE any code that you use to reference the css file because ASP.NET will automatically wire it up to all of your pages.

If you want more control over the pages you add the css to, you can simply add the theme to the @page directive on the pages or do it in code behind in your base page in the Page_PreInit event instead of the web.config file.

Now, if you also put images below your theme folder, they can be referenced like this from css:

background-image: url('Images/Buttons/login-sprite.gif');

This example assumes your image file is in the location

[AppFolder]/App_Themes/Default/Images/Buttons/login-sprite.gif

and your css file is in the location

[AppFolder]/App_Themes/Default/Styles.css

Solution 2

If you prefer not to rearrange your files, you can also dynamically generate the file or read it into a string and replace a token of your choosing (example #MyImageFile#) with the actual url after calling ResolveUrl to make sure it is correct.

You could put code such as this in a file named Styles.aspx:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'This is a wrapper for the CSS file that allows us to inject
    'any image URLs directly into the file, accounting for any relative
    'path differences between different environments.

    Dim FileName As String = Server.MapPath("Styles.css")
    Dim sr As StreamReader
    Dim contents As String

    sr = File.OpenText(FileName)
    Try
        contents = sr.ReadToEnd
    Finally
        sr.Close()
    End Try


    'Now that we have the contents of the file, run our
    'function on it to replace the tokens
    contents = Me.ProcessConfigurationTokens(contents)

    Response.Clear()

    Response.AddHeader("content-type", "text/css")
    Response.Write(contents)
    Response.End()

End Sub

And then change your page references from Styles.css to Styles.aspx.

There is a performance hit with this approach, but it could be offset using caching. However, I think using Themes is the best approach because it solves the problem using the framework alone without writing any extra code.

NightOwl888
Neither of these suit my needs but you might have given me an idea. I will investigate soon.
kouPhax