Beefy Boxes and Bandwidth Generously Provided by pair Networks vroom
Don't ask to ask, just ask
 
PerlMonks  

More on Web Application Frameworks

by impossiblerobot (Deacon)
on Apr 08, 2002 at 22:08 UTC ( #157582=perlquestion: print w/ replies, xml ) Need Help??
impossiblerobot has asked for the wisdom of the Perl Monks concerning the following question:

I'm about to start writing a medium-sized web-based application, which may eventually become much more complex. Although I am quite capable of coding the entire thing from scratch, using the appropriate modules for standard tasks, I thought I might be able to save myself some work, increase maintainability, and better prepare myself for growth by using one of the several CGI frameworks available.

Even after looking at the various nodes comparing/recommending various frameworks (such as Web Application Frameworks and their Templating Engines with a Comparative Study of Template and HTML::Template) and skimming the docs for several of the options mentioned, I have not reached that state of inner peace that is required before I commit to an undertaking. So I thought some more feedback/discussion might help. (Not to mention the fact that the tools available change so quickly that older posts may no longer reflect current reality.)

I hope that not everything that the monks have to say on this matter has been said. So what follows is a combination of the specifications for what I need to accomplish and some exposition about how I would normally do these things. I hope this doesn't get too long:

The Basics:

Since I'm not sure on which servers I will be deploying this, I can't count on having access to mod_perl; so my choices are limited to those frameworks that will work under CGI.

I don't necessarily need an all-in-one solution, but if I have to piece together too much of it myself, I don't know that I'm really doing myself any favors by choosing a framework solution (though I suppose extending an existing solution would be the monk-ish way to solve that problem). :-)

The Details:

Here are some of the functions I will need, along with My Thoughts or How I Would Probably Do It Myself. These are not absolute rules; I am willing to consider alternative theories, but these notes do reflect some of my current preferences:

View Management:

Doing It Myself, I would probably just use a dispatch table for the various 'screens' or 'views' the application would be presenting, abstracting as much of the re-usable logic as is useful into a separate module.

Session Management:

I would probably use Apache::Session, and use cookies for storing the session ID, with URL-munging as a fallback.

CGI Form-handling:

I would probably parse form data with CGI.pm (just because it would already be installed), even though one of the stripped-down versions (such as CGI::Lite) would probably be a better fit (since I don't use CGI.pm's HTML -generation routines).

Form Validation:

Although I could use a module for this, if I were Doing It Myself, I would probably use JavaScript on the client side (for immediate feedback) and stricter validation/taint-checking on the server side using regexes, etc.

Templating:

I haven't committed to any particular template module at this point.

I normally work with a designer, and in the past I've usually followed these rule for templates:

  • Use a one-template system -- I don't want me, or the designer, to have to build half-a-dozen templates everytime the site design changes.
  • Template mark-up should be visible in Dreamweaver's WYSIWYG mode -- The designer can see the mark-up, and know not to remove it. Or the designer can even add simple tags to the appropriate place(s) in the template, without having to delve into the HTML.
  • The design goes in the template; the logic goes in the application -- Otherwise the purposes other two rules will probably be defeated. (Having some presentation logic in the template might be useful, but I'm not sure how well it would work with my "one-template" plan.)

    So typically I've used a template that replaced the <TITLE> tag and filled in a content area with the results of each page. The designer used CSS to modify the look of the various elements in the content area.

Potential Requirements:

  • Authentication -- I will probably, at some point, need to authenticate some sessions with a username/password.
  • DBI -- I will definitely be using DBI (with MySQL) for this project, so I suppose that any framework database integration might be useful (though not strictly necessary).
  • Others -- I'm sure there are some things I should have mentioned, but forgot to.

The Request:

I'm hoping that our hallowed monks will be able to help me determine what the best CGI application building tools are for me. Feel free to tell me where my thinking has gone wrong, what I should do instead, as well as how you have or would do it yourself. If you've integrated these features using one or more packages, please share your experiences and opinions. Hopefully this will be as useful to others as I expect it will to me.


Impossible Robot

Comment on More on Web Application Frameworks
Re: More on Web Application Frameworks
by gav^ (Curate) on Apr 08, 2002 at 23:47 UTC
    An interesting book which covers these topics is Perl for the Web by Chris Radcliff (ISBN 0-7357-1114-3) which makes interesting bedtime reading.

    gav^

Re: More on Web Application Frameworks
by rob_au (Abbot) on Apr 08, 2002 at 23:58 UTC
    I must say, that I too have walked this path and searched for the "ideal" CGI framework, as yet, to no avail ... I would however throw a bit more into the melting point, and recommend you having a look at this node by boo radley which offers some excellent suggestions for development direction of CGI frameworks - It was from this node that I was able to draw many ideas for what is becoming the intended featureset for a CGI framework which I am currently developing.

    Currently, however, as many new work projects cross my desk, the available time for development disappears - For the time being, I have been making great use of the combination of CGI, CGI::Application, HTML::Template, Apache::Session and Data::FormValidator. If you are interested I can put up a couple examples of this, however as it stands, this framework is fairly basic and is far from a "packaged solution".

     

      Thanks, rob_au, I would appreciate seeing what you've done.

      It sounds like the list of tools you mentioned would probably meet all of my requirements, but would require some work to integrate. I guess I need to really delve into CGI::Application, to see how much it can really do for me.

      Update: I forgot to mention that although HTML::Template doesn't really match my preference as far as tag/markup style, it's probably something I can live with (which is fortunate, since CGI::Application seems to be tied to it).

      Impossible Robot
        The following is a small script framework that I have used for a couple of smallish CGI applications. While it doesn't incorporate session handling in any sense more than hidden HTML fields, this could easily be changed through the use of Apache::Session and instead of returning the parameters retrieved so far into hidden fields of the template markup, the single session id could be that passed into these fields.

        Also too, with regard to templating engine, there is nothing to stop your usage of Template::Toolkit with CGI::Application, an aspect of usage which I commented on here.

        The code including some comments follows ...

Re: More on Web Application Frameworks
by Tardis (Pilgrim) on Apr 09, 2002 at 01:19 UTC
    Although I have only so far used it in a limited fashion, Mason appears very powerful. It does use mod_perl, but can work without it (with the appropriate speed penalty).

    Within a couple of hours I put together a basic web site that had automatic templates, dynamic sidebar menu, and so on.

      Thanks, Tardis. Have you had a chance to use Mason in CGI mode? I wonder how much of a speed hit there would be. I wouldn't expect a lot of traffic for this application, but I also don't expect it to be running on very fast servers.

      Also, how well does Mason match up with my needs/preferences? Do its tools work well when not used in an embedded-code type application (which I understand is the normal way to use Mason)?

      Impossible Robot
        I'd prefer not to comment directly, given I haven't used it that much. I can tell you what I have done though.

        Page templating is done via the autohandler. The autohandler gets called for all page requests, plus it is also done in a hierarchy - if the current directory doesn't have an autohandler, it will go up a level and try the parent. As you can imagine, this makes page templating with overrides for certain web site areas rather easy.

        After my autohandler has done the page setup (via broken out components, my autohandler has very little actual HTML in it), I have a line: <% $m->call_next %>. This is where whatever actual object was referenced in the URL starts being displayed/processed.

        Thus, my actual documents have very little in them except basic markup. There is no need to have includes for the headers or footers, it's done automatically. I do have:

        <%method title>Page title here</%method>
        Which propagates up the tree, and is available to my components that generate the actual page headers and so forth.

        What I haven't done yet, is any form of user interactivity, though it looks like it will be quite easy handling GET/POST requests. But so no more, since I haven't tried it yet.

        Also of note (though I haven't used it yet either) is the caching ability - components can be automatically cached, and only regenerated after certain times. For example, a weather component might generate a chunk of HTML which shows the current temperature. The caching can easily ensure that it only runs say once per hour, calling components receiving the cached output in the meantime. This is a big boon for performance. I'm not sure if this works in non-persisitant (ie non mod_perl) environments.

        Lastly, and perhaps most importantly, there is very good documentation available on the web site, and some good tutorials around on other sites as well.

        BTW, I probably haven't explained the Mason stuff above too well, Mason diehards are welcome to go postal on any mis-uses of Mason terminology above :-).

        I use Mason a lot. Mostly on a mod_perl server. It can run, a bit slowly, in cgi mode. You can also run with FastCGI, although you lose some mod_perl based functionality.

        Mason has a pretty high overhead in CGI-mode, because you'll need to load the interpreter, handler, and parser objects, and then load your component and any modules used by any of these pieces for every page view. Speed is acceptable if you have very low traffic. Any persistance framework (ISAPI, mod_perl, etc.) will help a lot.

        There is an excellent article on masonhq called Design Issues with Mason. It should answer your question about not using embedded code. You can also use components in a MVC style--some components are used for display, some for app logic, and some for data access. Whichever style you use, mason's embedded code capability makes creating working prototype applications incredibly fast and easy.

        Probably the coolest thing about Mason is it's parameter handling. You have THREE different ways of getting params, and it can be useful to mix them. You can declare an <%args> section in your component, and name your variables:

        <%args> $foo => 'FOO!' # the value of foo goes here, default value "FOO!" @bar # Here we ask for a list of bar values, no default means bar is +a required param. $dog => $foo.'dog' # You can have dynamic defaults. $cat => undef # or undef by default. </%args>

        You can also just pull things out of @_, just like a perl subroutine, which is actually what a mason component compiles into. And third, you can use the magnificent %ARGS hash. This is really handy for building components that print form data in a pretty way without having to hard code in fields:

        <HTML><head><title>STUFF</title></head> <body> <table> % foreach my $field ( keys %fieldSpecs ) { <tr><td><% $field %></td><td><% $ARGS{$field} %></td></tr> % } </table> </body> </HTML> <%args> %fieldSpecs </%args>

        Of course a real usage of the above would need to be a bit more complex. You can manipulate one structure without affecting the others. This has proven to be rather handy.

        Dhandlers, autohandlers and inheritance are also very cool mason features. Autohandlers provide a way of creating nested templates and core functionality common to entire hierarchies on your server. If you have a file at /home/html/foo/bar/baz.html, it will automatically invoke the autohandlers at /home/html/autohandler (I'm assuming /home/html/is you doc root), /home/html/foo/autohandler, /home/html/foo/bar/autohandler. Combined with inheritance we have a very powerful feature. You can create sub components that live inside a main, parent component, if you specify that they are 'method's they can then be inherited. For example if you want every component on your website to be able to find print the time in roman numerals, you write a method to do this, then stick it in your root authandler. Then in any component you can call $m->comp(SELF:RomanTime) to get the results. Dhandlers allow you to specify how to react to requests for files that don't exist. Say you have all your content in xml stored in a database. You can write a dhandler that translates an html document request into a call to routines that look up the appropriate xml in the db, transform it to html. Your autohandler will take care of wrapping it in your standard templates for you.

        That's my Mason is Cool rant. I hope you have found it useful. Check out Bricolage and RT, a couple of impressive Mason apps. Plus, VIm has a syntax definition for Mason.


        TGI says moo

Re: More on Web Application Frameworks
by perrin (Chancellor) on Apr 09, 2002 at 03:32 UTC
    Unfortunately, you really limit yourself when you eliminate mod_perl. The frameworks I think are closest to what you're looking for are OpenInteract and Apache::PageKit, but neither of those will work with CGI. That leaves you with things like CGI::MxScreen or CGI::Application, plus Template Toolkit or HTML::Template.
      Seems like I remember Chris saying that losing the mod_perl dependence was something relatively high on his TODO list. While I haven't looked at the code lately, it might be something easy to do. I remember one application that "required" mod_perl because it used $r->print() and Apache::Request methods that have CGI counterparts. I think I spent 10 minutes changing it to run under CGI.

      At a minimum you should probably look at the frameworks Perrin mentioned because they have a lot of very useful functionality you might be able to implement for your framework.

        Relatively high -- it will be in the next version. (But then, everything will be in the next version :-)

        Chris
        M-x auto-bs-mode

        I think the reason OpenInteract needs mod_perl has more to do with performance than with specific module dependencies. The life-cycle of mod_perl applications allows you to use a larger codebase without the speed penalty of compiling it on each request, and cache expensive resources like database handles. I know that people have made, for example, Mason run under CGI, but it was too slow to be useful that way.
Re: More on Web Application Frameworks
by Ryszard (Priest) on Apr 09, 2002 at 03:41 UTC
    I've done some similar stuff and my preference is:
    1. CGI.pm - Nice easy way of both generating HTML, parsing forms, cookies et al.
    2. CGI::Application - Great framework for providing a structured application, altho care should be taken so your application doesnt become spaghetti.
    3. HTML::Template - Easy peasy method of templating HTML.
    4. DBI - say no more.
    5. Some ancillary modules (ala Digest::MD5 etc)

    I wrote my own session management, user management and access control becuase:

  • I could
  • I learned more
  • I could taylor it to specifically how/what I wanted.

    As a side (read personal) project I'm developing a web portal. Thus far it has an address book, date book, and an mp3 playlist manager. I'm also working on a photo album function, which will slot into the application framework with virtually no effort.

    The way I've structured the application is to have one CGI::Application application per concept, all in seperate directories. So I've got a directory containing the application for the address, date, and playlist functions. They are all tied together with session management and access control, ie each time a user fetches a page, the function that returns the page will check their session and whether they can access the function and branch accordingly.

    The access control is pretty handy as you can have an arbitrary level of granularity, and displays only menu functions the user has access to.

    My own session managemnt handles the authentication to a Postgres database, altho' I've only implemented a cookie based approach (and the key will last the length of the session (ie until it times out or the user logs out)). Doing your own session management is pretty damn easy to do well, altho' I'm sure you know what they say about the tried and the true. As the session management is my own module creation, It's really easy to modify (ie reissue a new key each view) without changing the upper "business" functionality.

    My form validation, ie taint checking, validity checking is done internally to each function (or method call) as i find when i'm doing form stuff its pretty specific to the function (or method).

    View management is handled via "run modes" in the CGI::Application framework.

    I found when I 1st started my project I was a bit bam-boozled by the endless possibilites etc etc, and quickly settled on this combo becuase its just so damn easy to use. Its just not rocket science.

    Good luck with the project, I'd be interested to hear what application framework you settle for, and why.

    Why use CGI::Application?
    Choosing a templating solution

Re: More on Web Application Frameworks
by BUU (Prior) on Apr 09, 2002 at 16:11 UTC
    Just something to keep in mind, when your generating the html output, is to make sure you keep all the html seperate from the style. I.E. you can put all your 'headers' in <h1>, all the body paragraphs in P, and so on. The advantage of this is you can write a style sheet for it, to control every aspect of how it displays, then you can change the stylesheet at any time, without changing the html output at all. This allows for very easy redesigns, different 'schemes', etc etc. Basically, keep content seperate from style from design.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://157582]
Approved by Corion
Front-paged by gav^
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (16)
As of 2014-04-23 18:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (553 votes), past polls