You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by Gabriel Sidler <si...@teamup.ch> on 2002/02/13 23:59:10 UTC

Velocity View API for Struts

As promised, I put together a proposal for the view API of Velocity
in the Struts framework. I consulted: 

- the ContextHelper.java by Ted
- the MessageTool.java by Nathan
- the existing Struts RequestUtil class
- the existing Struts JSP taglibs

to come up with a set of methods that should provide the necessary
Struts support from within Velocity templates. I have grouped functionality
by categories to give the whole method list some structure. I have really
focused on the Struts support. Other tools, like Nathan's LinkTool, 
are useful additions to the tools project, but are independent of Struts.


This is going to be a difficult discussion if we don't structure it
a bit. Let's please define the following three phases:

Phase 1) What functionality should be covered by the view API. Is
the proposed method set adequate. What needs to be added, what is irrelevant.
How should method signatures be changed to make them Velocity-friendly.
This does *not* cover the method names and the grouping of methods
into tools. It's meaningless to talk about grouping before we are 
clear what methods there are.

Phase 2) Group methods into tools. Define tool names and method names. 
(The method names really depend on the tools that we define)

Phase 3) Hash out the implementation strategy. ContextHelper or not?
ControllerAPI? Was parts are implemented on the Struts side and what
on the Velocity side, etc.


I'll serve as the editor of this draft and provide you with updated versions
as the discussion progresses.

Anyone with some Struts experience should really come forward now and 
comment on the proposal. I look forward to your feedback. Remember,
it's phase 1 now! :-)

Gabe



-------------------------------------------------------------------------------

VELOCITY VIEW API FOR STRUTS
============================


Category: Handling of URLs
--------------------------

Struts supports a configurable level of indirection between the URLs of a 
request and the handler of that request. For example, a URL of /main.do 
may be mapped by configuration to a handler of class com.app.my.handler.
Futhermore, Struts knows the concept of 'forwards'. A 'forward' is a name
for a request target, such as a request handler or simply a web page. 

This configurable mapping of logical targets to actual targets allows
one to avoid hard-coded URLs in templates. All the logical links between
the different views of an application can be maintained in a configuration
file. The following three methods are used to maps logical names to actual
URLs. The remaining methods are related.


public String actionURL(String action) 

    Converts the action name into a server-relative URL.
    Example: 
    <form name="login" action='$tool.actionURL("login")'>
    produces something like
    <form name="login" action="/myapp/actions/loginaction">


public String forwardURL(String forward)

    Converts the local or global forward into a server-relative URL.
    Example: 
    <a href='$tool.forwardURL("home")'>Home</a>
    produces something like
    <a href="/myapp/templates/index.vm">
    

public String forwardURL(String target, String parameters)

    Same as above but appends the string parameters are the end of the URL.
    Example:
    <a href='$tool.forwardURL("home", "frames=no&style=simple")'>Home</a>
    produces something like
    <a href="/myapp/templates/index.vm?frames=no&style=simple">
    

public String absoluteURL(String path)

    Create and return an absolute URL for the specified context-relative
    path.
    
    
public String baseRef() 

    Renders the reference for a HTML <base> element.
    Example: 
    <base href="$tool.baseRef()">
    produces something like
    <base href="/myapp/template/view.vm">


Support for the switch between HTTP and HTTPS would be useful here too. 
There has been some discussion on the list but currently Struts doesn't 
support it as far I know, right Ted?




Category: Messages
------------------

Struts supports internationalized messages. The messages are stored
in NVP files by language. The following methods operate on these message 
files.


public String message(String key)

    Return the localized message for the specified key.
    Example:
    <input type="submit" name="newbutton" value='$tool.message("view35.new")'/>
    renders something like
    <input type="submit" name="newbutton" value='Neuer Patient anmelden'/>
    

public String message(String key, Object args[])

    Same as above, but supports parametric message strings, for example:
      warning.quota=Your mail folder is {0} MB above the limit of {1} MB.
    Up to five replacement parameters are supported.
    

public boolean isMessage(String key)

    Return true if a message string for the specified message key
    is present for the user's Locale.
    

Question to Ted: How should the new ActionMessage be considered? What's
its role and how are they different than ActionError




Category: Error Handling
------------------------

Errors may stem from the validation of a submitted form or from the 
processing of the request. If there are errors, they are made available
to the view to output. A few aspects about errors are:
- Error messages are looked up in a bundle of messages resource files. Support 
for internationalized messages is provided.
- Error messages can have up to four replacement parameters.
- Errors have a property that marks them as 'global errors' (meaning that they
apply to the entire form) or 'specific errors' (meaning that they are specific
to one of the form elements). This allows to position error messages precisely 
where the error occured on the form.


public boolean hasErrors() 

    Returns true if there are errors queued, otherwise false.


public int errorSize() 

    Returns the number of error messages. 


public int errorSize(String property) 

    Returns the number of error messages for a particular property.
    

public String[] errors() 

    Returns an array of localized error messages. A typical application 
    would use a script similar to the following to output the error messages.
    Example:
    <ul>
    #foreach ($e in $tool.errors )
      <li>$e</li>
    #end
    </ul>


public String[] errors(String property) 

    Same as above but only the error messages for a particular 
    property are retrieved and returned.


public String errorMarkup()

    Returns a formatted error text consisting of all queued
    error messages. The markup is composed of an 'errors.header',
    followed by all error messages, followed by an 'errors.footer'. 
    'errors.header' and 'errors.footer' are keys that reference 
    messages in the messages resources bundle. If no errors are
    queued, an empty String is returned. 
    While some may consider it not nice that markup is produced 
    by this method, it is important to note that all markup is under 
    the control of the view designer. 
    Example:
    $tool.errorMarkup 
    Does all that's needed to output a formatted error message.
    
    
public String errorMarkup(String property)

    Same as above but only error messages for a specific property
    are included. 




Category: ActionForm
--------------------

Struts has support to parse incoming HTTP requests and stick the available
request parameter into a bean. The Struts config file defines what bean
class to use for a particular request. Additionally, a hook allows the 
application developer to include form validation code. The form bean is
passed around as an attribute to the servlet request. 


public ActionForm getActionForm()

    Retrieve and return the ActionForm bean associated with this mapping.
    The ActionForm is typically needed by the view designer to populate
    HTML form elements with values.
    
    


Category: Miscellaneous
-----------------------

public Locale getLocale()

    Retrieve and return the Locale for the user. If a Locale is
    not found, the default locale is returned. Note: Struts' Locale 
    is not request.getLocale().
    
    
-------------------------------------------------------------------------------



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Nathan Bubna <na...@esha.com>.
[...]
> > I propose this:
> >
> > public HashMap errors()
> > public HashMap errors(String property)
> >
> > It is close to what you had but avoids the prefix magic. Agree?
>
> yeah.  i'm not very into the ErrorMap/PREFIX hack myself.  i basically
said
> as much in my comments in MessageTool.  You also make a good point about
> having people being able to do something like:

[snipped out bad idea]

> but this is untested and off the top of my head, what do you think?

d'oh! i think i need to go back to bed, the top of my head isn't working too
well this morning.  a HashMap should work just fine, thank you very much and
have a nice day.

[...]

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 1] er... Phase 2.. i think.

Posted by Nathan Bubna <na...@esha.com>.
[snip]
> Nathan,
> what I propose is really very very similar to want you just describe. With
> my proposed approach the above link could be written as
>
> <a
href="$link.setPath($url.forward("login")).addQueryData('action','checkAuth'
)">Login</a>
>
> The added benefit is that the link tool stays general purpose and can
> be used with or without Struts. It this really "extremly annoying"?

:-) yeah...  seriously, it would really bug me to have to do that.  and
since nothing is in stone yet, this is the time to be really picky, is it
not?  i really don't see sufficient reason to split such closely related
functions into two seperate tools, and i think to do so will come across as
confusing and clumsy to people using it (it sorta does to me already).  it
needn't be that complicated. (14 extra keystrokes and dealing w/two separate
tools)

> If we combine all the features of your proposed link tool with the
forward,
> action and baseRef methods of Struts, we would need another link tool that
is not
> strut-ified, thereby duplicating some functionality. I think there is some
> value in having tools that are orthogonal to each other.

yes, this is something to consider... we should not go around haphazardly
duplicating code, but i think this may be a situation where it makes sense
to do so.  I think it will be fine to keep a copy of the basic LinkTool in
the velocity-tools-view subproject (if anyone wants it there) and to have a
StrutsLinkTool in the velstruts package.  Ideally, we would be able to have
the StrutsLinkTool extend the LinkTool, but given the nature of LinkTool's
behaviour (instances are immutable and 'mutator' methods return new
instances) that would be ridiculous.  So, while you'll normally find me
against maintaining two copies of mostly identical code, this is an
exception.  Besides, since it only deals with URLs, the underlying code in
LinkTool should be extremely stable, so we should rarely (if ever) have to
worry about keeping the two classes in sync (or in backstreet boys :-P).

> Additionally, in many practical cases, the forward, action and baseRef
methods
> are used without adding query parameter explicitely (forms add the
parameters
> automatically, baseRefs don't need parameters.) I am just finishing a
Struts
> application where I never had the need to add query parameter explicitely.
I
> worked with hidden form fields, instead. Those can be manipulated in
JavaScript.
> This add to my believe that the synergies of a combined tool are not as
big
> as it might seem at first.

if you want to convince me of something, it's usually not a good idea to
discuss using things like JavaScript. :-)  maybe i'll be less averse to such
things when browser implementations are all standardized, but i doubt i'll
live to see that day! :-P

anyway, you're right that query data probably won't often be needed all that
often, but there are reasonable situations where it will be wanted, and to
do what you suggest even once is hack to me.  and though it's use may be
more or less infrequent, i feel it is something we should support with out
resorting to such a, in my opinion, hack solution.

> Makes any sense to you? Any opinions from others?

yeah, anyone else care to weigh in on this stuff?  or is it just me and gabe
out here talking to ourselves?

Nathan Bubna
nathan@esha.com



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 1]

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:
> 
> definitely making progress...
> 
> [snip]
> > - Removed all query parameter from the method forwardURL(). The
> recommended
> > way is to use a context tools like Nathan's proposed LinkTool to achieve
> this.
> > See notes and example at the end of that section. Since the LinkTool makes
> > sense with and without Struts, I don't want to add all its functionality
> > to the Struts tool(s) but rather keep it as a separate tool.
> 
> hmm.
> 
> [snip]
> > Note:
> > If you need to append query data to the URLs created with above methods,
> > it is recommended to use a context tool like Nathan's proposed LinkTool.
> > Using LinkTool, adding query parameters would works the following way:
> >
> > #set( $foolink = $link.setPath($struts.forward("login")) )
> > <a href="$foolink.addQueryData("action", "checkAuth")">Login</a>
> 
> this note is kinda sliding into phase 2 already, but we're pretty close to
> that anyway, so i don't think it'll hurt to comment on it...
> 
> i don't propose using my LinkTool in any fashion resembling the VTL above.
> i think the path, action, forward, query data, etc.  all needs to be part of
> the same tool.   the VTL above would become extremely annoying if we had to
> do that for every link w/query data.  i would prefer to see a velstruts
> specific version of LinkTool  that includes a setAction(String) and
> forward(String)  that behave in similar fashion to LinkTool.setPath(String).
> that way a link w/query data is as simple as
> 
> <a href="$link.forward('login').addQueryData('action','checkAuth')">Login</a>
>

Nathan,
what I propose is really very very similar to want you just describe. With
my proposed approach the above link could be written as

<a href="$link.setPath($url.forward("login")).addQueryData('action','checkAuth')">Login</a>

The added benefit is that the link tool stays general purpose and can
be used with or without Struts. It this really "extremly annoying"? 

If we combine all the features of your proposed link tool with the forward, 
action and baseRef methods of Struts, we would need another link tool that is not
strut-ified, thereby duplicating some functionality. I think there is some 
value in having tools that are orthogonal to each other. 

Additionally, in many practical cases, the forward, action and baseRef methods 
are used without adding query parameter explicitely (forms add the parameters 
automatically, baseRefs don't need parameters.) I am just finishing a Struts 
application where I never had the need to add query parameter explicitely. I 
worked with hidden form fields, instead. Those can be manipulated in JavaScript.
This add to my believe that the synergies of a combined tool are not as big
as it might seem at first.

Makes any sense to you? Any opinions from others?

Gabe

> 
> Nathan Bubna
> nathan@esha.com

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 1]

Posted by Nathan Bubna <na...@esha.com>.
definitely making progress...

[snip]
> - Removed all query parameter from the method forwardURL(). The
recommended
> way is to use a context tools like Nathan's proposed LinkTool to achieve
this.
> See notes and example at the end of that section. Since the LinkTool makes
> sense with and without Struts, I don't want to add all its functionality
> to the Struts tool(s) but rather keep it as a separate tool.

