Equivalent to master pages in ASP Classic - templates

Is it possible to build some kind of master page with Classic ASP without frames or iframes?
I’m wondering if there is a way to include content pages in the main page like ASP.NET master pages do. From what I have researched, ASP Classic does support inclusion of other ASP/HTML pages into a page, but the value put into this include means the function cannot be dynamic.

You could just create functions (say, a Header() function and a Footer() function) which do nothing but output some set of markup. Those functions can take parameters too, and be called conditionally. It's not quite the same as a Master page, but it sounds like it accomplishes what you are trying to do. You would have an <!--#include file="headerfooter.asp"--> on each page, and each page would call Header() & Footer().
Or you can just use <!--#include file="header.asp"--> at the top and <!--#include file="footer.asp"--> at the bottom of each page too. I've seen both approaches.
If you are looking for the reverse, that is, a single template page which calls individual pages in it's "middle" section, then that's not really something you can do easily with ASP classic. It's a fundamental difference in approach: ASP.NET has a concept of a control tree, events, etc, while ASP Classic is essentially just a script that runs top to bottom.

This idea is from Classic ASP Master Pages | Godless Code. I’ve transcribed the code in images on that page, extended its example a bit, and also explored the limitations of this technique.
The idea is that each page has only one Server-Side Include (one <!--#include file="" --> call). The single inclusion is a master template file, which you could name master.asp. The master page calls custom subroutines on each page in place of each content area. Each child page defines those subroutines with Sub, with content unique to that child page.
master.asp
<!DOCTYPE html>
<html>
<head>
<title><% Title() %></title>
</head>
<body>
<% BodyContent() %>
</body>
</html>
aboutUs.asp
<!--#include file="master.asp" -->
<% Sub Title %> About Us <% End Sub %>
<% Sub BodyContent %>
<h1>About Us</h1>
<p>
We do things!
</p>
<% End Sub %>
That turns into this HTML when you visit aboutUs.asp on an IIS server:
<!DOCTYPE html>
<html>
<head>
<title> About Us </title>
</head>
<body>
<h1>About Us</h1>
<p>
We do things!
</p>
</body>
</html>
However, this approach does not allow nesting:
subtemplate.asp
<div class="innerLogo <% LogoSide() %>">
<% LogoImg() %>
</div>
template_user.asp
<!--#include file="master.asp" -->
<% Sub Title %> Our Logo <% End Sub %>
<% Sub BodyContent %>
<!--#include file="subtemplate.asp" -->
<% Sub LogoSide %> leftside <% End Sub %>
<% Sub LogoImg %>
<img src="img/about.png" alt="About" />
<% End Sub %>
<% End Sub %>
This will not work, because nested Subs are a syntax error:
Microsoft VBScript compilation error '800a03ea'
Syntax error
/template_user.asp, line 9
Sub LogoSide
^
Since nesting is not allowed, this templating system is, in effect, a one-time solution. If your individual pages’ subroutines become too unwieldy, you can’t use this technique again. So when using this technique, you should carefully choose where to carve out your set of templates in order to provide the best balance between flexibility and DRYness.

Rory wrote a great example for master pages in Classic ASP, but demonstrated that the "master page" approach had its limitations because Subs cannot be nested.
However, for the sake of demonstration, and because JavaScript in Classic ASP has hardly any documentation anywhere on the Internet, here's the same example that fails in ASP VBScript but won't fail in ASP JavaScript.
master.asp
<!DOCTYPE html>
<html>
<head>
<title><% Title() %></title>
</head>
<body>
<% BodyContent() %>
</body>
</html>
subtemplate.asp
<div class="innerLogo <% LogoSide() %>">
<% LogoImg() %>
</div>
template_user.asp
<%# Language= "Javascript" %>
<!--#include file="master.asp" -->
<% function Title() { %> About Us <% } %>
<% function BodyContent() { %>
<!--#include file="subtemplate.asp" -->
<% function LogoSide() { %> leftside <% } %>
<% function LogoImg() { %>
<img src="img/about.png" alt="About" />
<% } %>
<% } %>
It works! here are the juicy results:
<!DOCTYPE html>
<html>
<head>
<title> About Us </title>
</head>
<body>
<div class="innerLogo leftside ">
<img src="img/about.png" alt="About" />
</div>
</body>
</html>
Remember, JavaScript, even the ECMAScript 3 version in Classic ASP, is often way more powerful and expressive than the VBScript engine that was favoured and heavily promoted by Microsoft. If you ever have to use Classic ASP, use JavaScript!

One of the ugliest problems in classic ASP is that #includes always happen, so putting two includes in an if-then-else construct always includes both – even though you only see the output that applies to your conditional value.
Even when includes work, they don't give you the result you're really looking for, which is to select a template or skin “on the fly”.
One way to handle this situation is to use a template engine such as KudzuASP that surpasses the traditional #include methodology. Here is a very simple example:
<!-- An HTML Template -->
<html>
<head><title><!--[Replace|PageTitle]-->PageTitle<!--[/Replace]--></title></head>
<body>
<table border="1" cellpadding="4" callspacing="2" width="640">
<tr>
<td colspan="2"><!--[HeaderContent/]--></td>
</tr>
<tr>
<td width="160"><!--[LeftColumnContent/]--></td>
<td><!--[MainContent/]--></td>
</tr>
<tr>
<td colspan="2"><!--[FooterContent/]--></td>
</tr>
</table>
</body>
</html>
And the ASP code looks like this:
<%# Language=VBScript %>
<!-- #include file="./KudzuASP/_kudzu.asp" -->
<%
Dim PageTitle : PageTitle = "This is a Master Page"
'
' Create the template engine
'
Dim T_ENGINE
Set T_ENGINE = New CTemplateEngine
T_ENGINE.PutValue "PageTemplate", PageTemplate
T_ENGINE.SetHandler "HeaderContent", New CTXHeaderContent
T_ENGINE.SetHandler "LeftColumnContent", New CTXLeftColumnContent
T_ENGINE.SetHandler "MainContent", New CTXMainContent
T_ENGINE.SetHandler "FooterContent", New CTXFooterContent
'
' Custom Tage Handlers
'
Class CTXHeaderContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Header"
End Sub
End Class
Class CTXLeftColumnContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Left<br/>Content"
End Sub
End Class
Class CTXMainContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Main<br/>Content"
End Sub
End Class
Class CTXFooterContent
Public Sub HandleTag(vNode)
vNode.Engine.ContentAppend "Footer"
End Sub
End Class
'
' Evaluate the template
'
T_ENGINE.ParseFile Server.MapPath("./MasterPage.html")
T_ENGINE.EvalTemplate
%>
The template engine makes calls to your custom objects defined in the hosting ASP code page when the appropriate tags are processed. The function members of your custom classes have direct access to the hosting page and its variables and methods, as well as the template engine’s object hierarchy. In other words, the template is driving the output and the hosting ASP page during output.
This beats the include mechanism hands down, because the template engine can dynamically select which HTML template to process at runtime, and it can dynamically include libraries of custom tag handlers using the built in <!--[import/]--> tag.
UPDATE 2016.01.13: I have open sourced this project and you can find the latest code maintained at this address: https://github.com/Mumpitz/KudzuASP

I just use a Default.asp page with html, then put my code in the content area.
<%# Language="VBScript" %>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
</head>
<body>
<div id="topNav"> <!--begin top Nav-->
<ul>
<!--Be sure that all links are like this href="?page=contentPageEx"-->
<li>Home</li>
</ul>
</div> <!--end top Nav-->
<div id="content">
<%
Dim default
default= Request.QueryString
If default= "" Then
Server.execute "includes/home.html"
Else
Server.execute "includes/" & request("page") & ".html"
end if
%>
</div>
<div id="botNav"> <!--begin bot Nav-->
<ul>
<li>Home</li>
</ul>
</div> <!--end Bot Nav-->
</body>
</html>
Then I put all my content into an includes file with html pages.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!--Search engines use this title ect...-->
<title>Hello SEO! This is a content page!</title>
<!--Can be styled independently-->
<style>
p {
color: #0094ff;
}
</style>
</head>
<body>
<p>Hello World!</p>
</body>
</html>

Related

Rails link_to not loading leaflet map

I've come across a really strange (at least to me) issue. When I type the url by hand the map load just fine, however, when I use a link (either rails or a href) the map won't load until I hit refresh.
Any ideas?
routes.rb
Rails.application.routes.draw do
root 'page#map'
end
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>LeafletTest</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
map.html.erb
<%= link_to("reload page (rails)", root_path) %><br />
reload page (a href)<br />
<div id="mapid"></>
page.scss
#mapid {
width: 100%;
height: 600px;
}
page.coffee
$ ->
map = L.map('mapid').setView([
51.505
-0.09
], 13)
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', attribution: '© OpenStreetMap contributors').addTo map
I was able to fix this issue by ensuring a new TileLayer was created every time the map was rendered, i.e. when turbolinks:load is fired.
With the help of some other posts, I finally discovered that this was due to Turbolinks, and the way it calls a page load. Adding the data: { turbolinks: false} attribute to my rails link helped clear it up. I imagine it would work (with the correct formatting) for a non-rails link.

