Implementing Multiple Page Templates
For some Web applications, one page template doesn't provide enough flexibility. For instance, the look and feel of your site for customers who are not logged into your site may be drastically different from the UI for users who are, requiring multiple templates.
You can extend the single-template model you've already seen to a multi-template model by taking two extra steps. First, you must add a property to the PageBody class that stores a template path identifying the appropriate template to load. You can assign this TemplatePath
property either inline, where you declare the PageBody control on the page, or in the code for that page. Here's the property definition.
Public Property TemplatePath() As String
Set(ByVal Value As String)
If _TemplateLoaded Then
Throw New System.Web.HttpException( _
"The page template cannot be set " & _
"more than once.")
_TemplatePath = Value
_TemplateLoaded = True
shows how to modify the PageBody class. One drawback is that after you set the TemplatePath
property, you cannot change it, which ensures that the page template is loaded only once. This is because after determining the appropriate template, the application must load it into memory immediately so that you can instantiate child controls inside the NamingPlaceHolder. Once that's done the child controls cannot be removed from the NamingPlaceHolder in one template and re-instantiated in another because that would cause the intrinsic events for the child controls to fire more than once.
The next step is to declare a generic, abstract PageTemplate class that each specific page template inherits from (see Listing 7
). The class defines a property that references the PageBody control class for the Web application. The base class is necessary because you don't know which template to load until runtime. Now, the PageBody class references the page template from this base class type, as opposed to the actual page template user control class as in the one-to-one page template model shown earlier.
The calling page specifies the correct template to use. If the value of the TemplatePage
property never changes for a given page in your Web application, then it may be simpler to specify it declaratively inline with the PageBody declaration:
<mysc:PageBody id="pgbTemplate" runat="server"
<!-- page level content -->
Otherwise, you should specify the correct template in code:
pgbTemplate.TemplatePath = "templates/Template_1.ascx"
Remember, it has to be one or the other. You cannot specify the template declaratively and programmatically.