hmm.

[snip]
> Note:
> If you need to append query data to the URLs created with above methods,
> it is recommended to use a context tool like Nathan's proposed LinkTool.
> Using LinkTool, adding query parameters would works the following way:
>
> #set( $foolink = $link.setPath($struts.forward("login")) )
> <a href="$foolink.addQueryData("action", "checkAuth")">Login</a>

this note is kinda sliding into phase 2 already, but we're pretty close to
that anyway, so i don't think it'll hurt to comment on it...

i don't propose using my LinkTool in any fashion resembling the VTL above.
i think the path, action, forward, query data, etc.  all needs to be part of
the same tool.   the VTL above would become extremely annoying if we had to
do that for every link w/query data.  i would prefer to see a velstruts
specific version of LinkTool  that includes a setAction(String) and
forward(String)  that behave in similar fashion to LinkTool.setPath(String).
that way a link w/query data is as simple as

<a
href="$link.forward('login').addQueryData('action','checkAuth')">Login</a>

it should be simple to modify LinkTool in such a way.  but to talk about
that would be slipping into phase 3....

Nathan Bubna
nathan@esha.com



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [VelTools] Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:
> 
> Gabriel Sidler wrote:
> > Hi,
> > I have consolidated all past discussions in phase 1 and phase 2
> > into this latest draft v0.4. Discard all previous drafts.
> >
> > I added a section 2) on auto-population of the context. This documents
> > objects that are made available automatically in the Velocity context.
> > It represents the status of the current prototype.
> >
> > I welcome any feedback.
> 
> +1 on everything.  i like where things are headed!

Ok, that's great.

I am working now on turning the draft into code, documentation and
examples. In the process I came across several minor things that seem 
suboptimal in the current draft. Expect some more details later this
week.

Gabe

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [VelTools] Velocity View API for Struts

Posted by Nathan Bubna <na...@esha.com>.
Gabriel Sidler wrote: 
> Hi,
> I have consolidated all past discussions in phase 1 and phase 2 
> into this latest draft v0.4. Discard all previous drafts.
> 
> I added a section 2) on auto-population of the context. This documents
> objects that are made available automatically in the Velocity context.
> It represents the status of the current prototype.
> 
> I welcome any feedback. 

+1 on everything.  i like where things are headed!
 
> From my point of view we are now pretty close to a stable version and
> can soon move to the design, implementation and documentation.
> 
> Gabe



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [VelTools] Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Hi,
I have consolidated all past discussions in phase 1 and phase 2 
into this latest draft v0.4. Discard all previous drafts.

I added a section 2) on auto-population of the context. This documents
objects that are made available automatically in the Velocity context.
It represents the status of the current prototype.

I welcome any feedback. 

>From my point of view we are now pretty close to a stable version and
can soon move to the design, implementation and documentation.

Gabe


-------------------------------------------------------------------------------

VELOCITY VIEW API FOR STRUTS
============================

Version 0.4, 22-Feb-2002


This document describes the Velocity View API for Struts.

1) Context Tools

2) Auto-Population of the Velocity Context




1) Context Tools
----------------

The following five context tools have been defined:

1.1) LinkTool - Support for working with hyper links, translation between logical
                names and the corresponding paths

1.2) MessageTool - Support for working with Struts message resources

1.3) ErrorsTool - Support for working with Struts error messages

1.4) ActionMessagesTool - Support for working with Struts action messages

1.5) FormTool - Support for working with HTML forms in templates



1.1) LinkTool
--------------

Struts supports a configurable level of indirection between the URL of a 
request and the handler of that request. For example, a URL of /main.do 
may be mapped by configuration to a handler class.
Furthermore, Struts knows the concept of 'forwards'. A 'forward' is a name
for a request target, such as a request handler or simply a web page. 
This configurable mapping of logical targets to actual targets allows
one to avoid hard-coded URLs in templates. All the logical links between
the different views of an application can be maintained in a configuration
file. 

The LinkTool provides methods to work with hyperlinks:

o translate logical names to real paths
o construct and encode query strings
o retrieve server, port and path info for the current request

Class: org.apache.velocity.tools.struts.LinkTool

Recommended name in context: $link

Methods:

public LinkTool setPath(String path)

    Returns a copy of this link with the given path setting.
    No conversions are applied to path.
    Note: It is Struts recommended practice to forward to
    actions or forwards, but not directly to templates as this
    bypassed the Struts controller. Consider using setAction() 
    or setForward() instead.


public LinkTool setAction(String action) 

    Returns a copy of this link with the given action name
    converted into a server-relative path (as per configuration
    in struts-config.xml).
    Example: 
    <form name="login" action='$link.setAction("login")'>
    produces something like
    <form name="login" action="/myapp/actions/loginaction">


public LinkTool setForward(String forward)

    Returns a copy of this link with the given forward name
    converted into a server-relative path (as per configuration
    in struts-config.xml).
    Example: 
    <a href='$link.setForward("home")'>Home</a>
    produces something like
    <a href="/myapp/templates/index.vm">Home</a>
        

public LinkTool setAbsolute(String path)

    Returns a copy of this link with the specified context-relative 
    path converted to an absolute path.
    Example:
    <a href='$link.setAbsolute("/templates/login/index.vm")'></a>
    produces something like
    <a href="http://myserver:port/myapp/templates/login/index.vm">Login Page</a>
    

public LinkTool addQueryData(String key, Object value)

    Adds a key/value pair to the query data. This returns a new LinkTool 
    containing both a copy of this LinkTool's query data and the new data.
    This makes repeated use in Velocity templates much easy. Query data is
    URL encoded before it is appended.


public String getPath()

    Returns the current path set for this link as set by
    the methods setPath(), setAction(), setForward() or
    setAbsolute(). Any conversions have been applied.
    

public String getQueryData()

    Returns this link's query data as an url-encoded string
    e.g. "key=value&foo=this+is+encoded".


public String getServerPath()

    Returns the server & context url, e.g. "http://myserver.net/myapp".


public String getBaseRef()

    Returns a full reference to the template without any query data.
    e.g. "http://myserver.net/myapp/stuff/View.vm"
    NOTE! This returns that base ref of the last request. This will NOT 
    represent any path or query data set for this LinkTool! A typical 
    application of this is with the HTML base tag.
    e.g. <base href="$tool.baseRef">


public String toString()

    Returns the full URL that's been built with this tool
    e.g. "http://myserver.net/myapp/stuff/View.vm?id=42&type=blue"
    Typically it is not necessary to call this method explicitely.
    Velocity will call the toString() method automatically to 
    obtain a representable version of this object.



1.2) MessageTool
----------------

Struts supports internationalized messages. The messages are stored
in NVP files by language. The following methods operate on these message 
files.

Class: org.apache.velocity.tools.struts.MessageTool

Recommended name in context: $msg

Methods:

public String get(String key)

    Return the localized message for the specified key.
    Example:
    <input type="submit" name="newbutton" value='$msg.newpatient'/>
    looks up a message with key="newpatient" and renders something like
    <input type="submit" name="newbutton" value='Register new patient'/>


public String get(String key, Object args[])

    Same as above, but supports parametric message strings, for example
    for a message resource defined as:
    warning.quota=Your mail folder is {0} MB above the limit of {1} MB.
    {0} and {1} are replaced by the values passed. Up to five replacement 
    parameters are supported.


public boolean exists(String key)

    Return true if a message string for the specified message key
    is present for the user's Locale.


public Locale getLocale()

    Retrieve and return the Locale for the user. If a Locale is
    not found, the default locale is returned. Note: Struts' locale 
    is not request.getLocale().
    


1.3) ErrorsTool
---------------

Errors may stem from the validation of a submitted form or from the 
processing of the request. If there are errors, they are made available
to the view to render. A few aspects about errors are:
o Error message strings are looked up in the message resources. Support 
  for internationalized messages is provided.
o Error messages can have up to five replacement parameters.
o Errors have a property that marks them as either 'global errors' (meaning 
  that they apply to an entire form) or 'specific errors' (meaning that they 
  are specific to one of the form elements). This allows to position error 
  messages precisely where the error occurred on the form.

Class: org.apache.velocity.tools.struts.ErrorsTool

Recommended name in context: $errors

Methods:

public boolean exist() 

    Returns true if there are errors queued, otherwise false.


public int getSize() 

    Returns the number of error messages queued.


public int getSize(String property) 

    Returns the number of error messages queued for a particular property.


public HashMap getAll() 

    Returns a HashMap of localized error messages for all errors queued. 
    A typical application would use a script similar to the following to 
    output the error messages.
    Example:
    <ul>
    #foreach ($e in $errors.all )
      <li>$e</li>
    #end
    </ul>


public HashMap get(String property) 

    Same as above but only the error messages for a particular property 
    are retrieved and returned.


Note:
To output a fully formatted error message similar to what the JSP tag 
html:errors does, it is recommended to utilize a VelociMacro. The 
following VelociMacro produces the same output as the html:errors JSP
tag:

#macro ( errorMarkup )
    #if ($errors.exist )
        <ul>
        #foreach ($e in $errors.all )
            <li>$e</li>
        #end
        </ul>
    #end
#end

The following macro generates error markup for a particular property:

#macro ( errorMarkup $property)
    #if ($errors.exist($property) )
        <ul>
        #foreach ($e in $errors.get($property) )
            <li>$e</li>
        #end
        </ul>
    #end
#end



1.4 ActionMessagesTool
----------------------

Action messages generalize the concept of error messages to include 
all kinds of messages that an action might want to pass to the view.
So, every error message is an action message, but not every action
message is an error message. The set of methods are the same as for
handling error messages. Note: Action messages are not to be confused
with the message resources used for internationalized output.

Action messages are new in Struts 1.1. This tool will not work with
Struts versions prior to 1.1.

Class: org.apache.velocity.tools.struts.ActionMessagesTool

Recommended name in context: $actionmsgs

Methods: 

public boolean exist();

    Returns true if there are messages (stored under MESSAGE_KEY) OR
    errors (stored under ERROR_KEY) queued, otherwise false.


public int getSize();

    Returns the total number of messages and errors (stored under MESSAGE_KEY
    and ERROR_KEY).


public int getSize(String property);

    Returns the total number of messages and errors (stored under MESSAGE_KEY
    and ERROR_KEY) for the specified property.


public HashMap getAll();

    Returns a HashMap of localized messages and error messages (stored under
    MESSAGE_KEY and ERROR_KEY). 


public HashMap get(String property);

    Same as above but only messages and error for a particular property
    are returned.


Examples:

To output all queued action messages:
#if ($actionmsgs.exist() )
    <p>There are $actionmsgs.size() messages.</p>    
    <ul>
    #foreach ($m in $actionmsgs.all() )
        <li>$m</li>
    #end
    </ul>
#end

To output all queued action messages for a specific property 'password':
#if ($actionmsgs.exist("password") )
    <ul>
    #foreach ($m in $actionmsgs.password )
        <li>$m</li>
    #end
    </ul>
#end



1.5) FormTool
-------------

Struts has support to parse incoming HTTP requests and populate a Java bean
with the submitted request parameters. The Struts config file defines what 
bean class to use for a particular request. Additionally, a hook allows the 
application developer to include form validation code. The form bean is passed 
around as an attribute to the servlet request. 

FormTool provides miscellaneous methods to work with forms.

Class: org.apache.velocity.tools.struts.FormTool

Recommended name in context: $form

Methods:

public ActionForm getBean()

    Retrieve and return the form bean associated with this request. The 
    ActionForm is typically needed by view designers to populate HTML form 
    elements with values.
    Note that the form bean is available in the Velocity context by default 
    under the name defined in the Struts configuration. If the form bean
    is used repeatedly, it is recommended to create a local variable pointing
    to the bean rather than calling getBean() on each access.
    Example:
    #set ($defaults = $form.bean) 
    <input type="text" name="username" value="$defaults.username">    


public String getCancelName() 

    Retrieve and return the magic name that is to be used for cancel buttons
    in HTML forms. If this magic name is used for cancel buttons, the 
    automatic form validation is skipped if the cancel button caused the form
    submission. If automatic form validation is not used, this is irrelevant.
    

public String getToken()

    Retrieve and return the transaction control token for this session.




2) Auto-Population of the Velocity Context
------------------------------------------

VelocityViewServlet is the servlet class that is used with Struts applications
to process Velocity templates. It can be considered the equivalent of the 
JSPServlet for Velocity templates.

VelocityViewServlet automatically populates the Velocity context with several
objects that are relevant to the template designer. This includes for example
servlet request, servlet response, servlet context, etc. This section documents
all objects that are made available automatically in the Velocity context. This
is part of the view API that is available to the template designer.

Strictly speaking, auto-population of the Velocity context is not specific to 
Struts. It can be used with any servlet-based application. I describe it here, 
because Struts is the first framework that makes use of VelocityViewServlet and 
this information has not been documented anywhere yet. It will be part of a
user guide in the future.



