Coffeehouse Post

Single Post Permalink

View Thread: [ASP.NET] the page template paradox - separating design and content
  • User profile image
    Bryn Waibel

    We do use a templating system. Ours is built based on the Asp.Net Forums 2.0 skinning system. It is a SkinnedForumWebControl similar to the Asp.Net Repeater control. The control is very basic and doesn't meet all of the requirements that you mention, it also doesn't use the methods drawn out in that thread. Rather than having our pages inherit from a base page control, the template itself is a control, which has four ITemplate properties -- HeaderTemplate, RightBarTemplate, ContentTemplate and LeftbarTemplate. The HTML of the control itself looks something like this:

    file: /skins/themes/default/Skin-PageTemplate.ascx
    <HTML>
        <HEAD>
            <Forums:Style runat="server" ID="Style1" />
     <asp:PlaceHolder id="HeaderControl" runat="server" />
        </HEAD>
        <body>
        <form>
     <div class="header"></div>
     <div class="mainnav"></div>
     <div class="left" runat="server" id="LeftBarContainer">
      <asp:PlaceHolder id="LeftBarControl"" runat="server" />

     </div>
     <div class="content" runat="server" id="ContentContainer">
      <asp:PlaceHolder id="ContentControl"" runat="server" />
     </div>
     <div class="right" runat="server" id="RightBarContainer">
      <asp:PlaceHolder id="RightBarControl"" runat="server" />
     </div>
     <div class="footer"></div>
        </form>
        </body>
    </HTML>

    Obviously this is a vast simplification, the actual HTML contains pretty much everything that is common to the entire site. The header image, The Crew, Online Users, the HTML for the footer and both of the main navigation controls at the top of the page.

    The PageTemplate class which inherits from SkinnedForumWebControl simply has 4 ITemplate properties and the children of the properties are instantiated in the corresponding PlaceHolder control. The reason for each of the container controls is that we can decide weather or not to show the container depending on the contents of the template, the RightBarControl is invisible when the RightBarTemplate property is null for instance. Once we created this Page template, we just built all of our pages using this as the main control on the page. Our pages end up looking like this:
       <Forums:PageTemplate ID="template" Runat="server">
          <HeaderTemplate>
          <style>
             .content{margin-right:0px;} 
          </style>
          </HeaderTemplate>
          <ContentTemplate>
             <Forums:ThreadView runat="server" id="ThreadView1" />
          </ContentTemplate>
          <LeftBarTemplate></LeftBarTemplate>
       </Forums:PageTemplate>

    The real great parts of this system were all implemented in the Asp.Net Forums 2.0 code, we just added a little sugar to make it taste better. The most difficult problem that we've faced with this method is probably that it isn't possible to access an ITemplates control collection. We'd like to be able to in a code behind do something like:

    ((Literal)this.template.HeaderTemplate.FindControl( "Title" ))
       .Text = "Page Title";

    But instead, we are forced to make a control <Forums:Title> which poses a rather difficult state problem, context is difficult to achieve and the page's title logic is not encapsulated in the page itself but rather in a site wide Title control (alas, that's a lie, title is handled in Forums:Style, so goes the difficulty of finding a simple example to represent a complex problem, the concept still holds true however). Aside from that deficiency, this method has treated us quite well. I'm not sure I've done it justice here, but I think you get the idea. Thanks for asking miies, this type of curiosity is my favorite part of this project.