At 06:41 PM 06/12/02 +0100, Jeff AA wrote:
>Ok - full-circle back to encoding page state in links and hidden fields
>on the page itself, but it was an interesting loop!

[from a thread about saving state in links on the mod_perl list]

The other day Perrin and I discussed this state info, and where in MVC it
should be dealt with.  I think I don't allow my Templates (or the View) to
do enough work building links -- instead I have often done it in the model.

The example is an application that has a search interface, where you might
get a page of results at a time and you need to save state from request to
request.  And how best to track all the parameters that need to be passed
on every request.

This is a MVC-no-no I guess, but in my model (that knows what it needs to
do a query) I would setup the URL parameters for links back to the query
(such as prev|next links).

In the model I might do something like

     $navigation = {
          next => $self->build_search_href( 'start' => $next_page ),
          prev => $self->build_search_href( 'start' => $prev_page ),
     };

where build_search_href() knows all the state info that's used by the query
model.  The build_search_href() function might build a query string, which
database to search, limit parameters and so on, for example, in addition to
the start offset.

and then in the template use:

      <a href="[% search.navigation.prev %]">Prev</a> |
      <a href="[% search.navigation.next %]">Next</a>

(but I'd add logic to see if there was a Next or Prev, of course)

But I guess that's the wrong way since it's placing HTML in the model.
It's also bad because other models can't add info to that link, such as
advanced/standard search form to use, "skin", brief/full view, etc.

So, the controller might do:

   if ( $apr->param('query') ) {
      # Decode query string
      my $request = Controller::SearchArgs->new( $apr );

      # Run query
      my $results = Model::Query->new( $request );

      $vars->{results} = $results;

      # Now for the View

      if ( $results->num_records ) {
          $template->process( $results_template, $vars )
           || die $template->error();
          return;
      }


      # See if we can offer some spelling help

      if ( my $dictionary = $dict->lookup( $request->query_string ) ) {
          $vars->{dictionary} = $dictionary;
      }

      $template->process( $no_results_template, $vars )
        || die $template->error();
    }


Now, it's nice to be able to have template variables like 

    [% search.navigation.next_page %]

So, should the controller or the templates (view) build those links?  I
kind of feel it's the programmer's responsibility to build the URLs so that
the controller will get them as expected -- and make the templates simple.

Anyone have good examples of how to build these state-saving links for use
in templates?  Do you do them in the templates?  Or do you have a view
module that builds them before calling process()?


Thanks,
-- 
Bill Moseley
mailto:[EMAIL PROTECTED]


Reply via email to