2.1) Request, Response, Session, Servlet Context
------------------------------------------------

The following objects are added to the Velocity context:

Name            Class / Interface
--------------|----------------------------------------------------------------
$request        javax.servlet.http.HttpServletRequest

$session        javax.servlet.http.HttpSession

$response       javax.servlet.http.HttpServletResponse

$application    javax.servlet.ServletContext



2.2) Attributes of Request, Session and Servlet Context
-------------------------------------------------------

The classes HttpServletRequest, HttpSession and ServletRequest support 
attributes (see methods getAttribute(), setAttributes() of these 
classes). This allows to associated arbitrary objects with the request, 
session or servlet context. These attributes have been foreseen to provide 
the application developer a mechanism to pass information between servlets.
Struts and other web frameworks make heavy use of these attributes to
pass data from the controller to the view of an application. 

VelocityViewServlet makes all attributes of request, session and servlet
context automatically available as variables in the Velocity context. The
key of an attribute is used as the name of the variable in the Velocity 
context.
Since request attributes, session attributes and servlet context attributes 
each have their own name space, name clashes are possible. The following 
lookup priorities apply when accessing a variable:

    1) Search local Velocity context
    
    2) Search request attributes
    
    3) Search session attributes
    
    4) Search servlet context attributes
    

Example:


In Struts action class:

    ArrayList[] orders = <result of DB lookup>
    request.setAttribute("orders", orders);
    ...
    
In Velocity template:

    ## $orders is automatically available in the context
    #foreach ($o in $orders)
        $o.amount: $o.text
    #end



-------------------------------------------------------------------------------





Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [VelTools] Velocity View API for Struts [Phase 2]

Posted by Nathan Bubna <na...@esha.com>.
Gabriel Sidler wrote:
> Nathan Bubna wrote:
> [..]
> > > Any better ideas are highly welcome.
> >
> > did you give any thought to my suggestion of renaming the context key
for
> > MessageTool instead of the one for ActionMessagesTool?  my suggestion
was to
> > change '$msg' to '$i18n' or '$text' (or something better if someone
thinks
> > of one) and to let ActionMessagesTool keep '$msgs'.
> >
> > whaddaya think?
>
> Yes, I gave it some thought. The MessageTool will easily be the most used
> context tool in any Struts application. The correspoding JSP tag is
<bean:message .../>
> In contrast, ActionMessages is new. Noboby is using it yet. So I'd rather
come up
> with some creative naming for action messages instead of for the well
established
> message resources.

good point.

> I actually begin to like your proposed $actionmsgs. Message tool ($msg)
typically
> will be used many times a page. Keeping it short is good. $actionmsgs
typically is
> used once per template. Having a slightly longer name is not an issue. The
> potential for confusion between $msg and $actionmsgs is small.

even better point.

> I propose that we go with these names for now. We can always come back and
> change later.

very true.

+1

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [VelTools] Velocity View API for Struts [Phase 2]

Posted by Ted Husted <hu...@apache.org>.
The messages and errors are very closely related. The messages tag and
corresponding queue were really only invented to maintain backward
compatibility. We didn't want to change the behavior of the errors tag,
so we created another. It also gives people a way to send two streams of
application-generated messages to a page, one for errors and one for
confirmations. 

You might want to think of them as queues or batches. 

It is also important to note that the ActionMessage has been in the
nightly build for some time, and many people *are* actually using the
night build in production. 

Also, the errors and messages queues have options that associate a
particular message with a particular property, and people often use this
feature to display the error next to the property, rather than in a
lump.

-Ted.


Gabriel Sidler wrote:
> Yes, I gave it some thought. The MessageTool will easily be the most used
> context tool in any Struts application. The correspoding JSP tag is <bean:message .../>
> In contrast, ActionMessages is new. Noboby is using it yet. So I'd rather come up
> with some creative naming for action messages instead of for the well established
> message resources.
> 
> I actually begin to like your proposed $actionmsgs. Message tool ($msg) typically
> will be used many times a page. Keeping it short is good. $actionmsgs typically is
> used once per template. Having a slightly longer name is not an issue. The
> potential for confusion between $msg and $actionmsgs is small.
> 
> I propose that we go with these names for now. We can always come back and
> change later.
> 
> Gabe
> 
> >
> > Nathan Bubna
> > nathan@esha.com
> >
> > --
> > To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> > For additional commands, e-mail: <ma...@jakarta.apache.org>
> 
> --
> Gabriel Sidler
> Software Engineer, Eivycom GmbH, Zurich, Switzerland
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [VelTools] Velocity View API for Struts [Phase 2]

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:
[..]
> > Any better ideas are highly welcome.
> 
> did you give any thought to my suggestion of renaming the context key for
> MessageTool instead of the one for ActionMessagesTool?  my suggestion was to
> change '$msg' to '$i18n' or '$text' (or something better if someone thinks
> of one) and to let ActionMessagesTool keep '$msgs'.
>
> whaddaya think?

Yes, I gave it some thought. The MessageTool will easily be the most used
context tool in any Struts application. The correspoding JSP tag is <bean:message .../>
In contrast, ActionMessages is new. Noboby is using it yet. So I'd rather come up
with some creative naming for action messages instead of for the well established
message resources.

I actually begin to like your proposed $actionmsgs. Message tool ($msg) typically 
will be used many times a page. Keeping it short is good. $actionmsgs typically is 
used once per template. Having a slightly longer name is not an issue. The 
potential for confusion between $msg and $actionmsgs is small.

I propose that we go with these names for now. We can always come back and 
change later.

Gabe




> 
> Nathan Bubna
> nathan@esha.com
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Nathan Bubna <na...@esha.com>.
Gabriel Sidler said:
> $actionmsgs

this is my favorite of the suggestions...  but what about keeping '$msgs'
and changing '$msg' to something else?  (see below for more on that)

> $meldungen - switching language adds a new dimension :-)

heh.  that's cool.

> I guess my favorite so far is $amessages. It's somewhat special, so people
will take
> note. Once they get the meaning of the word it should be easy to remember.
Few
> developers use action messages at the moment.

it's not bad, but i don't think we need 'messages' when 'msgs' says enough,
and i like 'action' better than 'a', because it will be clearer that we mean
"action messages" rather than "a messages".

> The class name of the tool is not sensitive, because it's used once. So, I
would
> propose:
>
> org.apache.velocity.tools.struts.ActionMessagesTool

+1

> Any better ideas are highly welcome.

did you give any thought to my suggestion of renaming the context key for
MessageTool instead of the one for ActionMessagesTool?  my suggestion was to
change '$msg' to '$i18n' or '$text' (or something better if someone thinks
of one) and to let ActionMessagesTool keep '$msgs'.

whaddaya think?

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:
[..]
> > Tool 4) Action Messages
> > -----------------------
> >
> > Class: org.apache.velocity.tools.struts.MessagesTool
> >
> > Recommended name in context: msgs
> >
> > Methods:
> >
> >     public boolean exists();
> >
> >     public int getSize();
> >
> >     public int getSize(String property);
> >
> >     public HashMap getAll();
> >
> >     public HashMap get(String property);
> 
> ok, now i'm confused.  we can't have two classes named
> org.apache.velocity.tools.struts.MessagesTool  and i don't like the idea of
> having both  a $msg  and $msgs in the context.  that's just asking for trouble.  

One of the remaining issues was to find a clever context name for Action messages 
to avoid confusion with the message resources (named $msg in the context).

Some brainstorming yielded:

$messages - easily confused with $msg
$amessages
$actionmessages - too long
$amsg
$amsgs
$am
$actionmsgs
$actionmsg
$actionm
$meldungen - switching language adds a new dimension :-)
$infos
$notes

I guess my favorite so far is $amessages. It's somewhat special, so people will take 
note. Once they get the meaning of the word it should be easy to remember. Few 
developers use action messages at the moment. 

The class name of the tool is not sensitive, because it's used once. So, I would
propose:

org.apache.velocity.tools.struts.ActionMessagesTool


Any better ideas are highly welcome.

Gabe


--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Nathan Bubna <na...@esha.com>.
> Jim Seach wrote:
> [...]
> > Since it's exposing the form values, why not use:
> >
> >     public ActionForm getValue()
> >
> > This might be more descriptive.  we are exposing it in the view, and
> > designers might not have a clue what a JavaBean is.   That would give
> > us:
> >
> > <input type="text" name="username" value="$form.value.username">
>
> Well, I am not fully sold on it.

me neither.  it feels like a very misleading name to me.

> How about:
>
> public ActionForm getValues()    // note the 's' to emphasize that
>                                      // we retrieve multiple values

definitely better than getValue().  i could live with this i guess, but i
still don't feel it is quite as accurately descriptive as getBean().   we
are after all returning a single object that is not a collection (List, Map,
array, etc).  I don't want designers to get the idea that they could do a
#foreach on it.    i do see that $form.values.username could be more
comfortable to a designer unfamiliar with the concept of javabeans, but i
don't think it's a big issue.  besides, even struts/jsp uses the term 'bean'
in its tags.  i doubt any designers will struggle with it.

> public ActionForm getFormBean()

blech. redundancy. -1

> Or, we rename the $form tool to $formtool and name the method getForm()
> This would make: $formtool.form to access the form.


blech again. -1


> Or, we just keep the getBean() Method. It should be easy for designers
> to get the concept.

+1 (but i can live with getValues() if i'm outnumbered on this one.)


Nathan Bubna
nathan@esha.com



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Gabriel Sidler <si...@teamup.ch>.
Jim Seach wrote:
[...]
> Since it's exposing the form values, why not use:
> 
>     public ActionForm getValue()
> 
> This might be more descriptive.  we are exposing it in the view, and
> designers might not have a clue what a JavaBean is.   That would give
> us:
> 
> <input type="text" name="username" value="$form.value.username">

Well, I am not fully sold on it.

How about:

public ActionForm getValues()    // note the 's' to emphasize that
                                     // we retrieve multiple values

public ActionForm getFormBean()


Or, we rename the $form tool to $formtool and name the method getForm()
This would make: $formtool.form to access the form.

Or, we just keep the getBean() Method. It should be easy for designers
to get the concept. 

I need to think a little more about it.


> > Note that the form bean is available in the request or session
> > attributes already. getBean() isn't really necessary. It just a
> > little
> > convenience. I kind of like it because if there is a method in the
> > API
> > this makes it explicit how to get a hold of the form bean.
> >
> 
> As you say, it's just a convenience, but what a convenient one!  I like
> it!

The form is in the context and can be accessed with the name that was
defined in struts-config.xml, eg

<input type="text" name="username" value="$loginForm.username">

So, the convenience offered by the getBean() method is really very minor.


Gabe


> 
> Jim Seach
> 
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Sports - Coverage of the 2002 Olympic Games
> http://sports.yahoo.com
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Jim Seach <jw...@yahoo.com>.
--- Gabriel Sidler <si...@teamup.ch> wrote:
> Nathan Bubna wrote:
> > 
> I just realize that getForm() is the wrong name anyway. What we are
> asking 
> for the not really the form but rather the bean that contains the
> values 
> entered/to be entered into the form. There may be multiple forms per
> template.
> So, getBean() would probably be a more accurate naming. How about
> this:
> 
>     public ActionForm getBean()
> 
> In a template this would look like this:
> 
> <input typ="text" name="username" value="$form.bean.username">
> 
> For efficiency the recommended use should be:
> 
> #set ($mybean = $form.bean)
> <input typ="text" name="username" value="$mybean.username">
> ...

Since it's exposing the form values, why not use:

    public ActionForm getValue()

This might be more descriptive.  we are exposing it in the view, and
designers might not have a clue what a JavaBean is.   That would give
us:

<input type="text" name="username" value="$form.value.username">


> 
> Note that the form bean is available in the request or session
> attributes already. getBean() isn't really necessary. It just a
> little
> convenience. I kind of like it because if there is a method in the
> API 
> this makes it explicit how to get a hold of the form bean. 
> 

As you say, it's just a convenience, but what a convenient one!  I like
it!

> 
> 
> Gabe
> 

Jim Seach

__________________________________________________
Do You Yahoo!?
Yahoo! Sports - Coverage of the 2002 Olympic Games
http://sports.yahoo.com

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Nathan Bubna <na...@esha.com>.
> > > Tool 4) Action Messages
> > > -----------------------
> > >
> > > Class: org.apache.velocity.tools.struts.MessagesTool
> > >
> > > Recommended name in context: msgs
[snip]
> Actually the classes are not the same. It's
> org.apache.velocity.tools.struts.MessageTool and
> org.apache.velocity.tools.struts.MessagesTool

oops. :-) see! i'm confused already!

> But I completely agree that it's confusing. I just didn't have a
> a good solution and was hoping that someone has. :-)

