T
tag2453
I have this code that I found online previously which is a very useful class
to apply templating to a 1.1 asp.net application. You can specify where in
the template you want user controls to load and it will parse them. However,
it won't work if the user control contains .net form fields such as
dropdownlists or buttons because the server form control doesn't get added
until the <!--area:body--> section is parsed. So what I need is a way to add
a tag in my html template <!-- control:form-> and have it add a form control
at this location and then load all remaining content in the template
(including user controls) inside this form control.
Any help would greatly be appreciated...
Sample HTML Template:
<html>
<head>....</head>
<body>
<!-- control:form-->
<table>
<tr><td>Main Navigation Row</td></tr>
<tr><td><!-- control:searchbox --></td></tr>
</table>
<-- area:body-->
<table>
<tr><td><!--control:joinemaillist--></td></tr>
<tr><td>Footer NavigationRow</td></tr>
</table>
</body>
</html>
BasePage class which all aspx pages inherit from instead of
System.web.ui.page:
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Configuration
Imports System.Web.Caching
Public Class BasePage
Inherits System.Web.UI.Page
Dim _strTemplate As String
Dim _strTemplateFile As String
Dim _strHeader As String
Dim _strFooter As String
Dim _strTitle As String
Public Property Title() As String
Get
Return _strTitle
End Get
Set(ByVal Value As String)
_strTitle = Value
End Set
End Property
Public Property TemplateFile() As String
Get
Return _strTemplateFile
End Get
Set(ByVal Value As String)
If Value <> Me.TemplateFile Then
_strTemplateFile = Value
GetTemplate()
End If
End Set
End Property
Private Sub Token(ByVal Key As String, ByVal Value As String)
_strTemplate = _strTemplate.Replace(String.Format("<!-- token:{0} -->",
Key), Value)
End Sub
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
Try
If Me.TemplateFile = String.Empty Then
If Not (Request("Template") Is Nothing) Then
Me.TemplateFile = Request("Template").ToString()
ElseIf Not (Request.Cookies("TEMPLATE") Is Nothing) Then
Me.TemplateFile = Request.Cookies("TEMPLATE").Value
End If
End If
'If we have still have no Template path get it from web.config
If Me.TemplateFile = [String].Empty Then
Me.TemplateFile = ConfigurationSettings.AppSettings("Template")
End If
Catch
End Try
End Sub
Private Sub GetTemplate()
If Me.TemplateFile <> String.Empty Then
If Not Request.QueryString("refresh") = "" Then
Cache.Remove(Me.TemplateFile)
End If
If Not Cache.Item(Me.TemplateFile) Is Nothing Then
_strTemplate = CType(Cache.Item(Me.TemplateFile), String)
Else
_strTemplate = GetTemplateText()
If InStr(Me.TemplateFile, "http:") > 0 Then
Cache.Insert(Me.TemplateFile, _strTemplate, Nothing,
DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration)
Else
Cache.Insert(Me.TemplateFile, _strTemplate, New
CacheDependency(Server.MapPath(Me.TemplateFile)), DateTime.Now.AddMinutes(5),
Cache.NoSlidingExpiration, CacheItemPriority.High, Nothing)
End If
End If
If _strTemplate.Length > 1 Then
'--- replace static token values
Token("title", _strTitle)
Token("date", Now())
'--- parse the template
Dim splitter As String = "<!-- area:body -->"
Dim Sections() As String =
System.Text.RegularExpressions.Regex.Split(_strTemplate, splitter)
_strHeader = Sections(0)
_strFooter = Sections(1)
Else
_strHeader = ""
_strFooter = ""
End If
End If
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
ParseArea(_strHeader, writer)
MyBase.Render(writer)
ParseArea(_strFooter, writer)
End Sub
Private Sub ParseArea(ByVal strTemplateArea As String, ByVal writer As
System.Web.UI.HtmlTextWriter)
If strTemplateArea <> "" Then
Dim regexp As New System.Text.RegularExpressions.Regex("<!--
control(.|\n)*?) -->", System.Text.RegularExpressions. _
RegexOptions.IgnoreCase)
Dim RegexMatch As System.Text.RegularExpressions.MatchCollection
RegexMatch = regexp.Matches(strTemplateArea)
If RegexMatch.Count > 0 Then
Dim ControlName As String = RegexMatch.Item(0).ToString().Replace("<!--
control:", String.Empty).Replace( _
" -->", String.Empty)
Dim SubAreas() As String =
System.Text.RegularExpressions.Regex.Split(strTemplateArea,
String.Format("<!-- control:{0} -->", ControlName))
ParseArea(SubAreas(0), writer)
MyBase.Controls.AddAt(0, LoadControl(String.Format("{0}.ascx",
ControlName)))
MyBase.Controls(0).RenderControl(writer)
MyBase.Controls.Remove(MyBase.Controls(0))
ParseArea(SubAreas(1), writer)
Else
'--- no more matches are found, so we can safely outpout
writer.Write(strTemplateArea)
End If
End If
End Sub
Private Function GetTemplateText() As String
Dim tempXMLText As New StringBuilder
Dim StreamString As String
Dim objStreamReader As StreamReader
If InStr(Me.TemplateFile, "http:") > 0 Then
Dim Client As New WebClient
Client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.2; .NET CLR 1.0.3705; .NET CLR 1.1.4322)")
If InStr(LCase(Me.TemplateFile), "staging") > 0 Then
Dim myCred As New NetworkCredential("user", "pass", "domain")
Dim myCache As New CredentialCache
myCache.Add(New Uri(Me.TemplateFile), "Basic", myCred)
Client.Credentials = myCache
End If
Dim data As Stream = Client.OpenRead(Me.TemplateFile)
Dim Reader As New StreamReader(data)
tempXMLText.Append(Reader.ReadToEnd())
data.Close()
Reader.Close()
Else
If File.Exists(Server.MapPath(Me.TemplateFile)) Then
Dim objReader As New
System.IO.StreamReader(Server.MapPath(Me.TemplateFile))
'_strTemplate = objReader.ReadToEnd()
tempXMLText.Append(objReader.ReadToEnd())
objReader.Close()
End If
End If
GetTemplateText = tempXMLText.ToString
End Function
End Class
to apply templating to a 1.1 asp.net application. You can specify where in
the template you want user controls to load and it will parse them. However,
it won't work if the user control contains .net form fields such as
dropdownlists or buttons because the server form control doesn't get added
until the <!--area:body--> section is parsed. So what I need is a way to add
a tag in my html template <!-- control:form-> and have it add a form control
at this location and then load all remaining content in the template
(including user controls) inside this form control.
Any help would greatly be appreciated...
Sample HTML Template:
<html>
<head>....</head>
<body>
<!-- control:form-->
<table>
<tr><td>Main Navigation Row</td></tr>
<tr><td><!-- control:searchbox --></td></tr>
</table>
<-- area:body-->
<table>
<tr><td><!--control:joinemaillist--></td></tr>
<tr><td>Footer NavigationRow</td></tr>
</table>
</body>
</html>
BasePage class which all aspx pages inherit from instead of
System.web.ui.page:
Imports System.IO
Imports System.Net
Imports System.Text
Imports System.Configuration
Imports System.Web.Caching
Public Class BasePage
Inherits System.Web.UI.Page
Dim _strTemplate As String
Dim _strTemplateFile As String
Dim _strHeader As String
Dim _strFooter As String
Dim _strTitle As String
Public Property Title() As String
Get
Return _strTitle
End Get
Set(ByVal Value As String)
_strTitle = Value
End Set
End Property
Public Property TemplateFile() As String
Get
Return _strTemplateFile
End Get
Set(ByVal Value As String)
If Value <> Me.TemplateFile Then
_strTemplateFile = Value
GetTemplate()
End If
End Set
End Property
Private Sub Token(ByVal Key As String, ByVal Value As String)
_strTemplate = _strTemplate.Replace(String.Format("<!-- token:{0} -->",
Key), Value)
End Sub
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
Try
If Me.TemplateFile = String.Empty Then
If Not (Request("Template") Is Nothing) Then
Me.TemplateFile = Request("Template").ToString()
ElseIf Not (Request.Cookies("TEMPLATE") Is Nothing) Then
Me.TemplateFile = Request.Cookies("TEMPLATE").Value
End If
End If
'If we have still have no Template path get it from web.config
If Me.TemplateFile = [String].Empty Then
Me.TemplateFile = ConfigurationSettings.AppSettings("Template")
End If
Catch
End Try
End Sub
Private Sub GetTemplate()
If Me.TemplateFile <> String.Empty Then
If Not Request.QueryString("refresh") = "" Then
Cache.Remove(Me.TemplateFile)
End If
If Not Cache.Item(Me.TemplateFile) Is Nothing Then
_strTemplate = CType(Cache.Item(Me.TemplateFile), String)
Else
_strTemplate = GetTemplateText()
If InStr(Me.TemplateFile, "http:") > 0 Then
Cache.Insert(Me.TemplateFile, _strTemplate, Nothing,
DateTime.Now.AddMinutes(1), Cache.NoSlidingExpiration)
Else
Cache.Insert(Me.TemplateFile, _strTemplate, New
CacheDependency(Server.MapPath(Me.TemplateFile)), DateTime.Now.AddMinutes(5),
Cache.NoSlidingExpiration, CacheItemPriority.High, Nothing)
End If
End If
If _strTemplate.Length > 1 Then
'--- replace static token values
Token("title", _strTitle)
Token("date", Now())
'--- parse the template
Dim splitter As String = "<!-- area:body -->"
Dim Sections() As String =
System.Text.RegularExpressions.Regex.Split(_strTemplate, splitter)
_strHeader = Sections(0)
_strFooter = Sections(1)
Else
_strHeader = ""
_strFooter = ""
End If
End If
End Sub
Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
ParseArea(_strHeader, writer)
MyBase.Render(writer)
ParseArea(_strFooter, writer)
End Sub
Private Sub ParseArea(ByVal strTemplateArea As String, ByVal writer As
System.Web.UI.HtmlTextWriter)
If strTemplateArea <> "" Then
Dim regexp As New System.Text.RegularExpressions.Regex("<!--
control(.|\n)*?) -->", System.Text.RegularExpressions. _
RegexOptions.IgnoreCase)
Dim RegexMatch As System.Text.RegularExpressions.MatchCollection
RegexMatch = regexp.Matches(strTemplateArea)
If RegexMatch.Count > 0 Then
Dim ControlName As String = RegexMatch.Item(0).ToString().Replace("<!--
control:", String.Empty).Replace( _
" -->", String.Empty)
Dim SubAreas() As String =
System.Text.RegularExpressions.Regex.Split(strTemplateArea,
String.Format("<!-- control:{0} -->", ControlName))
ParseArea(SubAreas(0), writer)
MyBase.Controls.AddAt(0, LoadControl(String.Format("{0}.ascx",
ControlName)))
MyBase.Controls(0).RenderControl(writer)
MyBase.Controls.Remove(MyBase.Controls(0))
ParseArea(SubAreas(1), writer)
Else
'--- no more matches are found, so we can safely outpout
writer.Write(strTemplateArea)
End If
End If
End Sub
Private Function GetTemplateText() As String
Dim tempXMLText As New StringBuilder
Dim StreamString As String
Dim objStreamReader As StreamReader
If InStr(Me.TemplateFile, "http:") > 0 Then
Dim Client As New WebClient
Client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.2; .NET CLR 1.0.3705; .NET CLR 1.1.4322)")
If InStr(LCase(Me.TemplateFile), "staging") > 0 Then
Dim myCred As New NetworkCredential("user", "pass", "domain")
Dim myCache As New CredentialCache
myCache.Add(New Uri(Me.TemplateFile), "Basic", myCred)
Client.Credentials = myCache
End If
Dim data As Stream = Client.OpenRead(Me.TemplateFile)
Dim Reader As New StreamReader(data)
tempXMLText.Append(Reader.ReadToEnd())
data.Close()
Reader.Close()
Else
If File.Exists(Server.MapPath(Me.TemplateFile)) Then
Dim objReader As New
System.IO.StreamReader(Server.MapPath(Me.TemplateFile))
'_strTemplate = objReader.ReadToEnd()
tempXMLText.Append(objReader.ReadToEnd())
objReader.Close()
End If
End If
GetTemplateText = tempXMLText.ToString
End Function
End Class