dotCMS - Creating a Custom page (page content-type)

EDIT:
My objective:
Create a news page template with header and footer and body.
The news page needs a form for a content editor to add content to with two fields: Headline and story.
Each news page requires its own SEO meta data (keywords / description title).
These stories need to be easy to find within the CMS for future editing etc etc.
What is the best way of going about this?
What I currently have is a "Page" content-type which has all the form fields I require.
To create a new news item, I currently do:
Go to Site Browser
Right-Click [myFolder]
Click "New" --> Page
Choose my page from the select box (that was the page content-type I created earlier)
I now see my form, fill it in and save/publish and I see it, but with the issues I expressed before.
I am pretty sure I am going about this in the wrong way, but what is the right way?
-------------
I am struggling to create a very basic page in dotCMS.
Here is what I want to do:
Create a form for a content editor to be able to add content to the page (Content-Type: Page called "myForm") DONE
The form contains all the default fields (seo stuff etc that comes with the Page content-type) + two extra text fields I have created (fieldA and fieldB) DONE
Create a container and add in the velocity variable names. DONE
Surround the velocity variable names in some HTML. <div>$fieldA</div> and <div>$fieldB</div> DONE
Create a new theme with a template.vtl file DONE
So that is all set up. I now go and create a new page in a folder via Site Browser choosing my new "Page" called "myForm" from the drop down menu. I see my form and enter my data, save and publish.
Result. I dont see any of my data. Just a blank page.
So I check the docs and see what I have missed.
There is a page explaining that I need to add in some velocity into my template.vtl that looks like this:
#if($dotPageContent && $dotPageContent.fieldA)
<div class="row">
#dotedit($!dotPageContent.inode,$!dotPageContent.fieldA)
</div>
#end
#if($dotPageContent && $dotPageContent.fieldB)
<div class="row">
#dotedit($!dotPageContent.inode,$!dotPageContent.fieldB)
</div>
#end
(link to dotCMS help page)
OK, so now when I check my page again, the data is indeed being displayed. But there is a problem. The HTML that is in my container does not get parsed.
E.g. <div>$fieldA</div> and <div>$fieldB</div> does not have the <div></div> tags.
So now I'm worried this is not the way to create pages.
The reason I chose the "Page" content-type was that it comes ready to go with the "Advanced Propertied" for the page like SEO meta data (which by the way all worked fine).
Can someone point out what I may have missed or perhaps a better way of going about this?
Thanks in advance.
If you could post your container and template code somewhere and include the links here I could help you resolve the issue for sure, but I think what might be happening is that you are confusing the Page Content Type with the Container defined Content Types.
Here is a quick explanation that might help conceptual differentiation:
http://screencast.com/t/PlEXKU9glGd
What I explain in the video is that the Page Content Types are for page properties only - not content addition. Like you want a different facebook link on many of your pages, or some other special property tied to each page. To place content in a container, you use a secondary "Content" Content Type, and you add that content type to a container's code field. When a page loads, the execution happens in this order, the Page content loads, page properties and metadata are set, the page calls a template that provides the layout, the template calls containers, the containers have the code that formats the content, and then the content executes in the order that it is placed in the container by the content publisher. The Page content type is not intended to really provide any information that the front end user actually sees other than the Page Title, page url, and properties and metadata that are set "silently" in the background html of the page.
You also might find it helpful to join the dotCMS communty forum: http://dotcms.com/forum/
Hope that helps
In addition to my other post, I did do the test with what you were trying to to, in a test advanced template, and the template.vtl file does display the Page Content, as long as you actually edit your page properties and set, in this case, field A:
<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
#set($dotTheme = $contents.getEmptyMap())
#set($blah1 = $dotTheme.put("path", "/application/themes/one-pager/"))
#set($dotThemeLayout = $contents.getEmptyMap())
#set($blah2 = $dotThemeLayout.put("title", "Bear Mountain"))
<head>
#if($dotPageContent && $dotPageContent.fieldA)
<div class="row">
#dotedit($!dotPageContent.inode,$!dotPageContent.fieldA)
</div>
#end
##dotParse("${dotTheme.path}html_head.vtl")
</head>
#set($utilClass = $pageTitle.toLowerCase().replace(' ', '-'))
<body data-spy="scroll" data-target=".top-nav" data-offset="100">
<div class="body-wrapper">
#dotParse("${dotTheme.path}header.vtl")
<div class="content-wrapper" id="hotel">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h2>The Lodge</h2>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="wow fadeInLeft" data-wow-delay=".8s">
## Container: Default 2 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('5eb11b21-6b13-4fb8-a823-1de20bba56c0')
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="wow fadeInRight" data-wow-delay="1.2s">
## Container: Default 3 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('f1ba7688-453c-4c0d-a214-e5ac802b8034')
</div>
</div>
</div>
</div>
</div>
<div class="image-wrapper bg-image-1 hidden-xs" data-stellar-background-ratio="0.5"></div>
<div class="content-wrapper">
<div class="container">
<div class="row">
<div class="col-sm-12">
## Container: Default 1 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('56bd55ea-b04b-480d-9e37-5d6f9217dcc3')
</div>
</div>
</div>
</div>
<div class="image-wrapper bg-image-2 hidden-xs" data-stellar-background-ratio="0.7"></div>
<div class="content-wrapper">
<div class="container">
<div class="row">
<div class="col-sm-12">
## Container: Default 4 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('a6e9652b-8183-4c09-b775-26196b09a300')
</div>
</div>
</div>
</div>
</div>
#dotParse("${dotTheme.path}footer.vtl")
Powered by Dotcms - The Leading Open Source Java Content Management System
</body>
</html>
This was tested on demo.dotcms.com: U:admin#dotcms.com / P: admin