yeah i was hoping the same.  i'll try and think about it myself too...

> In Struts the corresponding JSP tags are
>
> <html:messages ... />
> <bean:message ... />
>
> ActionMessage is the super class of ActionError. It is supposed to
> generalize the concept of error messages to all possible types of
> messages an action might want to make available to the view, like
> for example notfifications, warnings, confirmations, etc. I believe
> ActionMessage is new in the upcoming 1.1 release.
>
> MessageResource (#2) is entirely different dispite the closeness in
> nameing. It's deals with internationalized strings from a bundle of
> NVP files.
>
> So, the challenge is to find a good naming to make the difference
> between action messages and message resources clear.

yeah, i think you're right.  most of my complaint was with the naming
similarities... although the relationship and functional similarity to
ActionErrors/ErrorsTool does make me wonder if there isn't some way to
connect/combine those with ActionMessages.  but, again, it's still fuzzy to
me.

so i guess i'd have to say that if 'MessagesTool' does stay on its own, then
i'd prefer naming the class ActionMessagesTool and finding some sufficiently
different suggestions for context keys.  $msg and $msgs will not do.  hmm.
maybe it's MessageTool's key that needs changed... what about $i18n instead
of $msg?  it's not as pretty, but it's a fairly accurate description.

> > > Tool 5) Action Form
> > > -------------------
> > >
> > > Class: org.apache.velocity.tools.struts.FormTool
[snip]
> That's an interesting idea, but I think it would be confusing. $form would
> look like the form bean itself, but it isn't. It is really a tool that
> provides methods to one *or* multiple forms in a template.

multiple forms, eh? hmm.  how would that work with getForm() or getBean()?
anyway, yeah, i agree the get(String s) trick would be misleading.  (but
still nifty... :-))

> I just realize that getForm() is the wrong name anyway. What we are asking
> for the not really the form but rather the bean that contains the values
> entered/to be entered into the form. There may be multiple forms per
template.
> So, getBean() would probably be a more accurate naming. How about this:
>
>     public ActionForm getBean()

+1  yeah, that's clear and accurate.

> Note that the form bean is available in the request or session
> attributes already. getBean() isn't really necessary. It just a little
> convenience. I kind of like it because if there is a method in the API
> this makes it explicit how to get a hold of the form bean.

heh. that's true...  still, i agree we should have this.

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan Bubna wrote:
> 
> hey Gabe, good stuff.  comments inline...


I'm glad we are getting closer to a good solution.



> > Tool 3) Error Handling
> > ----------------------
[...]
> +1  i like this much better than the way i did it.  only one suggestion...
> call the existence method 'exist()' instead of 'exists()'.  it's better
> grammar that way.

Good point. Will integrate into the next version.



> > Tool 4) Action Messages
> > -----------------------
> >
> > Class: org.apache.velocity.tools.struts.MessagesTool
> >
> > Recommended name in context: msgs
> >
> > Methods:
> >
> >     public boolean exists();
> >
> >     public int getSize();
> >
> >     public int getSize(String property);
> >
> >     public HashMap getAll();
> >
> >     public HashMap get(String property);
> 
> ok, now i'm confused.  we can't have two classes named
> org.apache.velocity.tools.struts.MessagesTool  and i don't like the idea of
> having both  a $msg  and $msgs in the context.  that's just asking for
> trouble.  of course, i'd like to propose some solution, but i'm still very
> hazy on this whole ActionMessages vs. ActionErrors deal, so i'm not much use
> here at the moment.  is there some way we can combine this into the
> ErrorsTool or maybe the MessageTool in #2?


Actually the classes are not the same. It's
org.apache.velocity.tools.struts.MessageTool and
org.apache.velocity.tools.struts.MessagesTool 

But I completely agree that it's confusing. I just didn't have a 
a good solution and was hoping that someone has. :-)

In Struts the corresponding JSP tags are 

<html:messages ... />
<bean:message ... />

ActionMessage is the super class of ActionError. It is supposed to 
generalize the concept of error messages to all possible types of
messages an action might want to make available to the view, like
for example notfifications, warnings, confirmations, etc. I believe
ActionMessage is new in the upcoming 1.1 release.

MessageResource (#2) is entirely different dispite the closeness in
nameing. It's deals with internationalized strings from a bundle of 
NVP files.

So, the challenge is to find a good naming to make the difference
between action messages and message resources clear.

I need to think more about this. Maybe Ted has a suggestion?


> > Tool 5) Action Form
> > -------------------
> >
> > Class: org.apache.velocity.tools.struts.FormTool
> >
> > Recommended name in context: form
> >
> > Methods:
> >
> >     public ActionForm getForm()      // was getActionForm()
> >
> >     public String getCancelName()    // was getCancelMagicName()
> >
> >     public String getToken()
> 
> +1 for the most part...
> i like grouping this stuff together.  i'm just not thrilled by the syntax.
> $form.token and $form.cancelName is good, but $form.form  is a little
> redundant.   here's a crazy idea for you...  what would you think about
> giving FormTool a get(String s) method that would then do a little
> velocity-style reflection on the ActionForm itself?   then we could do
> $form.foo instead of $form.form.foo.   i'm not sure i'm sold on the idea
> myself just yet, but it could be fun...

That's an interesting idea, but I think it would be confusing. $form would
look like the form bean itself, but it isn't. It is really a tool that 
provides methods to one *or* multiple forms in a template. 

I just realize that getForm() is the wrong name anyway. What we are asking 
for the not really the form but rather the bean that contains the values 
entered/to be entered into the form. There may be multiple forms per template.
So, getBean() would probably be a more accurate naming. How about this:

    public ActionForm getBean()

In a template this would look like this:

<input typ="text" name="username" value="$form.bean.username">

For efficiency the recommended use should be:

#set ($mybean = $form.bean)
<input typ="text" name="username" value="$mybean.username">
...

Note that the form bean is available in the request or session
attributes already. getBean() isn't really necessary. It just a little
convenience. I kind of like it because if there is a method in the API 
this makes it explicit how to get a hold of the form bean. 



Gabe


> 
> Nathan Bubna
> nathan@esha.com
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Nathan Bubna <na...@esha.com>.
hey Gabe, good stuff.  comments inline...

> --------------------------------------------------------------------------
-----
> PROPOSAL
>
> Context Tools for Velocity for Struts, Phase 2
> ----------------------------------------------
>
>
> Tool 1) Handling of URLs
> ------------------------

sounds good! +1

>
> Tool 2) Message Resources
> -------------------------
>
> Class: org.apache.velocity.tools.struts.MessageTool
>
> Recommended name in context: msg

i like this a lot!  ...but i'm not sure how this works
with/against/over/around/under/through the ActionMessages stuff in #4.  see
below.


> Tool 3) Error Handling
> ----------------------
>
> Class: org.apache.velocity.tools.struts.ErrorsTool
>
> Recommended name in context: errors
>
> Methods:
>
>     public boolean exists()
>
>     public int getSize()
>
>     public int getSize(String property)
>
>     public HashMap getAll()
>
>     public HashMap get(String property)

+1  i like this much better than the way i did it.  only one suggestion...
call the existence method 'exist()' instead of 'exists()'.  it's better
grammar that way.


> Tool 4) Action Messages
> -----------------------
>
> Class: org.apache.velocity.tools.struts.MessagesTool
>
> Recommended name in context: msgs
>
> Methods:
>
>     public boolean exists();
>
>     public int getSize();
>
>     public int getSize(String property);
>
>     public HashMap getAll();
>
>     public HashMap get(String property);

ok, now i'm confused.  we can't have two classes named
org.apache.velocity.tools.struts.MessagesTool  and i don't like the idea of
having both  a $msg  and $msgs in the context.  that's just asking for
trouble.  of course, i'd like to propose some solution, but i'm still very
hazy on this whole ActionMessages vs. ActionErrors deal, so i'm not much use
here at the moment.  is there some way we can combine this into the
ErrorsTool or maybe the MessageTool in #2?


> Tool 5) Action Form
> -------------------
>
> Class: org.apache.velocity.tools.struts.FormTool
>
> Recommended name in context: form
>
> Methods:
>
>     public ActionForm getForm()      // was getActionForm()
>
>     public String getCancelName()    // was getCancelMagicName()
>
>     public String getToken()

+1 for the most part...
i like grouping this stuff together.  i'm just not thrilled by the syntax.
$form.token and $form.cancelName is good, but $form.form  is a little
redundant.   here's a crazy idea for you...  what would you think about
giving FormTool a get(String s) method that would then do a little
velocity-style reflection on the ActionForm itself?   then we could do
$form.foo instead of $form.form.foo.   i'm not sure i'm sold on the idea
myself just yet, but it could be fun...

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 2/20/02 6:53 AM, "Gabriel Sidler" <si...@teamup.ch> wrote:

> "Geir Magnusson Jr." wrote:
>> 
>> By my clock, Phase 1 had a review period of 41 minutes.  :)
> 

Sorry.  39 minutes.  Wouldn't want to tarnish your reputation.

> Our slogan is: "Speed innovation to market" :-)

Why not make it " Speed innovation market" and save some time there too...
 
> Seriously, the latest draft 0.3 of phase 1 includes only minor
> changes on the handling of URLs. I documented what I believe
> is the latest concensus.
> 
> I put out a proposal on phase 2 to speed up the process a little
> bit. Don't let this stop you from commenting on phase 1. We'll
> make iterations of necessary.

I'm just so far behind...  Don't let my concerns stop you, but others might
want a read :)

Speed innovation market!

geir
 
> Gabe
> 
> 
>> 
>> I'll try to catch up...
>> 
>> On 2/20/02 6:40 AM, "Gabriel Sidler" <si...@teamup.ch> wrote:
>> 
>>> Hi,
>>> based on the output of phase 1 I put together a proposal on how to
>>> divide the functionality into context tools and how to name the methods.
>> 
>> [SNIP]
>> 
>> --
>> Geir Magnusson Jr.                                     geirm@optonline.net
>> System and Software Consulting
>> "He who throws mud only loses ground." - Fat Albert
>> 
>> --
>> To unsubscribe, e-mail:
>> <ma...@jakarta.apache.org>
>> For additional commands, e-mail:
>> <ma...@jakarta.apache.org>
> 
> --
> Gabriel Sidler
> Software Engineer, Eivycom GmbH, Zurich, Switzerland
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 

-- 
Geir Magnusson Jr.                                     geirm@optonline.net
System and Software Consulting
"They that can give up essential liberty to obtain a little temporary safety
deserve neither liberty nor safety." - Benjamin Franklin



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Gabriel Sidler <si...@teamup.ch>.
"Geir Magnusson Jr." wrote:
> 
> By my clock, Phase 1 had a review period of 41 minutes.  :)

Our slogan is: "Speed innovation to market" :-)

Seriously, the latest draft 0.3 of phase 1 includes only minor
changes on the handling of URLs. I documented what I believe
is the latest concensus. 

I put out a proposal on phase 2 to speed up the process a little
bit. Don't let this stop you from commenting on phase 1. We'll 
make iterations of necessary.

Gabe


> 
> I'll try to catch up...
> 
> On 2/20/02 6:40 AM, "Gabriel Sidler" <si...@teamup.ch> wrote:
> 
> > Hi,
> > based on the output of phase 1 I put together a proposal on how to
> > divide the functionality into context tools and how to name the methods.
> 
> [SNIP]
> 
> --
> Geir Magnusson Jr.                                     geirm@optonline.net
> System and Software Consulting
> "He who throws mud only loses ground." - Fat Albert
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
By my clock, Phase 1 had a review period of 41 minutes.  :)

I'll try to catch up...

On 2/20/02 6:40 AM, "Gabriel Sidler" <si...@teamup.ch> wrote:

> Hi, 
> based on the output of phase 1 I put together a proposal on how to
> divide the functionality into context tools and how to name the methods.

[SNIP]

-- 
Geir Magnusson Jr.                                     geirm@optonline.net
System and Software Consulting
"He who throws mud only loses ground." - Fat Albert


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 2]

Posted by Gabriel Sidler <si...@teamup.ch>.
Hi, 
based on the output of phase 1 I put together a proposal on how to 
divide the functionality into context tools and how to name the methods.
I grouped the functionality into 5 tools with related methods. Having
several tools leads to simpler methods names. 
I find this more elegant than having one tool with long decriptive method
names. I have added examples to give you an impression of how methods 
typically would be applied in a template.

I am looking forward to your feedback.

Gabe

PS: Please refer to version 0.3 of the API draft for more details about 
each method. I have not duplicated this information here.


-------------------------------------------------------------------------------
PROPOSAL

Context Tools for Velocity for Struts, Phase 2
----------------------------------------------


Tool 1) Handling of URLs
------------------------

Class: org.apache.velocity.tools.struts.LinkTool

Recommended name in context: link

