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