How to check if an object's value equals <p> </p> in custom Tags in .tag file

I am trying to create a custom tag using .tag file to check weather a value passed in attribute is equal to an html paragraph tag
<p> </p>
Here is my code
checkEmptyBody.tag
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# attribute name="pb_val" required="true" rtexprvalue="true" %>
<c:if test="${pb_val eq '<p> </p>'}">
<%-- Do some action here--%>
</c:if>
Code for usage of above defined Tag
bodyAndHeadingsAndTags.jsp
<c:set var="processedBody">
<article:renderField var="inlineElement" field="body">
<c:choose>
<c:when test="${inlineElement.content.articleTypeName == 'picture'}">
<div class="inline-image">
<%-- Unfortunately it is not possible to get the width/height of the inline image as it is in Content Studio
(by dragging the corners of the image), so therefore a hardcoded version is used instead. --%>
<img src="${inlineElement.content.fields.alternates.value.w300.href}"
width="${inlineElement.content.fields.alternates.value.w300.width}"
height="${inlineElement.content.fields.alternates.value.w300.height}"
alt="${fn:trim(inlineElement.content.fields.caption)}"
${not empty fn:trim(inlineElement.content.fields.caption) ? 'class="captify"' : ''}
title="${inlineElement.content.fields.caption}"/>
</div>
</c:when>
<c:otherwise>
<%-- do nothing!! --%>
</c:otherwise>
</c:choose>
</article:renderField>
</c:set>
<c:out value="${processedBody}"></c:out>111111111111111
<%-- <tgam:substring input="GOODMORNING" start="2" end="6"/>--%>
<tools:checkEmptyBody pb_val="${processedBody}" />
In bdyandheading <c:out value="${processedBody}"></c:out>
The problem is even if the value of pb_val is
<p> </p>
, the if condition comes out to false and hence the action is not performed.
I think since the value is not a string, it's an html tag, the if condition fails.
How to test for such equality?? Do I have to use regular expression or is there some other way to do this??
Thanks