Methods:

    public LinkTool setPath(String path)

    public LinkTool setAction(String action) 

    public LinkTool setForward(String forward)

    public LinkTool setAbsolute(String path)

    public LinkTool addQueryData(String key, Object value)

    public String getPath()

    public String getQueryData()

    public String getServerPath()

    public String getBaseRef()

    public String toString()

Examples:

    - A form action
    <form name="login" action='$link.setAction("login")'>
    produces something like
    <form name="login" action="/myapp/actions/loginaction">

    - A HREF with a forward
    <a href='$link.setForward("home")'>Home</a>
    produces something like
    <a href="/myapp/templates/index.vm">
        
    - A HREF with an absolute URL
    <a href='$link.setAbsolute("/templates/login/index.vm")'></a>
    produces something like
    <a href="http://myserver:port/myapp/templates/login/index.vm">Login Page</a>
   
    - Create a <base> tag    
    <base href="$link.baseRef()">
    produces something like
    <base href="/myapp/templates/login/index.vm">




Tool 2) Message Resources
-------------------------

Class: org.apache.velocity.tools.struts.MessageTool

Recommended name in context: msg

Methods:

    public String get(String key)

    public String get(String key, Object args[])

    public boolean exists(String key)
    
    public Locale getLocale()

Examples:

    - A simple internationalized output string
    $msg.login014     # equivalent to $msg.get("login014")

    - A submit button with an internationalized label
    <input type="submit" name="newbutton" value='$msg.get("view35.new")'/>
    renders something like
    <input type="submit" name="newbutton" value='Neuer Patient anmelden'/>




Tool 3) Error Handling
----------------------

Class: org.apache.velocity.tools.struts.ErrorsTool

Recommended name in context: errors

Methods:

    public boolean exists() 

    public int getSize() 

    public int getSize(String property) 

    public HashMap getAll() 

    public HashMap get(String property) 

Examples:

    - To output all queued error messages:
    #if ($errors.exists() )
        <p>There are $errors.size() errors. Please verify your input.</p>    
        <ul>
        #foreach ($e in $errors.all() )
            <li>$e</li>
        #end
        </ul>
    #end

    - To output all queued error messages for a specific property 'password':
    #if ($errors.exists() )
        <ul>
        #foreach ($e in $errors.password )
            <li>$e</li>
        #end
        </ul>
    #end





Tool 4) Action Messages
-----------------------

Class: org.apache.velocity.tools.struts.MessagesTool

Recommended name in context: msgs

Methods: 

    public boolean exists();

    public int getSize();

    public int getSize(String property);

    public HashMap getAll();

    public HashMap get(String property);

Examples:

    - To output all queued action messages:
    #if ($msgs.exists() )
        <p>There are $msgs.size() messages.</p>    
        <ul>
        #foreach ($m in $msgs.all() )
            <li>$m</li>
        #end
        </ul>
    #end

    - To output all queued action messages for a specific property 'password':
    #if ($msgss.exists() )
        <ul>
        #foreach ($m in $msgs.password )
            <li>$m</li>
        #end
        </ul>
    #end

    
 
Tool 5) Action Form
-------------------

Class: org.apache.velocity.tools.struts.FormTool

Recommended name in context: form

Methods:

    public ActionForm getForm()      // was getActionForm()
 
    public String getCancelName()    // was getCancelMagicName()
    
    public String getToken()

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 1]

Posted by Gabriel Sidler <si...@teamup.ch>.
Hi, this is version 0.3 of the Velocity View API for Struts.
Changes are limited to the first section "Handling of URLs".
I consider this now pretty close to final. This should not stop
you from commenting if you see something.

Changes in 0.3:

- Reworked the handling of URL to iron out some "extremly annoying"
behavoir :-). It works now along the lines of what Nathan proposed for 
the LinkTool.

Gabe


-------------------------------------------------------------------------------

VELOCITY VIEW API FOR STRUTS
============================

Version 0.3, 20-Feb-2002


Category: Handling of URLs
--------------------------

Struts supports a configurable level of indirection between the URLs of a 
request and the handler of that request. For example, a URL of /main.do 
may be mapped by configuration to a handler of class com.app.my.handler.
Futhermore, Struts knows the concept of 'forwards'. A 'forward' is a name
for a request target, such as a request handler or simply a web page. 

This configurable mapping of logical targets to actual targets allows
one to avoid hard-coded URLs in templates. All the logical links between
the different views of an application can be maintained in a configuration
file. The following three methods are used to maps logical names to actual
URLs. The remaining methods are related.


public LinkTool setPath(String path)

    Returns a copy of this link with the given path setting.
    No conversions are applied to path.
    Note: It is Struts recommended practice to forward to
    actions or forwards, but not directly to templates as this
    bypassed the Struts controller. Consider using setAction() 
    or setForward() instead.
    

public LinkTool setAction(String action) 

    Returns a copy of this link with the given action name
    converted into a server-relative path (as per configuration
    in struts-config.xml).
    Example: 
    <form name="login" action='$link.setAction("login")'>
    produces something like
    <form name="login" action="/myapp/actions/loginaction">


public LinkTool setForward(String forward)

    Returns a copy of this link with the given forward name
    converted into a server-relative path (as per configuration
    in struts-config.xml).
    Example: 
    <a href='$link.setForward("home")'>Home</a>
    produces something like
    <a href="/myapp/templates/index.vm">Home</a>
        

public LinkTool setAbsolute(String path)

    Returns a copy of this link with the specified 
    context-relative path converted to an absolute
    path.
    

public LinkTool addQueryData(String key, Object value)

    Adds key/value pair to the query data
    This returns a new LinkTool containing both
    a copy of this LinkTool's query data and the new data
    This makes repeated use in velocity templates much easier.
    Query data is URL encoded before it is appended.


public String getPath()

    Returns the current path set for this link as set by
    the methods setPath(), setAction(), setForward() or
    setAbsolute(). Any conversions have been applied.
    

public String getQueryData()

    Returns this link's query data as an url-encoded string
    e.g. "key=value&foo=this+is+encoded".


public String getServerPath()

    Returns the server & context url
    e.g. "http://myserver.net/myapp".


public String getBaseRef()

    Returns a full reference to the template without
    any query data.
    e.g. "http://myserver.net/myapp/stuff/View.vm"
    NOTE! This returns that base ref of the last request.
    This will NOT represent any path or query data
    set for this LinkTool! A typical application of 
    this is with the HTML base tag.
    e.g. <base href="$tool.baseRef">


public String toString()

    Returns the full URI that's been built with this tool
    e.g. "http://myserver.net/myapp/stuff/View.vm?id=42&type=blue"
    Typically it is not necessary to call this method explicitely.
    Velocity will call the toString() method automatically to 
    obtain a representable version of this object.



-- Nothing changed after here --


Category: Messages
------------------

Struts supports internationalized messages. The messages are stored
in NVP files by language. The following methods operate on these message 
files.


public String message(String key)

    Return the localized message for the specified key.
    Example:
    <input type="submit" name="newbutton" value='$tool.message("view35.new")'/>
    renders something like
    <input type="submit" name="newbutton" value='Neuer Patient anmelden'/>
    

public String message(String key, Object args[])

    Same as above, but supports parametric message strings, for example:
      warning.quota=Your mail folder is {0} MB above the limit of {1} MB.
    Up to five replacement parameters are supported.
    

public boolean isMessage(String key)

    Return true if a message string for the specified message key
    is present for the user's Locale.
    




Category: Error Handling
------------------------

Errors may stem from the validation of a submitted form or from the 
processing of the request. If there are errors, they are made available
to the view to output. A few aspects about errors are:
- Error messages are looked up in a bundle of messages resource files. Support 
for internationalized messages is provided.
- Error messages can have up to four replacement parameters.
- Errors have a property that marks them as 'global errors' (meaning that they
apply to the entire form) or 'specific errors' (meaning that they are specific
to one of the form elements). This allows to position error messages precisely 
where the error occured on the form.


public boolean hasErrors() 

    Returns true if there are errors queued, otherwise false.


public int errorSize() 

    Returns the number of error messages. 


public int errorSize(String property) 

    Returns the number of error messages for a particular property.
    

public HashMap errors() 

    Returns a HashMap of localized error messages. A typical application 
    would use a script similar to the following to output the error messages.
    Example:
    <ul>
    #foreach ($e in $tool.errors )
      <li>$e</li>
    #end
    </ul>


public HashMap errors(String property) 

    Same as above but only the error messages for a particular 
    property are retrieved and returned.



Note:
To output a fully formatted error message similar to what the JSP tag 
html:errors does, it is recommended to utilise a VelociMacro. The 
following example produces the same output that the html:errors JSP
tag does:

#macro ( errorMarkup )
    #if ($tool.hasErrors() )
        <ul>
        #foreach ($e in $tool.errors() )
            <li>$e.key()</li>
        #end
        </ul>
    #end
#end




Category: Action Messages
-------------------------
Action messages generalize the concept of error messages to include 
all kinds of messages that an action might want to pass to the view.
So, every error message is an action message, but not every action
message is an error message. The set of methods are the same as for
handling error messages. Note: Action messages are not to be confused
with the internationalized message strings. We need to find a good naming
scheme to make sure that people don't confuse it. 

Otherwise, same comments apply as to Error Messages above.
 

public boolean hasMessages();

    Returns true if there are messages (stored under MESSAGE_KEY) OR
    errors (stored under ERROR_KEY) queued, otherwise false.


public int messageSize();

    Returns the total number of messages and errors (stored under MESSAGE_KEY
    and ERROR_KEY).


public int messageSize(String property);

    Returns the total number of messages and errors (stored under MESSAGE_KEY
    and ERROR_KEY) for the specified property.


public HashMap messages();

    Returns a HashMap of localized messages and error messages (stored under
    MESSAGE_KEY and ERROR_KEY). 


public HashMap messages(String property);

    Same as above but only messages and error for a particular property
    are returned.
    
    
 


Category: ActionForm
--------------------

Struts has support to parse incoming HTTP requests and stick the available
request parameter into a bean. The Struts config file defines what bean
class to use for a particular request. Additionally, a hook allows the 
application developer to include form validation code. The form bean is
passed around as an attribute to the servlet request. 


public ActionForm getActionForm()

    Retrieve and return the ActionForm bean associated with this mapping.
    The ActionForm is typically needed by the view designer to populate
    HTML form elements with values.
    
    


Category: Miscellaneous
-----------------------

public Locale getLocale()

    Retrieve and return the Locale for the user. If a Locale is
    not found, the default locale is returned. Note: Struts' Locale 
    is not request.getLocale().
    

public String getToken()

    Retrieve and return the transaction control token for this session.
    
    
public String getCancelMagicName()    
    
    Retrieve and return the magic name that is to be used for cancel buttons
    in HTML forms. If this magic name is used for cancel buttons, the 
    automatic form validation is skipped. If automatic form validation is
    not used, this is irrelevant.
    
    
    
-------------------------------------------------------------------------------

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts [Phase 1]

Posted by Gabriel Sidler <si...@teamup.ch>.
Hi,
I have put all the discussed changes into a new draft. Thanks for all 
the feedback. I think we now have a much better API. You find a list
of changes just below. I would like to ask Ted to carefully look at what I
propose on the action messages. 

>From my point of view, this now concludes phase 1 (your feedback is still
welcome, of course). I am now going to work out a proposal for phase 2
(how to divide the functionality into tools, naming of methods).

Gabe



Changes:

- Added method getToken() to retrieve the transaction control token for the
current session. 

- Added method getCancelMagicName() to retrieve the string to be used for 
the name attribute of form cancel buttons if validation is enabled. (Input Ted)

- Remove methods errorMarkup(). The recommened way is to use a VelociMarcro.

- Changed the signatures of methods errors(...). They now return a HashMap.

- Removed all query parameter from the method forwardURL(). The recommended
way is to use a context tools like Nathan's proposed LinkTool to achieve this.
See notes and example at the end of that section. Since the LinkTool makes
sense with and without Struts, I don't want to add all its functionality
to the Struts tool(s) but rather keep it as a separate tool.

- Added set of methods to work with action messages (a new feature in the
upcoming Struts 1.1). See notes in the section. Still need some clarifications
from Ted.



-------------------------------------------------------------------------------

VELOCITY VIEW API FOR STRUTS
============================

Version 0.2, 18-Feb-2002


Category: Handling of URLs
--------------------------

Struts supports a configurable level of indirection between the URLs of a 
request and the handler of that request. For example, a URL of /main.do 
may be mapped by configuration to a handler of class com.app.my.handler.
Futhermore, Struts knows the concept of 'forwards'. A 'forward' is a name
for a request target, such as a request handler or simply a web page. 

This configurable mapping of logical targets to actual targets allows
one to avoid hard-coded URLs in templates. All the logical links between
the different views of an application can be maintained in a configuration
file. The following three methods are used to maps logical names to actual
URLs. The remaining methods are related.


