http://qs1969.pair.com?node_id=320955


in reply to Re: Why CGI::Application?
in thread Why CGI::Application?

I'm not sure how splitting into two or more C::A's would work (e.g. how would two C::A's interact?) - could you post a simple example of how to do it?

Replies are listed 'Best First'.
Re: Re: Re: Why CGI::Application?
by dragonchild (Archbishop) on Jan 13, 2004 at 18:12 UTC
    Sure. I'll post a condensation of what I'm working on right now. The plan is this - you have a main C::A, where you handle logging in, the home page, and logging out. You also have a C::A that handles how reporting works. Remember - some of your users might not have the authority to run reports, so it's easier to just disallow the whole C::A than it is to disallow certain run-modes.

    Ok, so far so good. But, we don't have another C::A yet. I personally do my navigation through some header that I've TMPL_INCLUDE'd into all the relevant templates. (All of them, except login and logout.) The header basically has

    HOME => main.cgi?mode=home REPORTS => reports.cgi LOGOUT => main.cgi?mode=logout

    But, you wanted to see the other C::A. Here ya go:

    That's it. No handling of cookies, no handling of nothing. In fact, there's absolutely no way the cookies are NOT going to be handled. You can't forget to add it to the top. You can't forget to do standard processing. It's quite ... nice to be able to forget that you have it cause it just works.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      I like the idea of composing subclasses of C::A into the larger application, but I didn't see how you implemented this bit of the 'technical specification':

      "...so it's easier to just disallow the whole C::A than it is to disallow certain run-modes."

      If REPORTS => reports.cgi is in the navigation template on every page, then how do you prevent the user from executing that particular C::A? And I don't think that

      # Display some method of choosing reports, probably with some author +ization # checks in there

      inside sub choose counts; it's still disallowing a certain run-mode named "choose". :-)

      p.s. I enjoyed and learned something from being sidetracked by http://www.mail-archive.com/cgiapp@lists.erlbaum.net/msg00849.html.

        It all depends on how your authentication method is set up. I'm still a little fuzzy on all the details, but you can do a few different things. Each has its own pros and cons, and some combination is probably best.
        1. Each C::A could authenticate itself against a master set of authorities. The C::A would implement a check against a set of authorities the user must have. The link would exist, but the user wouldn't get very far.
        2. If you're using TT or Mason, you could pass in a $user object and have it determine what links are available, based on the $user object. (Not C::A specific, I know, but not everything is implentable in C::A, nor should it be.)
        3. Instead of the $user knowing what links it can go to, you would have the C::A indicate what authorities are needed to get to it. Then, it would register with some master and the $user / TT / something would ask that master where it can go.

        And, I'm sure I'm missing other possible schemelets.

        ------
        We are the carpenters and bricklayers of the Information Age.

        Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

      This is a tad on the late side. :-)

      The situation you discuss earlier is one that I'm also facing. I'd be interested in breaking a C::A into one or more C::As.

      I've tried to recreate the method you've used but I've hit a snag.

      You have

      package My::Application::Base; use CGI::Application; our @ISA = qw( CGI::Application ); sub setup{ # Do basic stuff, including run_modes everyone has, like 'redirect +_login' }
      Note the reference to run_modes. Later you have
      package My::Application::Reports; use My::Application::Base; our @ISA = qw( My::Application::Base ); sub setup{ my $self = shift; $self->runmodes([qw( choose display )]); }
      As far as I can tell the run_modes in Base are overwritten by the run_modes in Reports and I get a "No such run mode..." error when reffering to any run_mode in Base.

      Did you encounter this?

      Also, how would you implement such a scheme as this? Would each C::A have its own instance script?

      Update:

      fwi, I've post my attempt here

        You need to call $self->SUPER::setup() as the first line after my $self = shift;

        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?