nysus has asked for the wisdom of the Perl Monks concerning the following question:

So I started building my own web app framework on top of mod_perl with jQuery Mobile for my front end. It was mostly done as an exercise for fun and learning. It's far enough along where I can make some pretty sophisticated forms with a few lines of code. It's far from complete but I feel comfortable with it because I wrote it myself and I know exactly how it works. I know how to get and save data to the database. If I kept going, I could improve upon it and add more and more capabilities and efficiencies.

Of course, it's not 2005 anymore. Many frameworks exists. Rolling your own is probably crazy...or is it?

I just downloaded and installed Dancer2. I got the sample app running. I spent about an hour looking it over. Here's some sample code from the tutorial:

<h2>Login</h2> [% IF err %]<p class=error><strong>Error:</strong> [% err %][% END %] <form actione="[\% processor_url %]" method=post> <dl> <dt>Name: <dd><input type=text name=name> <dt>Another field: <dd><input type=text name=text> <dd><input type=submit value=Submit> </dl> </form>

And with that sample code, I am less than impressed with what I see. I don't want to have to write what looks essentially like HTML with embedded Perl. I want to write high level code that generates as much HTML and javascript logic for me as possible.

Now, please compare the above with a sample from my code which generates this form:

sub handler { my $r = shift; my $html = MyApache2::AppPage->new({reqrec => $r, title => 'Upload F +ile'}); $html->add_header('header', { fixed => 1 }); $html->add_pages([ { title => 'Upload file', id => 'upload_file', ca +che => 1 }, ]); my $navbar = &MyApache2::Admin::Upload::generate_nav($html); $html->add_navbar($navbar); $html->add_content('upload_file', 'h1', 'Upload voter data file'); $html->add_content('upload_file', 'p', 'You can upload voter data he +re. Upload the file and choose the type of data you are uploading. There are two kinds of data you can upload +. One is a list of registered voters an d associated information called a <b>"Voter registration file."</b> Th +e other is a list of voters who partici pated in a particular election called a <b>"Voter activity file."</b>' +); my $form = $html->create_comp('form', 'ul_form', {method => 'post', +enctype => "multipart/form-data"}); $form->add_element('file', 'file_upload_field', {required => 1, allowed_exts => ['c +sv'], label => 'File (csv + format only)'}); $form->add_element('selectmenu', 'file_type', { label => 'Data file type', options => ['Voter registration file', 'Voter activity file'], required => 1, options_label => 'Select voter data type...', unhide => {'activity_data' => ['Voter activity file'], 'reg_data' => ['Voter registration file'], }, }); my $reg_fields = $form->add_element('html', 'reg_data', { hide => 1, + show_container => 1}); $form->add_element($reg_fields, 'textfield', 'date', { label => 'Date data was created', subtype => 'date', required => 1 }); my $act_fields = $form->add_element('html', 'activity_data', { hide +=> 1, show_container => 1 }); $form->add_element($act_fields, 'textfield', 'election_date', { subtype => 'date', label => 'Election Date', required => 1 }); $form->add_element($act_fields, 'textfield', 'election_desc', {label => 'Description of election', required => 1 }); $html->add_content('upload_file', $form); $html->generate; return Apache2::Const::OK; }

This simple amount of code results in a page that looks like this.. And so with a couple of off-the-shelf javascript libraries and my own HTML generation engine, I can crank out a pretty sophisticated form with fancy validation and javascript enhancements pretty easily. And, with my system, I can code in Perl, not in some pseudo HTML.

So, to get to my question, am I going to be able to crank out some sophisticated stuff with a few lines of code with Dancer? Is it going to limit my ability to automate the generation of HTML as much as possible? What, exactly, does Dancer buy me?

I'm pretty sure Dancer2 is more than likely the superior approach because people a lot smarter than me are using it. I'll admit I'm ignorant. But, still, I'm just not seeing the advantage right now. Can someone please set me straight?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: To Dance or not to Dance with Dancer2? That is the question.
by 1nickt (Canon) on Dec 05, 2017 at 01:02 UTC

    Hi, you rather seem to have formed your opinion already. But what you showed is a Template Toolkit template. It's nothing to do with writing application code in Perl for use with Dancer or any other PSGI application or any other solution.

    With Dancer2, as with most web app frameworks, you *may* use a templating engine to generate the HTML your clients see. You *may* use Template if you go that route. You also might return JSON and have a client-side framework such as AngularJS generate all of the HTML. Or you might use any of a million other solutions. It's completely up to you what you output and how you send it.

    As for what Dancer2 "buys you," it buys you the ability to begin making web apps instead of trying to make a framework to make webapps.


    The way forward always starts with a minimal test.

      No, I haven't made up my mind at all. I'm just playing kind of devil's advocate and trying to wrap my head around what Dancer2 can help me do. I've had a lot of fun developing my own method of generating HTML code with a bunch of Moose objects. I think what I'd like to do is marry my little HTML writing engine with Dancer2. I'm just not clear on how to get there at this point and I'm also unclear if I can make it super fast.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