public String actionURL(String action) 

    Converts the action name into a server-relative URL.
    Example: 
    <form name="login" action='$tool.actionURL("login")'>
    produces something like
    <form name="login" action="/myapp/actions/loginaction">


public String forwardURL(String forward)

    Converts the local or global forward into a server-relative URL.
    Example: 
    <a href='$tool.forwardURL("home")'>Home</a>
    produces something like
    <a href="/myapp/templates/index.vm">
        

public String absoluteURL(String path)

    Create and return an absolute URL for the specified context-relative
    path.
    
    
public String baseRef() 

    Renders the reference for a HTML <base> element.
    Example: 
    <base href="$tool.baseRef()">
    produces something like
    <base href="/myapp/template/view.vm">


Note: 
If you need to append query data to the URLs created with above methods, 
it is recommended to use a context tool like Nathan's proposed LinkTool.
Using LinkTool, adding query parameters would works the following way:

#set( $foolink = $link.setPath($struts.forward("login")) )
<a href="$foolink.addQueryData("action", "checkAuth")">Login</a>





Category: Messages
------------------

Struts supports internationalized messages. The messages are stored
in NVP files by language. The following methods operate on these message 
files.


public String message(String key)

    Return the localized message for the specified key.
    Example:
    <input type="submit" name="newbutton" value='$tool.message("view35.new")'/>
    renders something like
    <input type="submit" name="newbutton" value='Neuer Patient anmelden'/>
    

public String message(String key, Object args[])

    Same as above, but supports parametric message strings, for example:
      warning.quota=Your mail folder is {0} MB above the limit of {1} MB.
    Up to five replacement parameters are supported.
    

public boolean isMessage(String key)

    Return true if a message string for the specified message key
    is present for the user's Locale.
    




Category: Error Handling
------------------------

Errors may stem from the validation of a submitted form or from the 
processing of the request. If there are errors, they are made available
to the view to output. A few aspects about errors are:
- Error messages are looked up in a bundle of messages resource files. Support 
for internationalized messages is provided.
- Error messages can have up to four replacement parameters.
- Errors have a property that marks them as 'global errors' (meaning that they
apply to the entire form) or 'specific errors' (meaning that they are specific
to one of the form elements). This allows to position error messages precisely 
where the error occured on the form.


public boolean hasErrors() 

    Returns true if there are errors queued, otherwise false.


public int errorSize() 

    Returns the number of error messages. 


public int errorSize(String property) 

    Returns the number of error messages for a particular property.
    

public HashMap errors() 

    Returns a HashMap of localized error messages. A typical application 
    would use a script similar to the following to output the error messages.
    Example:
    <ul>
    #foreach ($e in $tool.errors )
      <li>$e</li>
    #end
    </ul>


public HashMap errors(String property) 

    Same as above but only the error messages for a particular 
    property are retrieved and returned.



Note:
To output a fully formatted error message similar to what the JSP tag 
html:errors does, it is recommended to utilise a VelociMacro. The 
following example produces the same output that the html:errors JSP
tag does:

#macro ( errorMarkup )
    #if ($tool.hasErrors() )
        <ul>
        #foreach ($e in $tool.errors() )
            <li>$e.key()</li>
        #end
        </ul>
    #end
#end




Category: Action Messages
-------------------------
Action messages generalize the concept of error messages to include 
all kinds of messages that an action might want to pass to the view.
So, every error message is an action message, but not every action
message is an error message. The set of methods are the same as for
handling error messages. Note: Action messages are not to be confused
with the internationalized message strings. We need to find a good naming
scheme to make sure that people don't confuse it. 

Otherwise, same comments apply as to Error Messages above.
 

public boolean hasMessages();

    Returns true if there are messages (stored under MESSAGE_KEY) OR
    errors (stored under ERROR_KEY) queued, otherwise false.


public int messageSize();

    Returns the total number of messages and errors (stored under MESSAGE_KEY
    and ERROR_KEY).


public int messageSize(String property);

    Returns the total number of messages and errors (stored under MESSAGE_KEY
    and ERROR_KEY) for the specified property.


public HashMap messages();

    Returns a HashMap of localized messages and error messages (stored under
    MESSAGE_KEY and ERROR_KEY). 


public HashMap messages(String property);

    Same as above but only messages and error for a particular property
    are returned.
    
    
 


Category: ActionForm
--------------------

Struts has support to parse incoming HTTP requests and stick the available
request parameter into a bean. The Struts config file defines what bean
class to use for a particular request. Additionally, a hook allows the 
application developer to include form validation code. The form bean is
passed around as an attribute to the servlet request. 


public ActionForm getActionForm()

    Retrieve and return the ActionForm bean associated with this mapping.
    The ActionForm is typically needed by the view designer to populate
    HTML form elements with values.
    
    


Category: Miscellaneous
-----------------------

public Locale getLocale()

    Retrieve and return the Locale for the user. If a Locale is
    not found, the default locale is returned. Note: Struts' Locale 
    is not request.getLocale().
    

public String getToken()

    Retrieve and return the transaction control token for this session.
    
    
public String getCancelMagicName()    
    
    Retrieve and return the magic name that is to be used for cancel buttons
    in HTML forms. If this magic name is used for cancel buttons, the 
    automatic form validation is skipped. If automatic form validation is
    not used, this is irrelevant.
    
    
    
-------------------------------------------------------------------------------




--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Nathan Bubna <na...@esha.com>.
> So, if nobody disagrees I propose that we give up on the idea of the
errorMarkup()
> method and instead propate the use of a Velocimacro for this case.

+1


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Ok, we are getting closer :-). See below.

Nathan Bubna wrote:
[...]
> hmm.  i guess i'm not totally clear on how the header and footer would be
> used.  does every individual error message get wrapped by the header and
> footer or does the header/footer wrap all the messages as a group?
> actually... i don't think it makes a difference.  i think i just went -1 on
> these methods.   unless i'm missing something, i don't see how this
> errorMarkup stuff is at all necessary.   if the header and footer wrap all
> the messages as a group, people should just do something like:
> 
> $msg.get('error.header')
> #foreach( $e in $tool.errors )
> $e <br>
> #end
> $msg.get('error.footer')

The existing errors tag in JSP does the equivalent of the following Velocity 
script:

#if ( errors.exist )
  $msg.get('error.header')
  #foreach( $e in $tool.errors )
    $e <br>
  #end
  $msg.get('error.footer')
#end


The errors tag is used frequently, typically once or serveral time per HTML
form there is. You certainly wouldn't want to repeat all the above code
all the time. Some automation is clearly needed.

Maybe this is a case where a Velocity macro is the right way to go? This would give
the designer most flexibility. We could ship some examples with the distribution.

So, if nobody disagrees I propose that we give up on the idea of the errorMarkup()
method and instead propate the use of a Velocimacro for this case.

Gabe





--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
I reckon :o)

Nathan Bubna wrote:
> Thanks for the explanation, Ted.  So, it would be correct to say that an
> 'errorOutput' method of sorts must remain in the ConfigHelper API, but would
> be extraneous in the Velocity/Struts API, right?


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Java Web Development with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Nathan Bubna <na...@esha.com>.
Thanks for the explanation, Ted.  So, it would be correct to say that an
'errorOutput' method of sorts must remain in the ConfigHelper API, but would
be extraneous in the Velocity/Struts API, right?

> Nathan Bubna wrote:
> > either way, the more i think about it, the more i think this whole
> > 'errorMarkup' idea is rendered completely unnecessary by Velocity.  or
am i
> > missing something?
>
> It relates to how the errors tag works in 1.0. There was just one tag
>
> <html:errors/>
>
> that could do all the work.
>
> In 1.1, there's a message tag that works more like you would expect.
>
> The Struts API bean would need to keep this method for backward
> compatability.
>
> My goal is to be able to have the Struts custom tags use the same API
> that we expect other presention layers to use. Sadly, not every
> presentation layer is as capable as Velocity :o)
>
>
> -- Ted Husted, Husted dot Com, Fairport NY USA.
> -- Java Web Development with Struts.
> -- Tel +1 585 737-3463.
> -- Web http://www.husted.com/struts/
>
> --
> To unsubscribe, e-mail:
<ma...@jakarta.apache.org>
> For additional commands, e-mail:
<ma...@jakarta.apache.org>
>
>


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
Nathan Bubna wrote:
> either way, the more i think about it, the more i think this whole
> 'errorMarkup' idea is rendered completely unnecessary by Velocity.  or am i
> missing something?

It relates to how the errors tag works in 1.0. There was just one tag 

<html:errors/>

that could do all the work. 

In 1.1, there's a message tag that works more like you would expect. 

The Struts API bean would need to keep this method for backward
compatability. 

My goal is to be able to have the Struts custom tags use the same API
that we expect other presention layers to use. Sadly, not every
presentation layer is as capable as Velocity :o)


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Java Web Development with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Nathan Bubna <na...@esha.com>.
> Nathan, thanks for the feedback. I have a few follow up questions. Would
> you please clarify.

will do.  read down.
...
> > So, i would prefer to see $urltool.forward(foo) and friends return a
> > instance of urltool so we can then call an addQueryData(key, value) on
it.
>
> Ok, makes sense. I'll integrate that in the next draft.

sweet.

> > > public int errorSize()
> > -1
> >
> > > public int errorSize(String property)
> >
> > -1
> >
...
> I saw that in your MessageTool.java and I basically agree. The reason I
left these
> two methods anyway was that errors() is a fairly expensive method whereas
> errorSize() is very cheap. errors() looks up all the message strings and
> does the parametric replacement operations. That's a lot of overhead if
you
> just need the number of messages.
>
> Makes sense?

that's a good point.  i'm still not thrilled to have them, but i think
that's just because i can't see myself using them independently of calling
errors(), but i can imagine scenarios where others might wish to do so.  so
if you see need for them, i'll back you up on it.  +1

> >
> > > public String[] errors()
> >
> > +1 on the functionality.  (but let's not return a String[].  I'd really
like
> > to see something closer to what MessageTool does here.)
>
> In your MessageTool you defined an internal class ErrorMap that is
returned. I didn't
> see the value of doing this. Can you elaborate on that? Specifically I
felt that
> the introduction of the PREFIX is too much magic behavior. It makes
assumptions about the
> keys of the error messages (in an application that I'm currently working
on all
> errors tags are numbered). I believe the typical way people would use the
errors()
> method is something like:
>
> <ul>
> #foreach ($e in $struts.errors())
>   <li>$e</li>
> #end
> </ul>
>
> What usage scenario did you have in mind?
>
> I propose this:
>
> public HashMap errors()
> public HashMap errors(String property)
>
> It is close to what you had but avoids the prefix magic. Agree?

yeah.  i'm not very into the ErrorMap/PREFIX hack myself.  i basically said
as much in my comments in MessageTool.  You also make a good point about
having people being able to do something like:

#foreach($e in $tool.errors)  $e <br> #end

that wouldn't work on a Map.  we'd have to use $tool.errors.values()
instead.  now, i know that's not a big difference, but we probably do better
to avoid it.  if i have to choose between a Map and a Set or List, i'd
choose Map,  but perhaps a custom class (mabye internal, maybe not) is in
order.   If I remember correctly, it's iterator() that Velocity looks for
when trying to loop over an object.   so something like this should handle
both cases:

public class ErrorMessages
{
    private HashMap map;

    public ErrorMessages()
    {
        map = new HashMap();
    }

    public void put(String key, String value)
    {
        map.put(key, value);
    }

    public String get(String key)
    {
        return (String)map.get(key);
    }

    public Iterator iterator()
    {
        return map.values().iterator();
    }
}

but this is untested and off the top of my head, what do you think?

> > > public String errorMarkup()
> >
> > +0  i'm not thrilled by it, but as long as all the actual markup is
pulled
> > from properties files under the view designer's control, i won't object.
> > But if i see ANY html or other markup stuck in the java, then i am
a -137 on
> > it.
>
> I fully agree with you here regarding the HTML in Java. That won't happen.
> An alternative could be that we allow footer and header as parameters.
That
> would be more explicit and less magic.
>
> public String errorMarkup(String footer, String header)
>
> What is better?

hmm.  i guess i'm not totally clear on how the header and footer would be
used.  does every individual error message get wrapped by the header and
footer or does the header/footer wrap all the messages as a group?
actually... i don't think it makes a difference.  i think i just went -1 on
these methods.   unless i'm missing something, i don't see how this
errorMarkup stuff is at all necessary.   if the header and footer wrap all
the messages as a group, people should just do something like:

$msg.get('error.header')
#foreach( $e in $tool.errors )
$e <br>
#end
$msg.get('error.footer')

of if wrapping each individually, something like:

#foreach( $e in $tool.errors )
$msg.get('error.header')
$e <br>
$msg.get('error.footer')
#end

