You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by cr...@apache.org on 2001/04/27 14:21:00 UTC
cvs commit: jakarta-turbine/xdocs webmacro-site.xml
criley 01/04/27 05:21:00
Modified: xdocs webmacro-site.xml
Log:
Fixing my own error, I carelessly clobbered the file.
Revision Changes Path
1.5 +399 -62 jakarta-turbine/xdocs/webmacro-site.xml
Index: webmacro-site.xml
===================================================================
RCS file: /home/cvs/jakarta-turbine/xdocs/webmacro-site.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- webmacro-site.xml 2001/04/27 12:12:33 1.4
+++ webmacro-site.xml 2001/04/27 12:20:58 1.5
@@ -2,113 +2,450 @@
<document>
<properties>
- <title>Getting Started with the TDK</title>
- <author email="eric@dobbse.net">Eric Dobbs</author>
+ <title>WebMacro Site</title>
+ <author email="jon@latchkey.com">Turbine Documentation Team</author>
</properties>
<body>
-<section name="The really big picture:">
+<section name="WebMacro Site">
+
+<p>
+In Turbine, we have excellent integration with the template tool
+<a href="http://www.webmacro.org/">WebMacro</a>,
+we call this WebMacroSite building. The reason why we want to wrap Turbine
+around WebMacro instead of using it on its own is to provide a completely
+MVC model for building web applications where the framework has control
+over the authentication, security, connection pool, etc and WebMacro is
+simply used as the View portion of the MVC model. Turbine is responsible
+for helping you manage all the different templates as well so that you
+can easily construct a site that both designers and engineers can work
+together on (<strong>that is our primary goal!</strong>). The reason why this is
+good is that it will help you design and build web applications that have
+more functionality and less duplication of code since Turbine is fully
+re-usable.
+</p>
+
+<p>
+Knowledge of how WebMacro works and what a WebMacro Context object is
+are required for understanding this documentation. This documentation also
+assumes that you are using a Servlet API 2.2 and higher serlvet engine
+such as <a href="http://jakarta.apache.org/tomcat/">Tomcat</a> because
+we are now targeting towards using WAR archives. Although, this should
+work with older servlet engines as well...it just may be slightly harder
+for you to setup. You should also be familiar with the rest of the Turbine
+documentation that is referenced on the <a href="index.html">index page</a>.
+</p>
+
+<p>
+Here is a brief description of the way that the system works: all requests
+are passed through the Turbine Servlet. The servlet is then responsible
+for brokering the request, building up the Context object and then calling
+WebMacro's template engine to process your template document and return
+the results. Pretty simple. Now, lets move on to some more detailed
+instructions...:-)
+</p>
+
+</section>
+
+<section name="Screens">
+
+<p>
+Lets start off with a simple WebMacro Screen to get things rolling
+so you can see how powerful things are. You should compile this class into
+your <em>WEB-INF/classes</em> directory.
+</p>
+
+<source><![CDATA[
+
+// WebMacro Stuff
+import org.webmacro.*;
+import org.webmacro.servlet.*;
+import org.webmacro.util.*;
+
+// Turbine Stuff
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.modules.screens.WebMacroSiteScreen;
+
+public class HelloWorld extends WebMacroSiteScreen
+{
+ public void doBuildTemplate( RunData data, Context context )
+ throws Exception
+ {
+ // the context object has already been setup for you!
+ context.put ("hello", "this is a test...");
+ }
+}
+]]></source>
+
+<p>
+Ok, as you can see, you do not even need to return a value from your method!
+You simply stuff objects into the WebMacro Context and that is it! Next,
+you will want to create a .wm template of the same name as your class:
+HelloWorld.wm...within that template you will put the BODY portion of your
+page. In other words, there is no reason to put the header/footer into
+this file since that will be built seperately (more documentation on that
+futher down...). You should save this document in your <em>templates/screens/</em>
+directory.
+</p>
+
+<source><![CDATA[
+<p>
+ <font color="red">
+ $hello of the emergency broadcast station.
+ <font>
+</p>
+]]></source>
+
+<p>
+When you request a URL like this:
+</p>
+
+<p>
+http://www.server.com/servlet/Turbine/template/HelloWorld.wm
+</p>
+
+<p>
+What that will do is cause the system to first execute the HelloWold.java
+class (if it exists) and then it will call WebMacro's template engine directly
+and execute the HelloWorld.wm template and then return the results back
+to you.
+</p>
+
+<p>
+<em>NOTE:</em> Turbine capitalizes the first letter in the class file name
+before looking for the matching class in the classpath. This allows you to
+follow (somewhat) normal class naming guidelines. For example:
+</p>
+
+<p>
+index.wm and Index.wm both map to Index.class
+
+roleeditor.wm maps to Roleeditor.class
+
+role_editor.wm maps to Role_editor.class
+</p>
+
<p>
-As you are developing your new Turbine application, you will
-be working mainly in three our four areas:
+The result will be a fully formed HTML document with the <em>$hello</em>
+replaced with the value: "this is a test...". If you want to make the URI
+above shorter or easier to read, you could simply re-write things using
+<a href="http://www.apache.org/docs/mod/mod_rewrite.html">mod_rewrite</a>.
+For example, by removing the "<em>/servlet/Turbine/template</em>" portion
+of the URI.
</p>
-<dl>
- <dd>
- 1. design and create your object model
- </dd>
- <dd>
- 2. create ApplicationTools (tools used in conjunction with
- the pull service)
- </dd>
- <dd>
- 3. create templates that use the ApplicationTools
- </dd>
- <dd>
- (1.5 in some cases you may be creating services that sit
- roughly between the object model and the
- ApplicationTools.
- </dd>
-</dl>
<p>
-Item 1 is the Model in the Model-View-Controller design
-pattern. In Turbine, this is a combination of the
-project-schema.xml file you will create to define your
-object model, and the various files Torque will create from
-your project-schema.xml.
+As you can see, this is much easier than doing servlet after servlet
+because it removes a lot of the setup and other things that could potentially
+go wrong. It also makes the individual template files easier to manage
+and more re-usable because there isn't any surrounding page layout mixed
+in with the page.
</p>
<p>
-Item 2, roughly speaking, is a bridge between your object
-model and the templates. If you are in a large shop, this
-is where the programmers will create an API for the web
-designers. If you are in a small shop, you still want to
-use the Pull model because it will make it much easier to
-modify your web application down the road.
+If you want to do something that is more complicated than this that
+is reflected across all of your Screens, then you should write a class
+that is a subclass of WebMacroSiteScreen and then put your specific code
+in there. For example, if you wanted a security method to be called automaticially
+without having to normally call super() to get it from an overridden method
+in the superclass, you could have something like this (semi-pseudo untested
+code):
</p>
+<source><![CDATA[
+
+// WebMacro Stuff
+import org.apache.webmacro.Context;
+
+// Turbine Stuff
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.modules.screens.WebMacroSiteScreen;
+
+public abstract class SecureScreen extends WebMacroSiteScreen
+{
+ protected boolean doCheckSecurity(RunData data)
+ throws Exception
+ {
+ if (data.isSecure())
+ return true;
+ else
+ return false;
+ }
+
+ /*
+ * override the doBuild() method of the
+ * TemplateScreen to always check security first
+ */
+ public void doBuild(RunData data, Context context) throws Exception
+ {
+ if ( !this.doCheckSecurity(data))
+ {
+ // set the template and screen to be different or do
+ // some other short circuit code here
+ }
+ doBuildTemplate(data, context);
+ return super.buildTemplate(data, context);
+ }
+}
+]]></source>
+
<p>
-Item 3 is the View. This is where you build the user
-interface for your web application. In Turbine these are
-typically Velocity templates.
+What this would do is override the doBuild() method in TemplateScreen (which
+is the base class that WebMacroSiteScreen subclasses from) and have it
+always do a security check before displaying the content. The benefit of
+this is that all you need to do to add security to your screen is to simply
+subclass this class instead of WebMacroSiteScreen. There is also no need
+to remember to call super() since the doBuild() method will be called for
+you automaticially by Turbine. You can start to see how Turbine is simply
+an extension of the servlet framework itself. For example, the Servlet
+Engine will call HttpServlet's service() method for you, just like Turbine
+will call your doBuild() method for you. Tight integration with tools like
+WebMacro just make things even cleaner. :-)
</p>
<p>
-The Turbine servlet is the Controller. Item 1.5 is how
-you extend the functionality of the controller in very
-flexible ways.
+One other feature in this system is that if you are not building up
+a Context object that is specific for your screen, then you do not need
+to create a Java class to match the template file. You simply create the
+.wm template and put it in a directory and call it with the same URI described
+above. This is really useful when you have a static site of content that
+you are converting to be dynamic and you only want to do small portions
+of it at any one time. You can also do the opposite of this which is to
+only create a Java class file and no template file. You can do this by
+simply overriding the doBuild() method in TemplateScreen and returning
+your results directly instead of attempting to build a template. Later,
+when you want to add a template and remove the HTML code, you can change
+the doBuild() into a doBuildTemplate(), build the Context object up and
+you are done. Cool!
</p>
<p>
-You can use JSP instead of Velocity, in which case item 2
-will consist of JSP tag libraries, and item 3 will be JSP
-templates that use those tag libraries.
+Here is an example of having templates in subdirectories and making
+links to each of them...
</p>
+
+<p>
+Create a directory structure like this:
+</p>
+
+<p>
+WEB-INF/templates/screens/admin/
+Put <em>index.wm</em> into the <em>screens/</em> directory.
+Put <em>UserAdmin.wm</em> into the <em>screens/admin/</em> directory.
+</p>
+
+<p>
+In index.wm, if you want to link to UserAdmin.wm, you would add something
+like this to the HTML:
+</p>
+
+<source><![CDATA[
+
+<a href="$link.setPage("admin,UserAdmin.wm")</font>">User Admin Screen</a>
+
+]]></source>
+
+<p>
+As you can see above, I used a "," instead of a "/". You can use either
+one here. The above will create a fully formed URI with the session information
+encoded into the link if the clients brower has cookies turned off.
+</p>
+
</section>
+
+<section name="Layout and Navigations">
-<section name="Getting to know the TDK:">
<p>
-Download the latest TDK and install it.
+Now that you know how to create simple Screens, you are probably wondering
+where the layout and navigation portions of the page come from and how
+you control that. If you were not wondering that, then shame on you. :-)
+Essentially, it is the same exact procedure as before except you subclass
+WebMacroSiteLayout and WebMacroSiteNavigation instead. Again, it is possible
+to not have Java class files always match up with the template and in most
+cases, you probably won't need to have a user defined Context in the Layout.
</p>
<p>
-Login with username 'turbine' and password 'turbine'
+Below is an example Layout. It will be searched for in the templates/layouts
+directory structure and also takes advantage of the same template path
+lookup code as described below:
</p>
+<source><![CDATA[
+
+#if ( $data.getMessage() )</font>
+{
+ $data.getMessage()
+}
+
+<table width="100%">
+
+<tr>
+ <td>$navigation.setTemplate("/default_top.wm")</td>
+</tr>
+<tr>
+ <td>$screen_placeholder</td>
+</tr>
+<tr>
+ <td>$navigation.setTemplate("/default_bottom.wm")</td>
+</tr>
+
+</table>
+
+]]></source>
+
<p>
-Insert a couple entries into the sample application, edit
-them, delete them. Play with Flux by adding a couple users,
-groups, roles, and permissions. These two examples are
-fairly basic web applications, but they contain all the
-ingredients of more complex applications.
+The variable <em>$screen_placeholder</em> is important here because that
+is where the output from your Screen will be placed. WebMacroSiteLayout
+is responsible for taking care of this. The other variables are for including
+your Navigations into the system. The benefit of all of this is that it
+enforces the View portion of the MVC model because the "body" and "navigation"
+portions of your page simply becomes a variable that you can plug into
+any number of Layouts and in any location. If you want to write code so
+that the Layout is determined by a variable in the database or in the HTTP
+request or whever, all you need to do is write your own WebMacroSiteLayout
+and override some of the methods in there to determine the layout based
+on your own conditions instead of the system default conditions.
</p>
+</section>
+
+<section name="How the templates are found">
+
<p>
-Item 1: look at WEB-INF/build/project/*-schema.xml and at
-WEB-INF/src/java/org/mycompany/newapp/om/*Peer.java and at
-WEB-INF/src/sql/*
-These are the Model part of the picture.
+Since everything is keyed off the template variable, if
+<em>data.getParameters().getString("template")</em>
+returns <em>/about_us/directions/driving.wm</em>, the search for the Screen
+class is as follows (in order):
+<ol>
+<li>
+about_us.directions.Driving</li>
+
+<li>
+about_us.directions.Default</li>
+
+<li>
+about_us.Default</li>
+
+<li>
+Default</li>
+
+<li>
+WebMacroSiteScreen</li>
+</ol>
</p>
<p>
-Item 2: look at ...<br/>
-TODO: need a pull version of the sample application so we
-can have an ApplicationTool to look at.
+If the template variable does not exist, then <em>WebMacroSiteScreen</em>
+will be executed and <em>templates/screens/index.wm</em> will be executed.
+If <em>index.wm</em> is not found or if the template is invalid or WebMacro
+execution throws an exception of any reason, then <em>templates/screens/error.wm</em>
+will be executed.
</p>
<p>
-Item 3: look at ./templates/screens/*.vm to see examples
-of Velocity templates.
+For the Layouts and Navigations, the following paths will be searched
+in the layouts and navigations template subdirectories (in order):
</p>
<p>
-Item 1.5: look at the javadoc for TurbineSecurity as an
-example of the service
+<ol>
+<li>
+/about_us/directions/driving.wm</li>
+
+<li>
+/about_us/directions/default.wm</li>
+
+<li>
+/about_us/default.wm</li>
+
+<li>
+/default.wm</li>
+</ol>
</p>
+
</section>
+<section name="Actions">
+<p>
+Actions happen when you have an <em>action</em> parameter defined in the
+URI. For example:
+</p>
+
+<p>
+<u>http://www.server.com/servlet/Turbine/template/HelloWorld/action/UpdateWorld</u>
+In this case, what happens is that the class UpdateWorld class (located
+in your <em>WEB-INF/classes/PACKAGE/actions/</em> directory) is executed
+first before anything. Then your HelloWorld class (located in your WEB-INF/classes/PACKAGE/screens/
+directory) is executed. Then your template (for screen/navigation/layout)
+HelloWorld.wm is executed. The point of an action is that it should perform
+some sort of "action" on your system. Usually, this means storing some
+information from a POST request into a database or sending email or something
+of that nature. Actions themselves do not return results, but may set a
+message with data.setMessage(). They can also short circuit the system
+by changing the Template and Screen to be executed. You might want to do
+that if there is an error with the form data and you want to re-display
+the same page again. Unlike most of the rest of the modules (ie: Screens,
+Navigations, Layouts), there is no corresponding WebMacro template file
+for an Action.
+</p>
+
+<source><![CDATA[
+
+// WebMacro Stuff
+import org.apache.webmacro.Context;
+
+// Turbine Stuff
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.modules.actions.WebMacroAction;
+
+public class AddUser extends WebMacroAction
+{
+ public void doPerform( RunData data, Context context ) throws Exception
+ {
+ if ( data.getParameter.getString("username",null) == null)
+ {
+ data.setMessage("Username does not exist");
+ setTemplate ( data, "AddUser.wm" );
+ return;
+ }
+
+ // store user info into database
+ data.setMessage("Information stored!");
+ setTemplate( data, "MainMenu.wm");
+
+ // stuff something into the WebMacro Context
+ context.put ("variable", "foo");
+ }
+}
+
+]]></source>
+
+<p>
+In the very basic example Action above, a check is performed to make sure
+that
+the form data contained a "username" variable. If there is no data, the
+template is changed back to the "AddUser" template and the processing is
+stopped with an error message that can be easily displayed in the template.
+If the processing finishes, then the MainMenu.wm template will be shown
+and the message can be displayed.
+</p>
+
+</section>
+
+<section name="Action Event">
+
+<p>
+There is also a new feature of Turbine that the WebMacroSiteAction takes
+advantage of, it is called <a href="action-event.html">Action Event</a>.
+Please click the link and read more documentation about it. This is an
+excellent way to write your actions because now they are entirely event
+driven based on which button was clicked in the HTML form.
+</p>
+
+</section>
</body>
-</document>
\ No newline at end of file
+</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: turbine-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: turbine-dev-help@jakarta.apache.org