This code contains no errors while compiling but gives errors while running it.

This code contains no errors while compiling but gives errors while running it.
I am not able to run this code on tomcat 7.0. I started restarting it several times. Can you suggest me any ideas how to change the code so that it works?
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<%# page import="java.util.*" %>
<body>
<form action="MyWSserve" method="get">Enter Zip Code
<br>
<input type="text" name="zipcode"></input>
<input type="submit" name="GO" value="GO"></input>
</form>
<% //Object obj=request.getAttribute("values");
//if(obj instanceof ArrayList){
//ArrayList<String>mylist = (ArrayList<String>)obj; }%>
<% //Iterator<String>itr = mylist.iterator(); %>
<% String[] strcode=(String[])request.getAttribute( "values"); %>
<p>The Temperature in Centigrade <%=strcode[0] %><br></p>
<p>The Temperature in Farenheit <%=s trcode[1] %><br></p>
<p>The Pressure is <%=s trcode[2] %><br></p>
<p>The weather Condition is <%=s trcode[3] %><br></p>
</body>
</html>
Try this:
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<%# page import="java.util.*" %>
<body>
<form action="MyWSserve" method="get">Enter Zip Code
<br>
<input type="text" name="zipcode"></input>
<input type="submit" name="GO" value="GO"></input>
</form>
<% //Object obj=request.getAttribute("values");
//if(obj instanceof ArrayList){
//ArrayList<String>mylist = (ArrayList<String>)obj; }%>
<% //Iterator<String>itr = mylist.iterator(); %>
<% String[] strcode = request.getParameterValues("values"); %>
<% if (strcode != null && strcode.length >= 4) { %>
<p>The Temperature in Centigrade <%=strcode[0] %><br></p>
<p>The Temperature in Farenheit <%= strcode[1] %><br></p>
<p>The Pressure is <%= strcode[2] %><br></p>
<p>The weather Condition is <%= strcode[3] %><br></p>
<% } else { %>
<p>Call this page using 4 parameters called "values":
?values=1st&values=2nd&values=3rd&values=4th
<% } %>
</body>
</html>