either way, the more i think about it, the more i think this whole
'errorMarkup' idea is rendered completely unnecessary by Velocity.  or am i
missing something?

...

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Nathan, thanks for the feedback. I have a few follow up questions. Would
you please clarify.

Nathan Bubna wrote:
> 
> > public String forwardURL(String target, String parameters)
> >
> >     Same as above but appends the string parameters are the end of the
> URL.
> >     Example:
> >     <a href='$tool.forwardURL("home", "frames=no&style=simple")'>Home</a>
> >     produces something like
> >     <a href="/myapp/templates/index.vm?frames=no&style=simple">
> 
> -1
> 
> i think it would be far better to put the adding of query data in a separate
> method like the LinkTool i wrote does.  (of course, i don't think that
> LinkTool is good for the Struts/Velocity project because it lacks the
> methods above).  I have several reasons for wanting this:
> 1.  elegance.  imo this doesn't have it.  (ok, so that's pretty subjective,
> but the next one is serious.)
> 2.  URL encoding.  I wouldn't want a forward(target, params) method to have
> to parse and then encode the values, and i certainly don't want to have to
> do the encoding manually in templates.
> 3.  what if you want to append query data to an action or absolute URL?
> then we'd have to have xxxx(target, params) methods for those as well.
> 
> So, i would prefer to see $urltool.forward(foo) and friends return a
> instance of urltool so we can then call an addQueryData(key, value) on it.

Ok, makes sense. I'll integrate that in the next draft.


> > public int errorSize() 
> -1
> 
> > public int errorSize(String property)
> 
> -1
> 
> Ok, here's my thoughts on these last two...
> It's not that i object to having the functionality.  We DO need that, i'm
> just not convinced these are methods we need to clutter up the tool API
> with.  IMO  what we should aim for is to have the getErrors() or errors() or
> whatever methods return an object that has a size() method.  That way we can
> just use $tool.errors.size()   This would provide equal functionality and
> would keep needless clutter out of the tool.

I saw that in your MessageTool.java and I basically agree. The reason I left these 
two methods anyway was that errors() is a fairly expensive method whereas 
errorSize() is very cheap. errors() looks up all the message strings and
does the parametric replacement operations. That's a lot of overhead if you 
just need the number of messages.

Makes sense?

> 
> > public String[] errors()
> 
> +1 on the functionality.  (but let's not return a String[].  I'd really like
> to see something closer to what MessageTool does here.)

In your MessageTool you defined an internal class ErrorMap that is returned. I didn't
see the value of doing this. Can you elaborate on that? Specifically I felt that
the introduction of the PREFIX is too much magic behavior. It makes assumptions about the
keys of the error messages (in an application that I'm currently working on all
errors tags are numbered). I believe the typical way people would use the errors()
method is something like:

<ul>
#foreach ($e in $struts.errors())
  <li>$e</li>
#end
</ul>

What usage scenario did you have in mind?

I propose this:

public HashMap errors()
public HashMap errors(String property)

It is close to what you had but avoids the prefix magic. Agree?


> > public String errorMarkup()
> 
> +0  i'm not thrilled by it, but as long as all the actual markup is pulled
> from properties files under the view designer's control, i won't object.
> But if i see ANY html or other markup stuck in the java, then i am a -137 on
> it.

I fully agree with you here regarding the HTML in Java. That won't happen.
An alternative could be that we allow footer and header as parameters. That
would be more explicit and less magic.

public String errorMarkup(String footer, String header)

What is better? 




As soon as I have your feedback I draft up a revised version of the API and send
it around.

Gabe




--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Nathan Bubna <na...@esha.com>.
Sounds like a good plan so far Gabriel.
Since we're in phase 1, i guess this is the place for me to comment on the
methods being discussed and ignore the question of signatures and grouping
for the time being. :)  As such, this will probably the phase where i have
the least to say.  anyway, here's my thoughts.

> Category: Handling of URLs
> --------------------------
>
> public String actionURL(String action)

+1

> public String forwardURL(String forward)

+1

> public String forwardURL(String target, String parameters)
>
>     Same as above but appends the string parameters are the end of the
URL.
>     Example:
>     <a href='$tool.forwardURL("home", "frames=no&style=simple")'>Home</a>
>     produces something like
>     <a href="/myapp/templates/index.vm?frames=no&style=simple">

-1

i think it would be far better to put the adding of query data in a separate
method like the LinkTool i wrote does.  (of course, i don't think that
LinkTool is good for the Struts/Velocity project because it lacks the
methods above).  I have several reasons for wanting this:
1.  elegance.  imo this doesn't have it.  (ok, so that's pretty subjective,
but the next one is serious.)
2.  URL encoding.  I wouldn't want a forward(target, params) method to have
to parse and then encode the values, and i certainly don't want to have to
do the encoding manually in templates.
3.  what if you want to append query data to an action or absolute URL?
then we'd have to have xxxx(target, params) methods for those as well.

So, i would prefer to see $urltool.forward(foo) and friends return a
instance of urltool so we can then call an addQueryData(key, value) on it.


> public String absoluteURL(String path)

+1

> public String baseRef()

+1

> Category: Messages
> ------------------
>
> public String message(String key)

+1

> public String message(String key, Object args[])

+1

> public boolean isMessage(String key)

+1

> Category: Error Handling
> ------------------------
>
> public boolean hasErrors()

+1

> public int errorSize()


-1

> public int errorSize(String property)


-1

Ok, here's my thoughts on these last two...
It's not that i object to having the functionality.  We DO need that, i'm
just not convinced these are methods we need to clutter up the tool API
with.  IMO  what we should aim for is to have the getErrors() or errors() or
whatever methods return an object that has a size() method.  That way we can
just use $tool.errors.size()   This would provide equal functionality and
would keep needless clutter out of the tool.


> public String[] errors()

+1 on the functionality.  (but let's not return a String[].  I'd really like
to see something closer to what MessageTool does here.)

> public String[] errors(String property)

+1 (same comment as above)

> public String errorMarkup()

+0  i'm not thrilled by it, but as long as all the actual markup is pulled
from properties files under the view designer's control, i won't object.
But if i see ANY html or other markup stuck in the java, then i am a -137 on
it.


> public String errorMarkup(String property)

+0 (same as above)

> Category: ActionForm
> --------------------
>
> public ActionForm getActionForm()

+1

> Category: Miscellaneous
> -----------------------
>
> public Locale getLocale()

+1


good stuff Gabriel, thanks for doing all this.

Nathan Bubna
nathan@esha.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
Gabriel Sidler wrote:
> Or should the second set of methods handle both, Errors and Messages? (but
> that's not what the html:messsages tag seems to do). I guess I'm still
> confused about the real purpose of ActionMessages. The way html:messages
> is implemented does not really support the concept that action messages
> are a superset of action errors. It's more like you have two types of
> messages and you choose which one to operate on.
> 
> Anything that clears up my confusion is really appreciated.

The real guide should be the existing source code  :o)

Part of it was that we needed to make some changes to the way the errors
were being handled, since it was encouraging markup to be mixed in with
the messages (head-slap). There wasn't a good way to fix the errors
without breaking them, so we just added the message object instead, and
left the errors as it was. 


-- Ted Husted, Husted dot Com

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Ted Husted wrote:
> 
> Gabriel Sidler wrote:
> > Ted,
> > could you clarify what exactly you mean by the last sentence? Which
> > 'it's own key'? Which 'message key'? I am not clear on that.
> 
> The ActionMessages object is stored as one request attribute, and the
> ActionErrors object is stored as another.
> 
> The statics used to identify the attributes are named MESSAGE_KEY and
> ERROR_KEY in the Action package.
> 

Ok thanks, I understand that now. 

The html:messages tag does look at ERROR_KEY by default and does look at
MESSAGES_KEY if the attribute 'message' is set to true. But it does not
look at both, if I understand the doc right.

Does it makes sense to have two sets of methods; one to handle the errors 
and one to handle the messages stored under MESSAGES_KEY.  Something like:

public boolean hasErrors();
public int errorSize();
public int errorSize(String property);
public HashMap errors();
public HashMap errors(String property);

public boolean hasMessages();
public int messageSize();
public int messageSize(String property);
public HashMap messages();
public HashMap messages(String property);

Or should the second set of methods handle both, Errors and Messages? (but 
that's not what the html:messsages tag seems to do). I guess I'm still
confused about the real purpose of ActionMessages. The way html:messages
is implemented does not really support the concept that action messages
are a superset of action errors. It's more like you have two types of
messages and you choose which one to operate on.

Anything that clears up my confusion is really appreciated.

Gabe









> -- Ted Husted, Husted dot Com
> -- For priority Struts support,
> -> visit http://husted.com/about/services
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
Gabriel Sidler wrote:
> Ted,
> could you clarify what exactly you mean by the last sentence? Which
> 'it's own key'? Which 'message key'? I am not clear on that.

The ActionMessages object is stored as one request attribute, and the
ActionErrors object is stored as another. 

The statics used to identify the attributes are named MESSAGE_KEY and
ERROR_KEY in the Action package.


-- Ted Husted, Husted dot Com
-- For priority Struts support, 
-> visit http://husted.com/about/services

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Ted Husted wrote:
> 
> Gabriel Sidler wrote:
> > So, we should really provide a set of methods similar to what we
> > offer for handling errors?
> >
> > public boolean hasMessages();
> > public int messageSize();
> > public int messageSize(String property);
> > public HashMap messages();
> > public HashMap messages(String property);
> > public String messageMarkup(String header, String footer);
> > public String messageMarkup(String property, String header, String footer);
> >
> > (We need to rething the naming once we know what tools there will be.)
> 
> Yes. It's actually a superset of ActionErrors. All errors are messages,
> but not all messages are errors. So the message methods have to check
> under it's own key, and the message key, and report on the joinder of
> the two.

Ted,
could you clarify what exactly you mean by the last sentence? Which 
'it's own key'? Which 'message key'? I am not clear on that.

Thanks
Gabe



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
Gabriel Sidler wrote:
> So, we should really provide a set of methods similar to what we
> offer for handling errors?
> 
> public boolean hasMessages();
> public int messageSize();
> public int messageSize(String property);
> public HashMap messages();
> public HashMap messages(String property);
> public String messageMarkup(String header, String footer);
> public String messageMarkup(String property, String header, String footer);
> 
> (We need to rething the naming once we know what tools there will be.)


Yes. It's actually a superset of ActionErrors. All errors are messages,
but not all messages are errors. So the message methods have to check
under it's own key, and the message key, and report on the joinder of
the two. My original code didn't actually do that :o(



> Regarding the transaction tag, my understanding is that it is something
> that should really be dealt with in the Action and therefore we don't
> need methods to handle this in the template. Is that right?

The token needs to be passed back by the form or a hyperlink, so that it
can be compared with the token in the session. So the API does need to
be able to check the request for a token, and output it if found. This
applies to forms and (optionally) hyperlinks.

One thing I forgot is the magic value for the CANCEL button, that the
Actions uses to enage the isCancelled method. So we need a method that
returns that too.


-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Java Web Development with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Ted,
Thanks for the feedback. Can you clarify the following two details?
Regarding the rest of your mail I'll follow up.

Ted Husted wrote:
[...]
> The ActionMessages are basically an enhanced version of ActionErrors. It
> acts like an iterator, rather than just spitting everything out. We kept
> the ActionErrors mostly for backward compatability. It also lets
> developers send confirmations through one queue, and "errors" through
> another. But I generally just use one or the other myself.

So, we should really provide a set of methods similar to what we
offer for handling errors?

public boolean hasMessages();
public int messageSize();
public int messageSize(String property);
public HashMap messages();
public HashMap messages(String property);
public String messageMarkup(String header, String footer);
public String messageMarkup(String property, String header, String footer);

(We need to rething the naming once we know what tools there will be.)

Regarding the transaction tag, my understanding is that it is something
that should really be dealt with in the Action and therefore we don't
need methods to handle this in the template. Is that right?


Gabe



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
Gabriel Sidler wrote:
> My proposal is the following:
> 
> 1) Struts defines and implements a "Controller API for Views" that
> offers methods to work with the controller resources. For commonly
> used tasks, it provides convenience methods. This API is independent
> of a specific view technologies. It offers a super-set of the functionality
> that all possible view technologies might want to use. Your class
> ContextHelper could be the start for this. RequestUtils seems to fulfill
> a similar purpose, right?


RequestUtils was the precursor for the ConfigHelper, but RequestUtils
was targeted for JSPs. 



> 2) In Velocity we define a set of context tools that implement the
> interface ContextTool. They don't access Struts controller resources directly
> but build on the Struts "Controller API for Views". These context tools
> basically are a layer above the "Controller API for Views".
> 
> I see the following advantages:
> 
> - The struts framework know-how that is relevant for views is kept on
> the Struts side of the fence AND in one place.
> 
> - The views have all the flexibility to make the Struts resources
> available in a way that well suits their needs and specific properties.
> Specifically, in Velocity the functionality would be divided into serveral
> tools and the method signatures would be adapted to benefit from the specific
> features of Velocity. In some cases we might add convenience methods
> or VelociMacros.
> 
> How do you think about this? Can you also say something about how
> RequestUtils fits/does not fit in the picture?


