简体   繁体   中英

Perl Dancer how to manage form actions

I'm learning perl Dancer and working on a to-do list depending on a form selection of two dates(today and tomorrow). If you select today a todo list for today will be generated, if you select tomorrow a different list will be created.

I've created a Dancer app called: Organizador and have the following in my Organizador.pm :

package Organizador;
use Dancer ':syntax';
use DBI;

our $VERSION = '0.1';
set session => "Simple";

get '/' => sub{
template 'index';  
}; 

get '/create_to_do_list'=>sub{
template 'create_to_do_list';
};

I've created a file called create_to_do_list.pl which contains the script that I would like to execute when the form is created.

<form action="create_to_do_list.pl">
<legend>Create todo list</legend>
        <label for="todoList">Create a todo list</label>
            <select name='todoList' id='todoList'>
                <option value="today">today</option>        
                <option value="tomorrow">tomorrow</option>
            </select>
            <button>Cancel</button>
            <button>Create</button>
</form>

How can I call create_to_do_list.pl as an action on template 'create_to_do_list'; after hitting the create button?

Thanks!

Firstly, before you go too far down this path, switch from Dancer to Dancer2.

From your comments, it seems that create_to_do_list.pl is a CGI program. Is it running on the same web server? You could probably call it remotely using something from LWP or HTTP::Tiny , but I don't think that's a very good idea - you'll get HTML back which you'll need to parse in some way to extract the useful information.

It's a far better idea to move the code from create_to_do_list.pl into a module. If the CGI program needs to exist as well (for historical reasons, perhaps) then move the core code into a module which can be used from both the CGI program and the new Dancer app. But if you won't need the CGI program once the Dancer app is ready, I'd just copy the code into the correct place in Organizador.pm.

Instead of using DBI directly, you might find it easier to switch to Dancer::Plugin::Database (or its Dancer2 equivalent ), bit for anything other than the simplest of database programs, I'd recommend DBIx::Class (and Dancer2::Plugin::DBIC ).

I wanted to move to Dancer so I thought there was a faster way of calling my script instead of having to copy it...I'm working with thousands of thousand of [CGI] to-do lists...

Ideally, you should convert all of your CGI scripts to modules so that you can use them in non-CGI contexts (eg unit tests, web frameworks like Dancer and Mojolicious); however, if you really have thousands of them, that will take a long time.

As a stop-gap measure while you work on the conversion, you can use CGI::Compile and CGI::Emulate::PSGI to create a PSGI wrapper around each of your unconverted CGI scripts. You can easily integrate these with a Dancer2* app using Plack::Builder .

For example, to integrate the following CGI script with a Dancer2 app:

use strict;
use warnings 'all';

use CGI;

my $q = CGI->new;
print $q->header,
      $q->start_html,
      $q->h1('Hello, CGI!'),
      $q->end_html;

Modify bin/app.psgi to look like this:

use strict;
use warnings 'all';

use FindBin;
use lib "$FindBin::Bin/../lib";

use CGI::Compile;
use CGI::Emulate::PSGI;
use Plack::Builder;

use MyApp;

my $foo_cgi = CGI::Compile->compile('/path/to/foo.cgi');

builder {
    mount '/'    => MyApp->to_app;
    mount '/foo' => CGI::Emulate::PSGI->handler($foo_cgi);
};

Now, requests to / will call the / route in MyApp, while requests to /foo will call your CGI script.

In your form, change:

<form action="create_to_do_list.pl">

to:

<form action="/foo">

Make sure the names of your form fields all match what the CGI script is expecting, and voila! You can keep using your CGI script without modification.

(Note that you could skip all the PSGI wrapper business and just continue serving your CGI scripts with Apache or whatever you were using before, but this approach allows you to centralize your routes and simplifies deployment.)

Add a separate mount statement for each CGI script you want to integrate with your app. Note that this approach will probably have performance problems , so you should only use it as a temporary measure while you work on converting your CGI scripts to proper modules.


* For new development, you should really be using Dancer2. Dancer1 is in maintenance mode and although it's still officially supported, it won't be getting any new features. I know you've had trouble getting started with Dancer2, but you should resolve those issues instead of using an old version of the framework. (And it's still unclear what exactly you were having trouble with; you should edit that question if you still need help.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM