Every example I've seen of CGI/Perl basically a bunch of print statements containing HTML, and this doesn't seem like the best way to write a CGI app. Is there a better way to do this? Thanks.
EDIT: I've decided to use CGI::Application and HTML::Template, and use the following tutorial: http://docs.google.com/View?docid=dd363fg9_77gb4hdh7b. Thanks!
Absolutely (you're probably looking at tutorials from the 90s). You'll want to pick a framework. In Perl-land these are the most popular choices:
CGI::Application - very lightweight with lots of community plugins
Catalyst - heavier with more bells and whistles
Jifty - more magical than the above
This is a really, really big question. In short, the better way is called Model/View/Controller (aka MVC). With MVC, your application is split into three pieces.
The Model is your data and business logic. It's the stuff that makes up the core of your application.
The View is the code for presenting things to the user. In a web application, this will typically be some sort of templating system, but it could also be a PDF or Excel spreadsheet. Basically, it's the output.
Finally, you have the Controller. This is responsible for putting the Model and View together. It takes a user's request, gets the relevant model objects, and calls the appropriate view.
mpeters already mentioned several MVC frameworks for Perl. You'll also want to pick a templating engine. The two most popular are Template Toolkit and Mason.
Leaving the question of CGI vs MVC framework for the moment, what you're going to want is one of the output templating modules from the CPAN.
The Template Toolkit is very popular (Template.pm on CPAN)
Also popular are Text::Template, HTML::Template, and HTML::Mason.
HTML::Mason is much more than a template module, and as such might be a little too heavy for a simple CGI app, but is worth investigating a little while you're deciding which would be best for you.
Text::Template is reasonably simple, and uses Perl inside the templates, so you can loop over data and perform display logic in Perl. This is seen as both a pro and con by people.
HTML::Template is also small and simple. It implements its own small set of tags for if/then/else processing, variable setting, and looping. That's it. This is seen as both a pro and a con for the exact opposite reasons as Text::Template.
Template toolkit (TT) implements a very large, perlish template language that includes looping and logic, and much more.
I used HTML::Template one, and found I wanted a few more features. I then used Text::Template with success, but found its desire to twiddle with namespaces to be a little annoying. I've come to know and love Template Toolkit. For me it just feels right.
Your mileage may vary.
Of course, there is still the old "print HTML" method, sometimes a couple of print statements suffices. But you've hit upon the idea of separating your display from your main logic. Which is a good thing.
It's the first step down the road to Model/View/Controller (MVC) in which you keep separate your data model&business logic (your code that accepts the input, does something with it, and decides what needs to be output), your your input/output (Templates or print statements - HTML, PDF, etc.) , and the code that connects the two (CGI, CGI::Application, Catalyst MVC Framework, etc.). The idea being that a change to your data structure (in the Model) should not require changes to your output routines (View).
The Perl5 Wiki provides a good (though not yet complete) list of web frameworks & templates.
The comparison articles linked in the "templates" wiki entry is worth reading. I would also recommend reading this push style templating systems article on PerlMonks.
For templating then Template Toolkit is the one I've used most and can highly recommend it. There is also an O'Reilly book and is probably the most used template system in the Perl kingdom (inside or outside of web frameworks).
Another approach which I've been drawn more and more to is non template "builder" solutions. Modules like Template::Declare & HTML::AsSubs fit this bill.
One solution that I feel strikes the right balance in the Framework/Roll-your-own dilemma is the use of three key perl modules: CGI.pm, Template Toolkit , and DBI. With these three modules you can do elegant MVC programming that is easy to write and to maintain.
All three modules are very flexible with Template Toolkit (TT) allowing you to output data in html, XML, or even pdf if you need to. You can also include perl logic in TT, even add your database interface there. This makes your CGI scripts very small and easy to maintain, especially when you use the "standard" pragma.
It also allows you to put JavaScript and AJAXy stuff in the template itself which mimics the separation between client and server.
These three modules are among the most popular on CPAN, have excellent documentation and a broad user base. Plus developing with these means you can rather quickly move to mod_perl once you have prototyped your code giving you a quick transition to Apache's embedded perl environment.
All in all a compact yet flexible toolset.
You can also separate presentation out from code and just use a templating system without needing to bring in all the overhead of a full-blown framework. Template Toolkit can be used by itself in this fashion, as can Mason, although I tend to consider it to be more of a framework disguised as a templating system.
If you're really gung-ho about separating code from presentation, though, be aware that TT and Mason both allow (or even encourage, depending on which docs you read) executable code to be embedded in the templates. Personally, I feel that embedding code in your HTML is no better than embedding HTML in your code, so I tend to opt for HTML::Template.
Related
I have a client who wants me to design a new web app from scratch
The problem is that he wants me to use only core modules that come with perl (5.10 or 5.12)
Is there a way to write MVC apps with just CGI?
I know about Catalyst, Mojolicious and Dancer and how easy it is to do MVC with them, but I have no clue on how to do it with CGI alone
Are there any code examples that I could see and inspire from? (I've already googled but didn't find anything that I could use)
Also, like with Mojo and Dancer, is there any way I can generate links (Routes from Mojo, and Rails) from CGI?
Thanks
First off, what's the reason for the "core modules only" restriction? Does that also mean that you can't write any new modules of your own? The most effective solution would undoubtedly be to convince the client to let you use CPAN.
If you're allowed to write your own non-core modules, would you be able to get away with including a new module named "Prancer" which looks suspiciously like Dancer? (i.e., Grab the Dancer source tree and s/Dancer/Prancer/g across the whole thing, then add it to your project.)
But, if all else fails... yes, it's possible to at least use MVC principles and strong separation of concerns under CGI.pm, although you won't have an actual framework helping you with it unless you write that framework yourself. You'll also have to write any database abstraction layer and templating engine yourself, too. I know this is possible because I was doing it myself 5-10 years ago, back in the Dark Ages before I switched to Dancer. I can't offer any examples, though, because I've successfully forgotten where I buried those bodies.
I've been having an agruement with a friend that Mason (Perl) is not a framework, but a templating language. I feel Mason for Perl does what JSP does for Java (as an analogy, not pure technical comparison). From what I know, JSP is not a framework and I feel neither is Mason. When I looked up wikipedia Mason (Perl), I see that the main site says it is a web application framework written in Perl while the discussion page contests it.
Any pointers on why it is/ it is not a framework?
Update based on comments from ysth:
For a framework, I feel it should at least make db access easy, manage sessions, basic security that a webapp would need, templating and code reuse (or libraries that make basic tasks easy).
Mason is an 'M' short of being a MVC (Model-View-Controller) framework. It provides extensive rendering (View) features, which is why people think of Mason as being a templating language. However it also provides quite a few dispatch mechanisms (epsecially in the form of dhandlers), and control mechanisms (which fit naturally into autohandlers).
A few years ago I wrote an on-line tutorial (in Mason) to show off some of these features. It's optimised for full-screen display, and needs javascript enabled.
What Mason doesn't give you is a database abstraction layer, so you have to bring your own Model.
To the best of my knowledge amazon.com is written in Mason, along with many other sites.
If you enjoy working with Mason, but you'd like to have a Model, more toys, and a pony, then you may consider looking at Jifty as a web application framework.
A templating system would be something like HTML::Template, that is, a module that only does templating.
I feel that Mason does more, it has somehow a routing mechanism, it provides argument handling though %ARGS, intialisations through %INIT.
It also provides interfaces to mod_perl, CGI...
Now, it does not talk to the database, as if you want a clean way to do it, you'll have to use Class::DBI, DBIx::Perlish or one of the other hundred perl modules that does object mapping, or whatever else...
It is not an Model-View-Controller type of framework, it is probably closer to PHP than Ruby on Rails for example (and just as bad from what I have seen of it).
Can't answer the question to whether HTML::Mason is or isn't a framework without looking at it but I'm always happy with the following definition....
"a framework calls your program whereas your program calls a library"
Looking at Embedded Perl in HTML with Mason view of its competition, I'd say it is a template language. Otherwise Catalyst and Maypole would be on the list. Also, I think I read somewhere that you can use Mason as the View portion in a Catalyst application.
I guess I can see where you can use it like a framework, but it seems to be more complete if you view it as a template language.
Mason alone is not a framework it's just a template system BUT with some very cool features. It's got it's own structure and you can embed perl code very easely in it also it's got cache support. I've seen people who use Mason alone for developing a large application, but I guess it works better in an MVC framework.
Take care!
The following definition of a framework is taken from the Gamma book on Design Patterns. "A framework is a set of cooperating classes that make up a reusable design for a specific class of software." Mason, by that definition, is a framework. An MVC framework is only one type of framework.
HTML::Mason is what frameworks want to become when they get older. With HTML::Mason you get:
a dispatcher
templating
caching
logging
extremely flexible modularization
It was designed for high performance multi-tiered web applications, not for pleasing the fans of design patterns borrowed from desktop programming (such as MVC was).
Depends of your definition of framework.
You can apply name framework to any library if it does more than one thing.
A few years ago I did a lot of work with CGI.pm. I'm evaluating using it again for a quick project. Can someone bring me up to speed on the current state of developing with CGI.pm in the "Web 2.0" world? What are the best libraries on CPAN to use with it? Are there clean ways to include jQuery, YUI, other CSS libs, etc, and do some AJAX. There are of course lots of libraries on CPAN but what works and what is commonly used?
We aren't still doing this?
$JSCRIPT<<EOF;
...
EOF
I realize people are going to offer Catalyst as an answer. However, many people may have legacy CGI.pm apps they simply want to enhance. Is starting over really the best answer?
Personally, I'm no fan of Catalyst (too heavy for my taste) or Mason (mixing code and HTML is bad ju-ju), but I do quite well using CGI.pm for input[1], HTML::Template for output, and CGI::Ajax to provide AJAX functionality where called for.
If you're looking at frameworks, you may also want to consider CGI::Application, which is a widely-used and lighter-weight alternative to Catalyst/Mason.
[1] I can't recall the last time I called anything other than $q->param or $q->cookie from CGI.pm. There are still a lot of tutorials out there saying to use its HTML-generation functions, but that's still mixing code and HTML in a way that's just as bad as using here docs, if not worse.
Consider using something more modern, for example Catalyst. It will make your life much easier and you won't have to reinvent the wheel. I understand that it is just a small project, but from my experience many small projects in time become large ones :)
The "web 2.0" apps that I've worked with usually use client-side JavaScript to request JSON data from the server, then use that data to update the page in-place via DOM.
The JSON module is useful for returning structured data to a browser.
As far as including JavaScript, HTML, or whatever in a here doc - that was never a good idea, and still isn't. Instead, use one of the plethora of template modules to be found on CPAN. For a CGI, I'd avoid "heavy" modules like Mason or Template Toolkit, and use a lighter module for quicker startup, such as Text::Template, or Template::Simple.
Yes, you can write perfect web2.0 web applications WITHOUT using any framework on the server side in any language Perl, Python, Java, etc and WITHOUT using any JavaScript libraries/framework on the client side. The definition of web 2.0 is kind of a loose definition, and I'm guessing by web2.0, you mean Ajax or partial page refresh, then all you would really need is to focus on the following:
Know about the XmlHttpRequest object.
Know how to return JSON object from the server to the client.
Know how to safely evaluate/parse the JSON object using JavaScript and know to manipulate the DOM. Also, at least know about innerHTML. InnerHTML is helpful occasioanally.
Know CSS.
Having said that, it's a lot easier to use some framework on the server side, but not because it's required by web2.0 and it's a lot easier to use some JavaScript on the client like jQuery, mootools, YUI. And you can mix-and-match depends on your needs and your tastes. Most JavaScript provides wrapper around the XmlHttpRequest so that it works across all browsers. No one write "naked" XmlHttpRequest anymore, unless you want to show some samples.
It's perfectly possible to write "Web 2.0" apps using CGI.pm, but you'll have to do the work yourself. From what I've seen, the focus in the Perl development community has been on developing successor frameworks to CGI, not on writing helper modules to let legacy apps get bootstrapped into modern paradigms. So you're somewhat on your own.
As to whether to start over, what are you really trying to accomplish? Everyone's definition of "Web 2.0" is somewhat different.
If you're trying to introduce a few modern features (like AJAX) to a legacy app, then there's no reason you need to start over.
On the other hand if you're trying to write something that truly looks, feels, and works like a modern web app (for example, moving away from the page-load is app-state model), you should probably consider starting from the ground up. Trying to make that much of a transformation happen after the fact is going to be more trouble than it's worth for anything but the most trivial of apps.
I agree with Adam's answer, you probably want to use Catalyst. That being said, if you really don't want to, there's nothing preventing you from using only CGI.pm. The thing is, Catalyst is a collection of packages that do the things you want to make Web 2.0 easy. It combines the various templating engines such as Template Toolkit or Mason with the various ORM interfaces like DBIx::Class and Class::DBI.
Certainly you don't have to use these things to write Web 2.0 apps, it's just a good idea. Part of your question is wondering if javascript and CSS frameworks like jQuery, or prototype require anything from the server-side code. They don't, you can use them with any kind of server-side code you want.
For new apps, if you don't find Catalyst to your taste, Dancer is another lightweight framework you may like. There are also plenty of others, including CGI::Simple, Mojo/Mojolicious, Squatting...
Any of these lightweight frameworks can take care of the boring parts of web programming for you, and let you get on with writing the fun parts the way you want to.
If the jump from CGI.pm to Catalyst seems too daunting then perhaps something like Squatting might be more appropriate?
Squatting is a web microframework and I have found it ideal for quick prototyping and for replacing/upgrading my old CGI scripts.
I have recently built a small "web 2.0" app with Squatting using jQuery with no issues at all. Inside the CPAN distribution there is an example directory which contains some programs using jQuery and AJAX including a very interesting [COMET](http://en.wikipedia.org/wiki/Comet_(programming)) example which makes use of Continuity (which Squatting "squats" on by default).
NB. If required then you can later "squat" your app onto Catalyst with Squatting::On::Catalyst
There is also CGI::Ajax.
I'm looking at introducing multi-lingual support to a mature CGI application written in Perl. I had originally considered rolling my own solution using a Perl hash (stored on disk) for translation files but then I came across a CPAN module which appears to do just what I want (i18n).
Does anyone have any experience with internationalization (specifically the i18n CPAN module) in Perl? Is the i18n module the preferred method for multi-lingual support or should I reconsider a custom solution?
Thanks
There is a Perl Journal article on software localisation. It will provide you with a good idea of what you can expect when adding multi-lingual support. It's beautifully written and humourous.
Specifically, the article is written by the folks who wrote and maintain Locale::Maketext, so I would recommend that module simply based upon the amount of pain it is clear the authors have had to endure to make it work correctly.
If you have the time then do take a look at the way the I18N is done in the Jifty framework - although initially quite confusing it is very elegant and usable.
They overload _ so that you can use _("text to translate") anywhere in the code. These strings are then translated using Locale::Maketext as normal.
What makes it really powerful is that they defer the translation until the string is needed using Scalar::Defer so that you can start adding the strings at any time, even before you know which language they will be translated into. For example in config files etc. This really make I18N easy to work with.
i have a big web application running in perl CGI. It's running ok, it's well written, but as it was done in the past, all the html are defined hardcoded in the CGI calls, so as you could imagine, it's hard to mantain, improve and etc. So now i would like to start to add some templating and integrate with a framework (catalyst or CGI::application). My question is: Somebody here has an experience like that? There is any things that i must pay attention for? I'm aware that with both frameworks i can run native CGI scripts, so it's good because i can run both (CGI native ad "frameworked" code) together without any trauma. Any tips?
Write tests first (for example with Test::WWW::Mechanize). Then when you change things you always know if something breaks, and what it is that breaks.
Then extract HTML into templates, and commonly used subs into modules. After that it's a piece of cake to switch to a framework.
In general, go step by step so that you always have a working application.
Extricate the HTML from the processing logic in the CGI script. Identify all code that affects the HTML output, as these are candidates for becoming template variables. Separate that into a HTML file, with the identified parts marked with template variables. Eventually you will be able to refactor the page such that all processing is done at the start of the code and the HTML template just called up at the end of all processing.
In this kind of situation, rewriting from scratch basically, the old code is useful for A) testing, and B) design details. Ideally you'd make a set of tests, for all the basic functionality that you want to replicate, or at least tests that parse the final result pages so you can see the new code is returning the same information for the same inputs.
Design details within the code might be useless, depending on how much the framework handles automatically. If you have a good set of tests, and a straightforward conversion works well, you're done. If the behavior of the new doesn't match the old, you probably need to dig deeper into the "why?" and that'll probably be something odd looking, that doesn't make sense at first glance.
One thing to remember to do first is, find out if anyone has made something similar in the framework you're using. You could save yourself a LOT of time and money.
Here is how I did it using Python instead of Perl, but that should not matter:
Separated out HTML and code into distinct files. I used a template engine for that.
Created functions from the code which rendered a template with a set of parameters.
Organized the functions (which I termed views, inspired by Django) in a sensible way. (Admin views, User views, etc.) The views all follow the same calling convention!
Refactored out the database and request stuff so that the views would only contain view specific code (read: Handling GET, POST requests, etc. but nothing low-level!). Relied heavily on existing libraries for that.
I am here at the moment. :-) The next obvious step is of course:
Write a dispatcher which maps URLs to your views. This will also lead to nicer URLs and nicer 404- and error handling of course.
One of the assumptions that frameworks make is that the urls map to the code. For example in a framework you'll often see the following:
http://app.com/docs/list
http://app.com/docs/view/123
Usually though the old CGI scripts don't work like that, you're more likely to have something like:
http://app.com/docs.cgi?action=view&id=123
To take advantage of the framework you may well need to change all the urls. Whether you can do this, and how you keep old links working, may well form a large part of your decision.
Also frameworks provide support for some sort of ORM (object relational mapper) which abstracts the database calls and lets you only deal with objects. For Catalyst this is usually DBIx::Class. You should evaluate what the cost of switching to this will be.
You'll probably find that you want to do a complete rewrite, with the old code as a reference platform. This may be much less work than you expect. However start with a few toy sites to get a feel for whichever framework/orm/template you decide to go with.