The 20 Minute GuideContents: Hello, World!We'll start with a Hello World example.
HelloWorld.html
<html> <head> <title>Hello World</title> </head> <body> <p id="HelloText">Hello world </body> </html>
HelloWorld.dyn
<dynamator language="jsp"> <prolog> <%@ page session="false" %> <%! private String getGreeting() { return "Hi!"; } %> </prolog> <id name="HelloText"> <content>getGreeting()</content> </id> </dynamator> The command
java dynamate HelloWorld.html
produces:
→
HelloWorld.jsp
<%-- generated by Dynamator Sun Jun 24 17:01:47 CDT 2001 --%> <%@ page session="false" %> <%! private String getGreeting() { return "Hi!"; } %> <html> <head> <title>Hello World</title> </head> <body> <p id="HelloText"><%= getGreeting() %></p> </body> </html> Here's what happened:
Now that you've had a taste, let's get to the details. What Dynamator isDynamator is a language that specifies how to transform an HTML or XML file into a server page or program, and a tool for performing the transformation. Template filesThe file that Dynamator operates on is called a template. Templates must be XML. Dynamator converts HTML to XML using JTidy, a Java port of Tidy. It's a good idea to validate HTML using Tidy before using it with Dynamator. Examples in this guide use HTML; XML works the same way. Dynamator files
A Dynamator file describes how to transform a template file
into a server page or program. For any template file
Programming Language SupportDynamator uses language-specific plugins to format the output file. Dynamator ships with plugins for JSP, XSL, PHP, ASP, and Java. Plugins for other languages are easy to write and install. Dynamator also ships with a plugin for an imaginary language named "none", that provides default support for stream-oriented template languages (such as Velocity) as well as HTML and XML. The default plugin supports all Dynamator elements that don't require knowledge of the target language. Elements that require a language plugin are <content>, <if>, <for>, and <foreach>. Equivalent constructs can be coded manually using low-level Dynamator elements. The examples in this guide use JSP, but the Dynamator element syntax is the same regardless of language. Marking up HTML and XMLDynamator needs some way to identify locations in the HTML or XML template. It uses two standard HTML 4.0 attributes: id (used to identify a single location in an HTML file) and class (used to identify a set of locations in an HTML file). In general, every HTML element that needs to be changed in some way needs an id or class attribute. However, some HTML elements (such as <body> and <meta> do not support these attributes. Dynamator also provides a way to identify these elements so they can be changed. Sometimes there is no element at a location that needs to be changed. HTML 4.0 also defines two elements that can be used in this situation: span (an in-line element that can contain in-line content) and div (a block element that can contain block or in-line content). All these features are invisible; they do not affect the appearance of the HTML. (The div element implies a line break; if this is not desired Dynamator can remove the tag.) HTML authors are familiar with these features of HTML because they use them with CSS. Here's a simple example that shows the use of span:
TheTime.html
<html> <head> <title>What time is it?</title> </head> <body> <p>The time is <span id="Now">[time goes here]</span> </body> </html>
TheTime.dyn
<dynamator language="jsp"> <id name="Now"> <content>new java.util.Date()</content> </id> </dynamator>
→
TheTime.jsp
<%-- generated by Dynamator Fri Nov 23 17:52:49 CST 2001 --%><html> <head> <title>What time is it?</title> </head> <body> <p>The time is <span id="Now"><%= new java.util.Date() %></span></p> </body> </html> Dynamator file syntaxDynamator files use XML syntax, with the following important exceptions:
These exceptions simplify coding, and are similar to the kinds of exceptions made by languages such as JSP. A Dynamator file contains the changes to be applied to a template file. The structure of the file mirrors a two step process:
Root LevelHere's an empty Dynamator file: <dynamator language="jsp"> </dynamator>
Every Dynamator file must start and end with a First Level: LocatorsMost elements at the first level of the Dynamator file identify locations in the template file. These elements are called locators. Here's a Dynamator file showing the most important first-level elements: <dynamator language="jsp"> <prolog> This text is inserted at the beginning of the file </prolog> <id name="idname"> <!-- This locator matches any template element with the attribute id="idname" --> </id> <class name="classname"> <!-- This locator matches any template element with the attribute class="classname" --> </class> <tag tag="tagname"> <!-- This locator matches any template element with the name tagname --> </tag> <include file="filename"/> <!-- This element includes the contents of the Dynamator file filename --> <epilog> This text is inserted at the end of the file </epilog> </dynamator> File prolog and epilogThe <prolog> and <epilog> elements allow text to be placed at the very top and bottom of the output file. Text within these elements is copied as-is, including white-space. If you don't want white space, don't use any: <dynamator language="xsl"> <prolog><?xml version="1.0"></prolog> </dynamator> Locating elements by key
The Locating elements by id name
The
id_example.html
<html> ... <h1 id="title-heading">Title</h1> ... </html>
id_example.dyn
<dynamator language="jsp"> <id name="title-heading"> <content>titleHeading</content> </id> </dynamator>
→
id_example.jsp
...
<html>
...
<h1 id="title-heading"><%= titleHeading %></h1>
...
</html>
...
The
(In a valid HTML document, there is at most one occurrence
of any Locating elements by class name
The
class_example.html
<html> ... <h1 class="subject-name">Subject</h1> ... <h2>Summary for <span class="bold subject-name">Subject</span>:</h2> ... </html>
class_example.dyn
<dynamator language="jsp"> <class name="subject-name"> <content>subject.getName()</content> </class> </dynamator>
→
class_example.jsp
... <html> ... <h1 class="subject-name"><%= subject.getName() %></h1> ... <h2>Summary for <span class="bold subject-name"><%= subject.getName() %></span>:</h2> ... </html> ...
The
Note that the second template element above belongs to two
classes, Locating elements by name and attributesSometimes an HTML element can't legally have an id or class attribute. For example, id and class attributes are invalid for elements in the <head> section. So Dynamator also provides the tag locator, which can be used to locate a set of elements based on tag name and attributes. Here are some examples of the tag locator:
The Including other filesDynamator provides a file include mechanism to enable reuse. The <include> element logically inserts the contents of another Dynamator file into the including file. An <include> element may only be used at the top level, and the included file must be a Dynamator file. By default, Dynamator uses the directory containing the initial Dynamator file as the basis for resolving relative filenames. You can specify a search path using the command line option "-I dir". If multiple -I arguments are provided, each directory is tried in order. If the file isn't found in any of the include directories, the directory containing the top-level Dynamator file is tried. Second Level: ModifiersThe content of a locator specifies the changes to be made to the located element. Elements within a locator are called modifiers. Here's a locator element with the most frequently used modifiers. Note that these modifiers apply to the <class> and <tag> locators as well as <id>. <id name="idname"> <content> A program expression to be output instead of the element's content. </content> <raw-content> Text or code that replaces the attribute value. </raw-content> <discard/> <!-- Removes the element and its content --> <discard-tag/> <!-- Removes the element's start and end tags but not its content --> <attr name="attrname"> <!-- Attribute modifiers, described below. --> </attr> <rename to="element-name"/> <!-- Renames the element --> <!-- ======================================== Language-specific elements: These elements require a language plugin. ======================================== --> <if> A program conditional expression. The template element is output only if the condition is true. </if> <foreach> A program collection expression. The template element is output for each element of the collection. </foreach> </id> The <content> element contains a program expression (often a variable reference). Dynamator replaces the content of the template element with code to output the value of that expression. We've already seen examples of the <content> element in the helloworld and time examples.
The <content> element uses the language-specific
plugin to determine the appropriate expression reference
syntax for the target language. (For JSP, the expression
syntax is The <raw-content> element works like <content>, except that its content is used as-is. The <raw-content> is rarely used when a language-specific plugin is available. The <discard/> element causes the entire matched element to be removed (from the start-tag to the end-tag, including everything in between). This is useful for removing sample data from a demonstration site. The <discard-tag/> element causes just the matched start and end tags to be removed, leaving the element content. The <rename> element causes the matched element to be renamed. This is useful for JSP tag libraries and ASP.NET, which use pseudo-HTML elements. IfThe if element generates code to cause an element to be output only if a condition is true. The following Dynamator example uses if to generate a greeting appropriate for the time of day.
TimeGreeting.html
<html> <head> <title>What time is it?</title> <span type="text/css"> .hide { display: none } </span> </head> <body> <p>The time is <span id="Time">[time]</span></p> <p id="Morning">Good Morning!</p> <div class="hide"> <p id="Afternoon">Good Afternoon!</p> <p id="Evening">Good Evening!</p> </div> </body> </html>
TimeGreeting.dyn
<dynamator language="jsp"> <prolog> <%@ page import="java.util.Calendar"%> <% Calendar calendar = Calendar.getInstance(); int hour = calendar.get( Calendar.HOUR_OF_DAY); %> </prolog> <id name="Time"> <content>calendar.getTime()</content> </id> <id name="Morning"> <if>hour < 12</if> </id> <id name="Afternoon"> <if>12 <= hour && hour < 18</if> </id> <id name="Evening"> <if>18 <= hour</if> </id> <class name="hide"> <discard-tag/> </class> </dynamator>
→
TimeGreeting.jsp
<%-- generated by Dynamator Sat Nov 24 10:02:26 CST 2001 --%> <%@ page import="java.util.Calendar"%> <% Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); %> <html> <head> <title>What time is it?</title> </head> <body> <p>The time is <span id="Time"><%= new Date() %></span></p> <% if ( hour < 12 ) { %><p id="Morning">Good Morning!</p><% } %> <% if ( 12 <= hour && hour < 18 ) { %><p id="Afternoon">Good Afternoon!</p><% } %> <% if ( 18 <= hour ) { %><p id="Evening">Good Evening!</p><% } %> </body> </html>
The example above shows a pattern that can be used for
handling selective display of text defined in a template.
The template contains all the text, but displays only the
text associated with a single condition. This is so the
template can be used in a static demo site. (You can get a
lot more sophisticated in a demo site if you want.) The
Dynamator file makes all elements potentially visible--in
this case by removing the
Note a difference here from how you would hand-code this:
Dynamator does not support else. (Supporting
else would make the Dynamator file dependent on the
sequence of the entries in the HTML file.) You can always
use Dynamator's ForeachThe foreach element generates code to repeat the located template element for each element of a collection. The attributes used depend on the language. The following example outputs each item in the classpath.
Classpath.html
<html> <head> <title>Java Classpath</title> </head> <body> <h1>Classpath:</h1> <p class="pathelem"> (element) </body> </html>
Classpath.dyn
<dynamator language="jsp"> <prolog> <%@ page import="java.util.StringTokenizer"%> </prolog> <class name="pathelem"> <foreach type="Enumeration[String]" collection="tokens" element="dir" > new StringTokenizer( System.getProperty("java.class.path"), System.getProperty("path.separator")) </foreach> <content> dir </content> </class> </dynamator>
→
Classpath.jsp
<%-- generated by Dynamator Fri Nov 23 11:11:46 CST 2001 --%> <%@ page import="java.util.StringTokenizer"%> <html> <head> <title>Java Classpath</title> </head> <body> <h1>Classpath:</h1> <% { java.util.Enumeration tokens = new StringTokenizer( System.getProperty("java.class.path"), System.getProperty("path.separator")); String dir; while ( tokens.hasMoreElements() ) { dir = (String) tokens.nextElement(); %> <p class="pathelem"><%= dir %></p>> <% } } %> </body> </html> Attribute ModifiersAttributes can be changed, added, removed, and made conditional. Here's a locator element with all possible attribute modifiers. <id name="idname"> <attr name="attrname"> <content> A program expression to be output instead of the attribute value. </content> <raw-content> Text or code that replaces the attribute value. </raw-content> <discard/> <!-- Removes the attribute --> <rename to="attr-name"/> <!-- Renames the attribute --> <!-- ======================================== Language-specific elements: These elements require a language plugin. ======================================== --> <if> A program conditional expression. The attribute is output only if the condition is true. </if> </attr> </id> If an <attr> element contains a content or raw-content entry, and the corresponding attribute is not found in the template, it is added. Text can also be added directly to a tag using the raw-attrs modifier.
Within the content and raw-content entries
for an <attr> element, the magic string
Menu.html
<html> <head> <title>Menu</title> </head> <body> <a href="page1.html">Page 1</a> <br> <a href="page2.html">Page 2</a> <br> <a href="page3.html">Page 3</a> <br> <a href="page4.html">Page 4</a> </body> </html>
Menu.dyn
<dynamator language="jsp"> <tag tag="a" with-attr="href"> <attr name="href"> <content> response.encodeURL("[[@/.html/.jsp]]") </content> </attr> </tag> </dynamator>
→
Menu.jsp
<%-- generated by Dynamator Sat Nov 24 10:55:37 CST 2001 --%><html> <head> <title>Menu</title> </head> <body> <a href="<%= response.encodeURL("page1.jsp") %>">Page 1</a><br> <a href="<%= response.encodeURL("page2.jsp") %>">Page 2</a><br> <a href="<%= response.encodeURL("page3.jsp") %>">Page 3</a><br> <a href="<%= response.encodeURL("page4.jsp") %>">Page 4</a><br> </body> </html> Primitive ModifiersPrimitive modifiers support low-level changes to a template. You shouldn't need to use them very often. If you are generating to an unsupported template language, you can use primitive modifiers to manually create if and foreach logic. (Better yet, create a plugin and save yourself some time.) Here's a locator element showing all the primitive modifiers. Note that these modifiers apply to the <class> and <tag> locators as well as <id>. <id name="idname"> <before> Text or code inserted immediately before the element's start tag </before> <before-content> Text or code inserted immediately after the element's start tag </before-content> <raw-content> Text or code that replaces the element's content. </raw-content> <after-content> Text or code inserted immediately before the element's end tag </after-content> <after> Text or code inserted immediately after the element's end tag </after> <raw-attrs> <!-- Text or code added to the element's start tag. --> </raw-attrs> </id> Here's the placement relationship of the primitive elements to the located element in the generated server page: before <located-element raw-attrs> before-content element content or content or raw content after-content </located-element> after Locator PrecedenceIf an element is addressed by multiple locators, locators are applied in the following order:
If more than one of any kind of locator (for example, two <tag> locators) matches the same element, they are applied in the order they appear in the Dynamator file. Regardless of how many locators match, only one of each kind of modifier is applied. Attribute modifiers are distinguished by attribute name, so if locator 'a' has an attribute modifier for attribute 'x', and locator 'b' has an attribute modifier for attribute 'x' and attribute 'y', locator 'a's modifier for 'x' will be applied, and locator 'b's modifier for 'y' will be applied. Where to go from hereYou now should have a basic understanding of Dynamator facilities for creating server pages and programs. Some possible next steps:
|
|||||||||||||
Page last updated 01 April 2004 |
Copyright 2001-2004 by Jay Dunning. All rights reserved. |
hosted by |