java.io.IOException: No serializer found for class

Below jsp displays the returned HashMap value from the webservice
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<%#page import="com.action.AuraDecisionWorsheetDetailsService"%>
<%#page import="com.action.AuraDecisionWorsheetDetailsServiceLocator"%>
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<form name="form1" method="post" action='gawd.jsp'>
<center><h1>DETAILS</h1></center>
<%
try{
AuraDecisionWorsheetDetailsService psi = new AuraDecisionWorsheetDetailsServiceLocator();
com.action.AuraDecisionWorsheetDetails ps = psi.getAuraDecisionWorsheetDetails();
if(request.getParameter("PolId")!=null){
String pol_id=request.getParameter("PolId");
%>
<center><b>RESULT :</b> <%= ps.service(pol_id)%></center>
<% }else
{%>
<TABLE align="center">
<TR>
<TD>ENTER POLICY NUMBER</TD>
<TD><input type="text" name= "PolId" /></TD>
</TR>
<TR>
<TD colspan="2" align="center"> </TD>
</TR>
<TR>
<TD colspan="2" align="center"><input type="submit" value="Submit"></TD>
</TR>
</TABLE>
<% }
}catch(Exception exe)
{
exe.printStackTrace();
}
%>
</form>
</BODY>
</HTML>
Received below exception
faultString: java.io.IOException: No serializer found for class com.solcorp.pathfinder.uidefs.UIElement in registry org.apache.axis.encoding.TypeMappingDelegate#c87621
Caused by: java.io.IOException: No serializer found for class com.solcorp.pathfinder.uidefs.UIElement in registry org.apache.axis.encoding.TypeMappingDelegate#c87621
Web service takes one parameter i.e. pol_id and returns HashMap.
It is created using Apache Axis.
You have so many problems in this code:
It is a bad practice to call webservices from the jsp, you should do it in the servlet. The jsp should mainly focus on presentation not on logic. Try using jstl.
You are doing alert(pol_id); without opening any script tag. alert is a javascript function and must be contained inside <script></script>.
You have this line: <TD><input type="text" name= "PolId" %></TD>, it should obviously be: <input type="text" name= "PolId" /></TD> (note that i changed % at the end to /.
in this line: <%= ps.service(pol_id)%> you are missing ; at the end.
You have this condition:
`if(request.getParameter("PolId")!=null){
String pol_id=request.getParameter("PolId")==null?"":request.getParameter("PolId");}`
you are doing the same check twice, either remove the if or the ternary operator.
Fix these problems (the first one is really more of a best practice, so you can skip it for now), and then if you have more problems come back and post your question.
EDIT:
in your code you are eching the result from the service:
`<center><b>RESULT :</b> <%= ps.service(pol_id)%></center>`
but as you mentioned it is a Hashmap, so i don't think you can echo it directly. you need to echo the values you extract from it, so try doing this for testing:
//in the java snippet
Map map = ps.service(pol_id);
...
//in the html
<center><b>RESULT :</b> <%= map.get(0)%></center>