Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
PrivateSpace::
            ::Display
            ::DataBase
            ::Session
            ::CGI

This is not any kind of final word on the matter. Just a suggested outline. See also Code and html separation - always or mostly doable?, and others from the search.

If you don't separate your business logic from your display logic you get self-involved spaghetti code. It's difficult at first to realize this b/c it seems natural to write it all together but for a big project it's Wrong and will bite you. Imagine if you will that DBI and CGI and Mason were all one module called WebDataDisplay or something. You can see how awful and un-modular it becomes. It's no longer a tool to pick up and use but an application that either fits or doesn't and if it doesn't then all the shoe-horns in Taiwan might not turn the trick.

PrivateSpace::
Just a name space for an app.
            ::Display
A wrapper for Template or Mason or whathaveyou.
            ::DataBase
A base for DB stuff, DBI or Class::DBI or DBIx or whatever based.
            ::Session
An excellent choice is Apache::Session. It's file or RDBMS based. It saves sessions which can be restored by cookie for persistence across scripts/pages/templates.
            ::CGI
Param parsing and encoding and maybe here CGI::Application comes in. CGI::Application is a nice tool but it's almost superflous if you are using a good templating system and have your data encapsulated well.

Once all that is setup you can write an application as simply as (this is pseudo code from something real I've done):

use PS::Display; use PS::DataBase; use PS::Session; use PS::CGI; my %dispatch = ( action1 => \&do_me, action2 => \&do_you, ); my $action = PS::CGI::param('action_var') || $default; my $session = PS::Session->new_or_from_cookie(); my $user = PS::DataBase->user( $session->userid ); my ( $page, %extra_data ) = $dispatch{$action}->(); my %template_info = ( session => $session, user => $session->user, %extra_data ); print PS::CGI::header(-cookie => $session->cookie); SR::Template->process ( data => \%template_data, page => $page, );
Then your template (TT2 example here) can branch in ways like:
[% IF session.is_authorized %] YXZ branching with and based on [% all_that_prepared_data %] [% ELSE %] No XYZ for you, please <a href="[% uri.login %]">login</a> or <a href="[% uri.register %]">register</a>. [% END %]
The great part about this is the templates can be very logically complicated without being anywhere near as hard to read as the equivalent in raw perl. As soon as one gets too complex to take in easily, you just split it into its logical components. And since templates generate visual output, they tend to be easier to follow (visualize) anyway.

If you want to see a complete and well tested version of this kind of thing you could always get slashcode and check it out.

I too would love to see a concise, well-done set of code to handle this basic need (login based user driven sites). I think it's ellusive in part b/c there are SO many choices that can go into making the recipe. Templating systems alone still boast several widely favored options. Hit the search with cookie, session, template, and other terms to see tons of excellent advice for all the various ingredients in this pie.

To touch on your real questions too: Which parts of the program actually need to be run modes? If you're using a good template then only the data generation and template selection. The templates can and probably should do all the sorting out of the data. Where does my validation function go? Right before you are going to do something serious like alter a DB entry--passing validation means go ahead, not means dump back to previous state/mode with error feedback. How do I store/work with a session? Seriously check out Apache::Session, it's easy and it works realy well. How do I debug C::A? Lots of informative carp()s in your modules and lots of warn()s in your CGI proper. Then your error log is your friend. croak() and die() if you are ready to catch it without showing the user a 500 screen that offers extra pointers for how to hack your stuff. :)

Good luck! And you can always break parts down into more easily masticated bits for more Qs on the project. (update: fixed a couple pseudo-typos.)


In reply to Re: Starting with CGI::Application and Logins by Your Mother
in thread Starting with CGI::Application(::Session) and Logins by deep submerge

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2024-04-23 14:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found