|
- <?xml version="1.0"?>
- <?component error="true" debug="false"?>
- <component>
- <registration
- description="WscMvc ViewRenderer"
- progid="WscMvc.ViewRenderer"
- version="1.00"
- classid="{4948DF84-5DC6-448A-9F1B-EB596C28842B}">
- </registration>
-
- <public>
- <method name="Render">
- <parameter name="viewsDir"/>
- <parameter name="viewName"/>
- <parameter name="data"/>
- <parameter name="output"/>
- </method>
- </public>
-
- <script language="VBScript">
- <![CDATA[
- Option Explicit
-
- ' Loads a separate .html template and substitutes {{Key}} placeholders with
- ' HTML-encoded values from a Scripting.Dictionary. Never references ASP
- ' intrinsics - viewsDir is a plain path string resolved by the caller (same
- ' pattern as RequestContext's logDir). Only text-context HTML encoding is
- ' implemented (SPEC SS8); attribute/URL/JS-context encoding is out of scope
- ' until a view actually needs it. Template content is never executed as
- ' VBScript or evaluated as an expression - substitution is a single literal
- ' scan-and-replace pass.
- Sub Render(viewsDir, viewName, data, output)
- Dim fso, templatePath, template, stream
-
- output = ""
-
- If Not IsValidViewName(viewName) Then
- Err.Raise vbObjectError + 1, "WscMvc.ViewRenderer", "Invalid view name"
- End If
-
- Set fso = CreateObject("Scripting.FileSystemObject")
- templatePath = viewsDir & "\" & viewName & ".html"
-
- If Not fso.FileExists(templatePath) Then
- Set fso = Nothing
- Err.Raise vbObjectError + 2, "WscMvc.ViewRenderer", "View template not found"
- End If
-
- Set stream = fso.OpenTextFile(templatePath, 1) ' 1 = ForReading
- template = stream.ReadAll
- stream.Close
- Set stream = Nothing
- Set fso = Nothing
-
- output = ExpandTemplate(template, data)
- End Sub
-
- Function IsValidViewName(viewName)
- Dim i, c
- IsValidViewName = False
- If IsNull(viewName) Or IsEmpty(viewName) Then Exit Function
- If Len(viewName) = 0 Then Exit Function
- For i = 1 To Len(viewName)
- c = Mid(viewName, i, 1)
- If Not ((c >= "A" And c <= "Z") Or (c >= "a" And c <= "z") Or _
- (c >= "0" And c <= "9") Or c = "_" Or c = "-") Then
- Exit Function
- End If
- Next
- IsValidViewName = True
- End Function
-
- ' Single left-to-right scan for {{Key}} tokens. Unterminated "{{" and a key
- ' with no matching dictionary entry are both treated as template-authoring
- ' errors (Err.Raise) rather than emitted as literal text, so rendered output
- ' is always fully resolved - never partially-substituted markup.
- Function ExpandTemplate(template, data)
- Dim result, pos, openPos, closePos, key, hasKey
-
- result = ""
- pos = 1
-
- Do
- openPos = InStr(pos, template, "{{")
- If openPos = 0 Then
- result = result & Mid(template, pos)
- Exit Do
- End If
-
- result = result & Mid(template, pos, openPos - pos)
-
- closePos = InStr(openPos + 2, template, "}}")
- If closePos = 0 Then
- Err.Raise vbObjectError + 3, "WscMvc.ViewRenderer", "Unterminated view placeholder"
- End If
-
- key = Trim(Mid(template, openPos + 2, closePos - openPos - 2))
-
- hasKey = False
- If Not data Is Nothing Then
- If data.Exists(key) Then hasKey = True
- End If
- If Not hasKey Then
- Err.Raise vbObjectError + 4, "WscMvc.ViewRenderer", "Unresolved view placeholder"
- End If
-
- result = result & HtmlEncode(CStr(data(key)))
- pos = closePos + 2
- Loop
-
- ExpandTemplate = result
- End Function
-
- Function HtmlEncode(s)
- Dim r
- r = s
- r = Replace(r, "&", "&")
- r = Replace(r, "<", "<")
- r = Replace(r, ">", ">")
- r = Replace(r, """", """)
- r = Replace(r, "'", "'")
- HtmlEncode = r
- End Function
- ]]>
- </script>
- </component>
|