A JSF faces request (a form submission) encapsulates both an "action" (a method binding) and "parameters" (input value bindings). A page action might also needs parameters!
Since GET requests are bookmarkable, page parameters are passed as human-readable request parameters. (Unlike JSF form inputs, which are anything but!)
Seam lets us provide a value binding that maps a named request parameter to an attribute of a model object.
<pages>
<page view-id="/hello.jsp" action="#{helloWorld.sayHello}">
<param name="firstName" value="#{person.firstName}"/>
<param name="lastName" value="#{person.lastName}"/>
</page>
</pages>
The <param> declaration is bidirectional, just like a value binding for a JSF input:
When a non-faces (GET) request for the view id occurs, Seam sets the value of the named request parameter onto the model object, after performing appropriate type conversions.
Any <s:link> or <s:button> transparently includes the request parameter. The value of the parameter is determined by evaluating the value binding during the render phase (when the <s:link> is rendered).
Any navigation rule with a <redirect/> to the view id transparently includes the request parameter. The value of the parameter is determined by evaluating the value binding at the end of the invoke application phase.
The value is transparently propagated with any JSF form submission for the page with the given view id. (This means that view parameters behave like PAGE-scoped context variables for faces requests.
The essential idea behind all this is that however we get from any other page to /hello.jsp (or from /hello.jsp back to /hello.jsp), the value of the model attribute referred to in the value binding is "remembered", without the need for a conversation (or other server-side state).
This all sounds pretty complex, and you're probably wondering if such an exotic construct is really worth the effort. Actually, the idea is very natural once you "get it". It is definitely worth taking the time to understand this stuff. Page parameters are the most elegant way to propagate state across a non-faces request. They are especially cool for problems like search screens with bookmarkable results pages, where we would like to be able to write our application code to handle both POST and GET requests with the same code. Page parameters eliminate repetitive listing of request parameters in the view definition and make redirects much easier to code.
Note that you don't need an actual page action method binding to use a page parameter. The following is perfectly valid:
<pages>
<page view-id="/hello.jsp">
<param name="firstName" value="#{person.firstName}"/>
<param name="lastName" value="#{person.lastName}"/>
</page>
</pages>
You can even specify a JSF converter:
<pages>
<page view-id="/calculator.jsp" action="#{calculator.calculate}">
<param name="x" value="#{calculator.lhs}"/>
<param name="y" value="#{calculator.rhs}"/>
<param name="op" converterId="com.my.calculator.OperatorConverter" value="#{calculator.op}"/>
</page>
</pages>
<pages>
<page view-id="/calculator.jsp" action="#{calculator.calculate}">
<param name="x" value="#{calculator.lhs}"/>
<param name="y" value="#{calculator.rhs}"/>
<param name="op" converter="#{operatorConverter}" value="#{calculator.op}"/>
</page>
</pages>