0

I am new to asp.net but Master Pages seem to do what I need - allow me to configure different templates/presentations/styles in runtime, so my app may take on a different look and feel by selecting a different Master Page. Each Master Page sits in its own folder with a set of images tailored for that "template" - I then want, in content pages, to reference various images sitting in the folder of the currently selected Master Page, for example the navigation buttons in a DataPager:

<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" 
    PageSize="25">
<Fields>
    <asp:NextPreviousPagerField ButtonType="Image" ShowFirstPageButton="True" 
        ShowNextPageButton="False" 
        FirstPageImageUrl="<<Current Master Root>>/img/action-first.png" 
        PreviousPageImageUrl="<<Current Master Root>>/img/action-prev.png" />
    <asp:NumericPagerField ButtonCount="10" NextPageText="&gt;&gt;" 
        PreviousPageText="&lt;&lt;" />
    <asp:NextPreviousPagerField ButtonType="Image" ShowLastPageButton="True" 
        ShowPreviousPageButton="False" 
        LastPageImageUrl="<<Current Master Root>>/img/action-last.png"
        NextPageImageUrl="<<Current Master Root>>/img/action-next.png" />
</Fields>
</asp:DataPager>
TEST: "<%= System.IO.Path.GetDirectoryName(MasterPageFile) %>" 
(this does not work if we try to use it inside the DataPager?)

Is there a proper way to be doing this, like the tilda ~ character is used to get to the application root folder? Setting this in code is also proving to be tedious, especially for things like DataPager where the properties are nested in dynamic lists of sub controls (For example I do not know how to set the property DataPager1.Fields[0].NextPreviousPagerField.FirstPageImageUrl in code).

I have found trying to do this with Themes requires more coding than I started with because I have to include the entire control definition in the skin file, not just the image url properties, and then I have to duplicate that code in every single theme/skin. If I happen to want a DataPager with a different configuration of buttons and/or numeric fields then I have to duplicate those variations in every skin file also. If I make a change at a later date I will have to remember to make that change in all skins also - seriously defeating the purpose of separating the code from the skin.

My application runs multiple projects, and each project may select its own template. For the entire application I want to say: if the current project uses TemplateX then use images from folder /TemplateX/img/, if TemplateY is seletected then use images from /TemplateY/img/. As you know CSS cannot always be relied upon to determine what image to use where, so we have to be able to put the image reference directly in the HTML output.

In the custom ISAPI DLL web system I developed I simply use a substitution string like "[#HTML.Template]/img/prev.png" to stick the template folder in front of the image URL. Is there perhaps a way I can hook a custom .aspx preprocessor to manually substitute all ocurrences of, as in the example above, "<< Current Master Root >>" with the currently selected folder?

Etherman
  • 1,777
  • 1
  • 21
  • 34
  • 1
    You may want to look at Themes instead - see http://msdn.microsoft.com/en-us/library/ykzx33wh.aspx You can switch Themes at Runtime quite easily. – dash Dec 02 '11 at 16:07
  • Using Themes sort of works but is not a great solution. I can put the img subfolder into the Theme folder, but I have to include everything in the tag, not just the image url properties. This means that I have to duplicate all this code for every theme (and for every type and variation of control), which kind of defeats the purpose. – Etherman Dec 05 '11 at 07:17
  • I think you've got a pretty decent solution to be honest. I would probably write my image urls as "/{MASTER}/img/img.png" and use a UrlRewriting library to capture paths to this URL and replace the token with the current master page. This is equivalent to what you have, although you don't need a custom ISAPI dll - you can just map a handler onto your .Net code (http://msdn.microsoft.com/en-us/library/ms972953.aspx). The alternative is to derive your own custom controls from the framework ones and change their render methods to be aware of the master page - the solution you have is much easier. – dash Dec 05 '11 at 09:06
  • The ISAPI dll is a completeley self-contained web system written using Delphi. I am trying to re-implement that solution using Visual Studio/ASP.NET. This may be the source of some mental blocks as I have preconceptions based on how I did things in that system, which for me seem obvious, but in asp.net seems to be very convoluted. I'll have a look at UrlRewriting but am a bit skeptical - for example, how does the url handler know what master page was used to construct the url, or would we then have to add the master page to the url (...which then leads to the same question as the original one) – Etherman Dec 05 '11 at 10:35
  • You should be able to see the current HTTPContext in the handler. Depending on where you are in the request lifecyle, you can get a handle to the page being requested, which means you should be able to work out the current master page. You can certainly get at the user, so you could also check to see what the user's current master page property is, too, if you wanted to store it as a user setting for the current user (via either session, a db query etc). – dash Dec 05 '11 at 10:45

1 Answers1

0

try use smething like this

var path = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + HttpContext.Current.Request.ApplicationPath;
huMpty duMpty
  • 14,346
  • 14
  • 60
  • 99
  • Your code does not include the current Master Page. For that I can use "System.IO.Path.GetDirectoryName(MasterPageFile)", but as stated there seems to be no convenient way to use this declaratively within a DataPager. – Etherman Dec 05 '11 at 06:56