That sounds fine.

The ultimate goal would be to have the tags use the ConfigHelper too,
and eliminate the need for the RequestUtils. 


-- Ted Husted, Husted dot Com

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Gabriel Sidler <si...@teamup.ch>.
Ted,
I finally got around to study your post from last week regarding the
ConfigHelperInterface. See below.

Ted Husted wrote:
> 
> This look quite good Gabriel. I also made a pass on the original
> ContextHelper object, and reduced it to an interface, which essentially
> dovetails with this API. There are some minor differences, which I will
> need to give some additonal thought.
> 
> http://husted.com/struts/resources/ConfigHelperInterface.java
> 
> The name change corresponds to the new support for multiple Struts
> configurations. The goal would be to provide an object that worked with
> both 1.0 or 1.1, and supported multiple configurations when they are
> being used. My original object compiled fine, but I need to test it, and
> then add the new configuration support.
> 
> Currently, the default type for other Struts controller elements,
> ActionMapping, ActionForward, et cetera, can be specified in the
> ActionServlet configuration. I'm thinking that we could do the same with
> the ConfigHelper. There would be a default base object type, but another
> could be specified. For example, a Velocity ConfigHelper might provide
> signatures that didn't bother with the get* convention, and provide
> additional helper methods.

That's an interesting way to look at it! But, it raises a few concerns
and/or questions on my side.
- It would be difficult to support applications that use multiple view
technologies at the same time.
- You would need to maintain multiple version of the ConfigHelper.
- I don't see ConfigHelper being used directly as a context tool in Velocity
for several reasons:
   o We have the concept of a toolbox that contains the context tools.
     Tools need to implement the ContextTool interface. This allow
     the toolbox to manage the tools. 
   o I believe it is better to have several small tools rather than
     one large tool.
   o The context tools should be on the Velocity side of the fence to
     give the view people the flexibility in building view tools.


On the other side, I wish very much to be able to build on a 
"Struts Views API" that offers all the functionality the controller 
framework offers to views. The ContextHelper you wrote contains 
a lot of framework know-how. Having this on the Velocity side would
be wrong. The only reason I moved ContextHelper to the Velocity side
in the past, was that this allowed me to support Struts 1.0. In the
medium to long term this should be on the Struts side.

My proposal is the following:

1) Struts defines and implements a "Controller API for Views" that
offers methods to work with the controller resources. For commonly
used tasks, it provides convenience methods. This API is independent
of a specific view technologies. It offers a super-set of the functionality
that all possible view technologies might want to use. Your class 
ContextHelper could be the start for this. RequestUtils seems to fulfill
a similar purpose, right?

2) In Velocity we define a set of context tools that implement the
interface ContextTool. They don't access Struts controller resources directly
but build on the Struts "Controller API for Views". These context tools
basically are a layer above the "Controller API for Views".


I see the following advantages:

- The struts framework know-how that is relevant for views is kept on
the Struts side of the fence AND in one place.

- The views have all the flexibility to make the Struts resources 
available in a way that well suits their needs and specific properties. 
Specifically, in Velocity the functionality would be divided into serveral 
tools and the method signatures would be adapted to benefit from the specific
features of Velocity. In some cases we might add convenience methods
or VelociMacros.


How do you think about this? Can you also say something about how 
RequestUtils fits/does not fit in the picture?

Gabe



--
Gabriel Sidler
Software Engineer, Eivycom GmbH, Zurich, Switzerland

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: Velocity View API for Struts

Posted by Ted Husted <hu...@apache.org>.
This look quite good Gabriel. I also made a pass on the original
ContextHelper object, and reduced it to an interface, which essentially
dovetails with this API. There are some minor differences, which I will
need to give some additonal thought.

http://husted.com/struts/resources/ConfigHelperInterface.java

The name change corresponds to the new support for multiple Struts
configurations. The goal would be to provide an object that worked with
both 1.0 or 1.1, and supported multiple configurations when they are
being used. My original object compiled fine, but I need to test it, and
then add the new configuration support.

Currently, the default type for other Struts controller elements,
ActionMapping, ActionForward, et cetera, can be specified in the
ActionServlet configuration. I'm thinking that we could do the same with
the ConfigHelper. There would be a default base object type, but another
could be specified. For example, a Velocity ConfigHelper might provide
signatures that didn't bother with the get* convention, and provide
additional helper methods. 

For 1.0 compatibility, a Velocity Servlet could instantiate this object
itself. In 1.1, the Struts controller could instantiate it instead; the
Velocity Servlet could then expose the ConfigHelper through the Velocity
context, and do the template merging thing.

The ActionMessages are basically an enhanced version of ActionErrors. It
acts like an iterator, rather than just spitting everything out. We kept
the ActionErrors mostly for backward compatability. It also lets
developers send confirmations through one queue, and "errors" through
another. But I generally just use one or the other myself. 

The ActionMessages should not be confused with the Message Resource.
ActionMessages live in the request scope, and are meant to be passed
along to the page. The other messages live in application scope, and are
used directly by the page to print localized labels and what not. Both
the ErrorMessages and ActionMessages refer to the Message Resource to
generate localized messages.

Switching back and forth between HTTP and HTTPS has always been tricky.
There's a new contribution available, but it relies on Servlet 2.3. 

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Java Web Development with Struts.
-- Tel +1 585 737-3463.
-- Web http://www.husted.com/struts/


Gabriel Sidler wrote:
> 
> As promised, I put together a proposal for the view API of Velocity
> in the Struts framework. I consulted:
> 
> - the ContextHelper.java by Ted
> - the MessageTool.java by Nathan
> - the existing Struts RequestUtil class
> - the existing Struts JSP taglibs
> 
> to come up with a set of methods that should provide the necessary
> Struts support from within Velocity templates. I have grouped functionality
> by categories to give the whole method list some structure. I have really
> focused on the Struts support. Other tools, like Nathan's LinkTool,
> are useful additions to the tools project, but are independent of Struts.
> 
> This is going to be a difficult discussion if we don't structure it
> a bit. Let's please define the following three phases:
> 
> Phase 1) What functionality should be covered by the view API. Is
> the proposed method set adequate. What needs to be added, what is irrelevant.
> How should method signatures be changed to make them Velocity-friendly.
> This does *not* cover the method names and the grouping of methods
> into tools. It's meaningless to talk about grouping before we are
> clear what methods there are.
> 
> Phase 2) Group methods into tools. Define tool names and method names.
> (The method names really depend on the tools that we define)
> 
> Phase 3) Hash out the implementation strategy. ContextHelper or not?
> ControllerAPI? Was parts are implemented on the Struts side and what
> on the Velocity side, etc.
> 
> I'll serve as the editor of this draft and provide you with updated versions
> as the discussion progresses.
> 
> Anyone with some Struts experience should really come forward now and
> comment on the proposal. I look forward to your feedback. Remember,
> it's phase 1 now! :-)
> 
> Gabe
> 
> -------------------------------------------------------------------------------
> 
> VELOCITY VIEW API FOR STRUTS
> ============================
> 
> Category: Handling of URLs
> --------------------------
> 
> Struts supports a configurable level of indirection between the URLs of a
> request and the handler of that request. For example, a URL of /main.do
> may be mapped by configuration to a handler of class com.app.my.handler.
> Futhermore, Struts knows the concept of 'forwards'. A 'forward' is a name
> for a request target, such as a request handler or simply a web page.
> 
> This configurable mapping of logical targets to actual targets allows
> one to avoid hard-coded URLs in templates. All the logical links between
> the different views of an application can be maintained in a configuration
> file. The following three methods are used to maps logical names to actual
> URLs. The remaining methods are related.
> 
> public String actionURL(String action)
> 
>     Converts the action name into a server-relative URL.
>     Example:
>     <form name="login" action='$tool.actionURL("login")'>
>     produces something like
>     <form name="login" action="/myapp/actions/loginaction">
> 
> public String forwardURL(String forward)
> 
>     Converts the local or global forward into a server-relative URL.
>     Example:
>     <a href='$tool.forwardURL("home")'>Home</a>
>     produces something like
>     <a href="/myapp/templates/index.vm">
> 
> 
> public String forwardURL(String target, String parameters)
> 
>     Same as above but appends the string parameters are the end of the URL.
>     Example:
>     <a href='$tool.forwardURL("home", "frames=no&style=simple")'>Home</a>
>     produces something like
>     <a href="/myapp/templates/index.vm?frames=no&style=simple">
> 
> 
> public String absoluteURL(String path)
> 
>     Create and return an absolute URL for the specified context-relative
>     path.
> 
> 
> public String baseRef()
> 
>     Renders the reference for a HTML <base> element.
>     Example:
>     <base href="$tool.baseRef()">
>     produces something like
>     <base href="/myapp/template/view.vm">
> 
> Support for the switch between HTTP and HTTPS would be useful here too.
> There has been some discussion on the list but currently Struts doesn't
> support it as far I know, right Ted?
> 
> Category: Messages
> ------------------
> 
> Struts supports internationalized messages. The messages are stored
> in NVP files by language. The following methods operate on these message
> files.
> 
> public String message(String key)
> 
>     Return the localized message for the specified key.
>     Example:
>     <input type="submit" name="newbutton" value='$tool.message("view35.new")'/>
>     renders something like
>     <input type="submit" name="newbutton" value='Neuer Patient anmelden'/>
> 
> 
> public String message(String key, Object args[])
> 
>     Same as above, but supports parametric message strings, for example:
>       warning.quota=Your mail folder is {0} MB above the limit of {1} MB.
>     Up to five replacement parameters are supported.
> 
> 
> public boolean isMessage(String key)
> 
>     Return true if a message string for the specified message key
>     is present for the user's Locale.
> 
> 
> Question to Ted: How should the new ActionMessage be considered? What's
> its role and how are they different than ActionError
> 
> Category: Error Handling
> ------------------------
> 
> Errors may stem from the validation of a submitted form or from the
> processing of the request. If there are errors, they are made available
> to the view to output. A few aspects about errors are:
> - Error messages are looked up in a bundle of messages resource files. Support
> for internationalized messages is provided.
> - Error messages can have up to four replacement parameters.
> - Errors have a property that marks them as 'global errors' (meaning that they
> apply to the entire form) or 'specific errors' (meaning that they are specific
> to one of the form elements). This allows to position error messages precisely
> where the error occured on the form.
> 
> public boolean hasErrors()
> 
>     Returns true if there are errors queued, otherwise false.
> 
> public int errorSize()
> 
>     Returns the number of error messages.
> 
> public int errorSize(String property)
> 
>     Returns the number of error messages for a particular property.
> 
> 
> public String[] errors()
> 
>     Returns an array of localized error messages. A typical application
>     would use a script similar to the following to output the error messages.
>     Example:
>     <ul>
>     #foreach ($e in $tool.errors )
>       <li>$e</li>
>     #end
>     </ul>
> 
> public String[] errors(String property)
> 
>     Same as above but only the error messages for a particular
>     property are retrieved and returned.
> 
> public String errorMarkup()
> 
>     Returns a formatted error text consisting of all queued
>     error messages. The markup is composed of an 'errors.header',
>     followed by all error messages, followed by an 'errors.footer'.
>     'errors.header' and 'errors.footer' are keys that reference
>     messages in the messages resources bundle. If no errors are
>     queued, an empty String is returned.
>     While some may consider it not nice that markup is produced
>     by this method, it is important to note that all markup is under
>     the control of the view designer.
>     Example:
>     $tool.errorMarkup
>     Does all that's needed to output a formatted error message.
> 
> 
> public String errorMarkup(String property)
> 
>     Same as above but only error messages for a specific property
>     are included.
> 
> Category: ActionForm
> --------------------
> 
> Struts has support to parse incoming HTTP requests and stick the available
> request parameter into a bean. The Struts config file defines what bean
> class to use for a particular request. Additionally, a hook allows the
> application developer to include form validation code. The form bean is
> passed around as an attribute to the servlet request.
> 
> public ActionForm getActionForm()
> 
>     Retrieve and return the ActionForm bean associated with this mapping.
>     The ActionForm is typically needed by the view designer to populate
>     HTML form elements with values.
> 
> 
> 
> Category: Miscellaneous
> -----------------------
> 
> public Locale getLocale()
> 
>     Retrieve and return the Locale for the user. If a Locale is
>     not found, the default locale is returned. Note: Struts' Locale
>     is not request.getLocale().
> 
> 
> -------------------------------------------------------------------------------
> 
> --
> Gabriel Sidler
> Software Engineer, Eivycom GmbH, Zurich, Switzerland
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>