G
Guest
The way the system works is, you create a user control (ascx) that will be a
template and must implement the interface IPageTemplate. You then create one
or more user controls (ascx) that implement the IPageContent interface. A
page (aspx) must then be created that loads (using Page.LoadControl) the
page template, and the page content. The page content adds itself to the
page template. The page template is then added to the aspx's control
collection. [Remember , Page and UserControl, derive from Control]. The
known drawbacks to this system are, it will double the file count since each
templated page must have an ascx and an aspx. Since the content of the
rendered page is stored in ascx files, the ids of server controls will be
changed at render-time.
My implementation of templated websites is based on the idea that, one wants
to develop a website where all pages have a consistent layout content [e.x.:
the same header, footer, and maybe a navigation bar on the left hand side]
with unique/dynamic content for each page. If you separate the two, every
page has a 'template' and '[dynamic] content' and I present to you, the two
interfaces, IPageTemplate and IPageContent.
public interface IPageTemplate
{
HtmlContainerControl Body
{
get;
}
HtmlContainerControl Head
{
get;
}
Control Content
{
get;
}
}
The IPageTemplate interface was created on the idea/assumption that every
template should have at least 3 HTML sections. A HTML body section, a HTML
head section, and a section where the dynamic content should be placed. You
may even encounter cases where the Content property returns the same
reference as the Body property. Anything more (such as a Title property, a
'NavigationBar' property, etc) can be specified in another interface or
class that implements IPageTemplate. The definition of the IPageContent is
as followed:
public interface IPageContent
{
void AddToTemplate(IPageTemplate pageTemplate);
}
It has only one method 'AddToTemplate'. The idea behind this is the method
is to be called to let the content 'add itself to a page template'.
To a show a simple example of the following in action, I present the three
files.
TemplateTest.ascx - This is my "master" page. It defines the template I
would like to use. I define a simple layout where I want every page to start
with "TEMPLATE EPILOGUE" and end with "TEMPLATE PROLOGUE".
I implement the IPageTemplate interface.
----------------------------------------------------------------------------
<%@ Control%>
<%@ Implements interface="HB.Web.UI.IPageTemplate" %>
<script language="C#" runat="server">
public System.Web.UI.HtmlControls.HtmlContainerControl Body
{
get
{
return body;
}
}
public System.Web.UI.Control Content
{
get
{
return content;
}
}
public System.Web.UI.HtmlControls.HtmlContainerControl Head
{
get
{
return head;
}
}
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head runat="server" id="head">
</head>
<body runat="server" id="body">
<form runat="server" method="post">
TEMPLAE EPILOGUE<br>
<asplaceHolder ID="content"
Runat="server"></asplaceHolder>
TEMPLAE PROLOGUE<br>
</form>
</body>
</html>
----------------------------------------------------------------------------
Test.ascx - Here I define a content section that outputs the date and time.
----------------------------------------------------------------------------
<%@ Control%>
<%@ Implements interface="HB.Web.UI.IPageContent" %>
<script language="C#" runat="server">
void HB.Web.UI.IPageContent.AddToTemplate(HB.Web.UI.IPageTemplate template)
{
template.Content.Controls.Add(this);
}
</script>
I AM DYNAMIC CONTENT <%=DateTime.Now.ToString()%><br>
----------------------------------------------------------------------------
Test.aspx - Here I create a page that loads it's respective content
(Test.ascx) and the template I want to use (TemplateTest.ascx).
I then call AddToTemplate on the content control to make it add itself to
the template. I then add the template to the page's controls.
----------------------------------------------------------------------------
<%@ Page%>
<script language="C#" runat="server">
public void Page_Init(object sender, EventArgs e)
{
//load template
Control template = LoadControl("TemplateTest.ascx");
//load the content and invoke AddToTemplate
Control content = LoadControl("Test.ascx");
((IPageContent)content).AddToTemplate((IPageTemplate) template);
//add the template to the page.
Controls.Add(template);
}
</script>
----------------------------------------------------------------------------
And the redered html is
----------------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head id="_ctl0_head">
</head>
<body id="_ctl0_body">
<form name="__aspnetForm" method="post" action="Test.aspx"
id="__aspnetForm">
<input type="hidden" name="__VIEWSTATE"
value="dDw1MzgxOzs+ON1TyCLuD5sISHo9HTqB06VGFh4=" />
TEMPLAE EPILOGUE<br>
I AM DYNAMIC CONTENT 11/25/2004 12:58:43 PM<br>
TEMPLAE PROLOGUE<br>
</form>
</body>
</html>
----------------------------------------------------------------------------
template and must implement the interface IPageTemplate. You then create one
or more user controls (ascx) that implement the IPageContent interface. A
page (aspx) must then be created that loads (using Page.LoadControl) the
page template, and the page content. The page content adds itself to the
page template. The page template is then added to the aspx's control
collection. [Remember , Page and UserControl, derive from Control]. The
known drawbacks to this system are, it will double the file count since each
templated page must have an ascx and an aspx. Since the content of the
rendered page is stored in ascx files, the ids of server controls will be
changed at render-time.
My implementation of templated websites is based on the idea that, one wants
to develop a website where all pages have a consistent layout content [e.x.:
the same header, footer, and maybe a navigation bar on the left hand side]
with unique/dynamic content for each page. If you separate the two, every
page has a 'template' and '[dynamic] content' and I present to you, the two
interfaces, IPageTemplate and IPageContent.
public interface IPageTemplate
{
HtmlContainerControl Body
{
get;
}
HtmlContainerControl Head
{
get;
}
Control Content
{
get;
}
}
The IPageTemplate interface was created on the idea/assumption that every
template should have at least 3 HTML sections. A HTML body section, a HTML
head section, and a section where the dynamic content should be placed. You
may even encounter cases where the Content property returns the same
reference as the Body property. Anything more (such as a Title property, a
'NavigationBar' property, etc) can be specified in another interface or
class that implements IPageTemplate. The definition of the IPageContent is
as followed:
public interface IPageContent
{
void AddToTemplate(IPageTemplate pageTemplate);
}
It has only one method 'AddToTemplate'. The idea behind this is the method
is to be called to let the content 'add itself to a page template'.
To a show a simple example of the following in action, I present the three
files.
TemplateTest.ascx - This is my "master" page. It defines the template I
would like to use. I define a simple layout where I want every page to start
with "TEMPLATE EPILOGUE" and end with "TEMPLATE PROLOGUE".
I implement the IPageTemplate interface.
----------------------------------------------------------------------------
<%@ Control%>
<%@ Implements interface="HB.Web.UI.IPageTemplate" %>
<script language="C#" runat="server">
public System.Web.UI.HtmlControls.HtmlContainerControl Body
{
get
{
return body;
}
}
public System.Web.UI.Control Content
{
get
{
return content;
}
}
public System.Web.UI.HtmlControls.HtmlContainerControl Head
{
get
{
return head;
}
}
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head runat="server" id="head">
</head>
<body runat="server" id="body">
<form runat="server" method="post">
TEMPLAE EPILOGUE<br>
<asplaceHolder ID="content"
Runat="server"></asplaceHolder>
TEMPLAE PROLOGUE<br>
</form>
</body>
</html>
----------------------------------------------------------------------------
Test.ascx - Here I define a content section that outputs the date and time.
----------------------------------------------------------------------------
<%@ Control%>
<%@ Implements interface="HB.Web.UI.IPageContent" %>
<script language="C#" runat="server">
void HB.Web.UI.IPageContent.AddToTemplate(HB.Web.UI.IPageTemplate template)
{
template.Content.Controls.Add(this);
}
</script>
I AM DYNAMIC CONTENT <%=DateTime.Now.ToString()%><br>
----------------------------------------------------------------------------
Test.aspx - Here I create a page that loads it's respective content
(Test.ascx) and the template I want to use (TemplateTest.ascx).
I then call AddToTemplate on the content control to make it add itself to
the template. I then add the template to the page's controls.
----------------------------------------------------------------------------
<%@ Page%>
<script language="C#" runat="server">
public void Page_Init(object sender, EventArgs e)
{
//load template
Control template = LoadControl("TemplateTest.ascx");
//load the content and invoke AddToTemplate
Control content = LoadControl("Test.ascx");
((IPageContent)content).AddToTemplate((IPageTemplate) template);
//add the template to the page.
Controls.Add(template);
}
</script>
----------------------------------------------------------------------------
And the redered html is
----------------------------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head id="_ctl0_head">
</head>
<body id="_ctl0_body">
<form name="__aspnetForm" method="post" action="Test.aspx"
id="__aspnetForm">
<input type="hidden" name="__VIEWSTATE"
value="dDw1MzgxOzs+ON1TyCLuD5sISHo9HTqB06VGFh4=" />
TEMPLAE EPILOGUE<br>
I AM DYNAMIC CONTENT 11/25/2004 12:58:43 PM<br>
TEMPLAE PROLOGUE<br>
</form>
</body>
</html>
----------------------------------------------------------------------------