Re: To Dance or not to Dance with Dancer2? That is the question.
by stevieb (Canon) on Dec 05, 2017 at 01:42 UTC
    "What, exactly, does Dancer buy me?

    Hundreds of plugins to do all manner of everything easily, ability to connect to any conceivable backend for data storage, abstraction levels that are extremely remarkable while completely independent, sessions, authentication, trivially simple route handling, significant list of features to incorporate functionality within routes, page redirection, configuration management etc etc.

    As 1nickt said, you're looking at HTML templates. Something must be used to display data to your user; the HTML has to be generated somehow. Dancer2 is not limited in scope to just simple forms; it's a full blown framework with one hell of a lot of features, but with that said, extremely simple to get up and going. Look Ma, no webserver setup to test!

    App::RPi::EnvUI, a single-page web application to automate indoor grow room environments. Has authentication for all routes that perform db write operations, includes a bunch of JS and CSS in the "views" directory (some off-the-shelf, the rest my own), spins off asynchronous events that performs various actions, has a separate singleton API module, a separate singleton DB module for all backend data storage, sessions, two HTML templates (in "views" dir, one for the main page, the other for statistics) etc. It's a lot more elaborate than a simple web form, but I digress. The lib/App/RPi/EnvUI/EnvUI.pm file is the one that contains the Dancer code.

    Once your template/HTML output mechanism is in place, it's all Perl code after that essentially. I use JSON extensively for passing data back and forth between the web front-end and the Perl backend.

    To be honest, after quickly reviewing your code snip, it looks like you've created more of an HTML page builder than a web framework (again, after only a cursory glance).

      Ah, I think you've put your finger on it. You are correct, I have built an HTML generation engine specific to my needs (with a wee bit of framework features like cookie authentication). And what I'm hoping to do is marry my humble little engine with Dancer2. If you are telling me I can do that, I'm all in on Dancer2. But then my question is, can I make it super fast like with mod_perl? With mod_perl, I have my entire HTML generation engine in memory and it spits out code really fast. Will using something like uwsgi get me there?

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

Re: To Dance or not to Dance with Dancer2? That is the question.
by dsheroh (Monsignor) on Dec 06, 2017 at 08:25 UTC
    We seem to have established that the question isn't really "Dancer vs. my homebrew webapp framework", but rather "templated HTML vs. my homebrew HTML generator". So, then, what do templates buy you?

    Simplicity, for one. I glance at the TT (Template Toolkit) template in your post and immediately understand what it is, what fields the form has, etc. Aside from being several times as long, I need to actually read your HTML generation code and think about what it says before I can figure out what it's going to create. To be honest, when I read your post and saw "I'm not impressed with this small HTML template and consider this huge mass of Perl to be a 'simple amount of code'", I initially suspected you were joking.

    The biggest thing that using templated HTML instead of generated HTML buys you, though, is separation of concerns. Your Perl code just stuffs all the data into a hash (or whatever other data structure) and hands it off to the template engine, then the template engine uses the template to figure out how to display that. This lets you do things like provide a basic HTML version of some data, a fancy HTML version of that same data, an XML version to feed to other software, a JSON version to feed to yet other software, and a CSV version for exports, all with no changes to the Perl code. All you have to do is specify a different template to the same underlying data structure.

    A nice side effect of this separation is that, if you don't want to get your hands dirty with HTML editing (and I can't blame you; I avoid the stuff as much as I can, too), you can pass it off to actual web designers and let them create hand-crafted, artisanal HTML with all the bells and whistles and latest design fads, then turn that into a template (usually a simple process, or, if you're lucky, you might find a designer willing to learn to create templates himself) and you're good to go. And when the next design fad hits, it's just a new template away. You can even keep the old template available and let users choose which version they want to see.

      Excellent point: TT is instantly recognizable by anyone who has ever dealt with TT. I didn't even notice how instantly that was.

Re: To Dance or not to Dance with Dancer2? That is the question.
by Dallaylaen (Chaplain) on Dec 05, 2017 at 13:55 UTC

    Be careful when mocking Template::Toolkit. It's quite powerful, in fact more powerful than it should be - it's a Turing-complete language.

    The whole idea of Template (or any comparable renderer, say Text::Xslate, dozens of them) is the separation of logic from presentation - but with a very flexible presentation layer. You just give the templating engine a template and a hash of values - and the engine does the rest. Templates are much easier to edit than general-purpose code. I'm never ever coming back to $form->addElement("foo")->addValue("bar");

    Dancer example shows only variable substitution for simplicity, but Template can do way more than that.

    • Conditionals with [% IF foo == bar %]...[% END %];
    • looping with [% WHILE cond %]...[% END %];
    • iterating over data [% FOREACH item IN list %] * [% item | html %];[% END %];
    • sanitizing/escaping/trimming strings [% GET username | html %];
    • filtering them through predefined perl functions [% FILTER myfunc %]some text here[% END %];
    • , inclusion of external files (say headers/footers) [% PROCESS file %] or [% INCLUDE file %] and - last but not least -
    • defining your own blocks to avoid boilerplate/repetitions: [% BLOCK foo %]...[% END %] and then [% PROCESS foo option="value" %]

    See Template documentation for more examples. I didn't have time to google a comprehensive portfolio though.

Re: To Dance or not to Dance with Dancer2? That is the question.
by Anonymous Monk on Dec 05, 2017 at 03:53 UTC

      Yeah, that fairly closely resembles the kind of thing I'd like to do. I want to write as little HTML and javascript as possible. Then the questions becomes, can it be super fast? I was using mod_perl because that was what I was familiar with and it could crank out code very quickly.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest";
      $nysus = $PM . ' ' . $MCF;
      Click here if you love Perl Monks

        I found that trying to push as much stuff as possible into Perl is possible but usually not worth the effort, at least for SQL, Javascript and HTML.

        Personally, I write those parts natively and include them, at least until I have completely understood the problem space. When using "integrated" solutions, I usually find myself running up to the limits of the integration and then fighting the framework that adapts Perl to whatever output I want, instead of actually solving the problem.

        But if you're doing it for the fun of it, and for exploratory purposes, have a look at Jifty, which did lots of interesting high-traffic integration of Perl and Javascript, by generating Perl code to generate Javascript components from component templates.