http://www.perlmonks.org?node_id=411793


in reply to Re: Review: CGI::Prototype
in thread Review: CGI::Prototype

Our app will have to figure out which button was hit and handle the data and output as needed. In C::A, there is really only one place you can put this logic: cgiapp_prerun(). If you have many runmodes that need this sort of functionalilty, your cgiapp_prerun() can start getting rather large.

When I do this kind of thing, I put the logic in the handling runmode ... something like:

# This runmode show the data-entry template sub show_entry { # ... yada yada yada } sub process_entry { my ( $self, $query ); $self = shift; $query = $self->query(); # This method will add the entry in the db $self->add_entry(); # Now if the user hit the 'add another' button... if ( $query->param( 'addanother' ) ) { return $self->show_entry(); } else { # mainscreen() being the main/home page runmode return $self->mainscreen(); } }

Replies are listed 'Best First'.
Re^3: Review: CGI::Prototype
by hardburn (Abbot) on Dec 02, 2004 at 15:47 UTC

    When I do this kind of thing, I put the logic in the handling runmode

    I don't think this will work very well. Often, mainscreen() itself took input from some other form. Now I'll need to pile on yet more logic inside mainscreen() to know which runmode it's being called by.

    I don't see a solution with C::A that doesn't involve pileing on a lot of additional logic. It seems very good for applications that have a simple, linear progression through the pages (start -> A -> B -> C -> finish). It breaks down fast for more complex structures.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      /I'm assuming mainscreen() is just a call to a template in my response here...

      Why would mainscreen() change its appearance a lot based on where it was called from? It shouldn't really care - it should show data and messages and that's it. Use a different template for different screens, and include the common parts.

        Why would mainscreen() change its appearance a lot based on where it was called from?

        It may or may not change it's appearance. It may very well change what it does underneath based on where it's called from.

        For instance, I often create a set of forms for a user to go through to enter data that eventually ends up in a database. I have a second set that allows them to edit that information later. Really, the second set is exactly the same as the first set, just with the existing data pre-filled into the same forms, and we write our SQL to do UPDATE instead of INSERT.

        Since they're really the same thing with minor differences, and taking to heart the idea that copy-and-paste is the lowest form of reuse, we'll want to code things so that the same runmodes and templates can be used again.

        Certainly, C::A can do this (I've coded it to do just this many times). But I think a different approach (specifically, using polymorphic objects) could be a lot cleaner.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      I don't think this will work very well. Often, mainscreen() itself took input from some other form. Now I'll need to pile on yet more logic inside mainscreen() to know which runmode it's being called by.

      Well, it depends on your mainscreen(). My mainscreen() is always the very first page, which by definition doesn't take any input.

      In my years of cgiapp development, I actually haven't needed it any other way. That's probably b/c I don't develop the more complex structures, but I've done countless e-commerce and complicated database applications in this "simple" manner.

      Now that I think about it, there are a few other options. Remember in each runmode you got access to the $self (cgiapp class), which you can call its get_current_runmode() to see what runmode it's being called by. You also have access to the CGI object within. You can also stuff/access something inside the cgiapp object with its own param() method. Lastly, you can also pass along arguments to the various runmodes.

      You have to put that logic somewhere... ;)

        You have to put that logic somewhere... ;)

        Yes, and where I don't want it is in an if statement. I'd rather put the logic as a simple method call via polymorphism.

        "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.