Skip to content

Integrating with CGI::Application

dannyglue edited this page Aug 20, 2012 · 4 revisions

Integrating Rose::DBx::Object::Renderer with CGI::Application is very straightforward. We need 3 additional parameters for the rendering methods:

  1. query – to pass in the CGI query object, this is optional with plain CGI scripts, but mandatory in persistent environments, such as FCGI. It is a good practice to have this since it reuses the CGI object.
  2. queries – to keep track of the current runmode, and
  3. output – to return the generated UI (as opposed to printing it out)

Here is a complete CGI::Application that has two runmodes:

  1. A public view to showcase all the Projects
  2. A protected admin area where users must login using predefined credentials (username:admin, password:password)
package Application;
use strict;
use warnings;

use base 'CGI::Application';
use CGI::Application::Plugin::AutoRunmode;
use CGI::Application::Plugin::Authentication;

use Rose::DBx::Object::Renderer;

sub setup {
 my $self = shift;
 $self->authen->config(
  DRIVER => [
   ['Generic', sub {
    my $username = shift;
    my $password = shift;
    return unless $username && $password;
    return $username if $username eq 'admin' && $password eq 'password';
   }],
  ],
  STORE => ['Cookie', NAME => 'AUTH', SECRET => '39245872340', EXPIRY => '+1y']
 );
 
 my $renderer = Rose::DBx::Object::Renderer->new(
  config => {
   db => {type => 'Pg', name => 'application', username => 'postgres', password => '', tables_are_singular => 1},
   template => {path => '../templates'},
   upload => {path => '../htdocs/uploads', url => '/uploads'},
  },
  load => 1,
 );
}

sub start: Runmode {
 my $self = shift;
 Application::Project::Manager->render_as_table(
  query => $self->query,
  output => 1,
 )->{output};
} 

sub admin: Runmode Authen {
 my $self = shift;
 Application::Employee::Manager->render_as_menu(
  query => $self->query,
  output => 1,
  create => 1,
  edit => 1,
  copy => 1,
  delete => 1,
  searchable => 1,
  queries => {rm => $self->get_current_runmode},
  order => ['Application::Employee', 'Application::Position', 'Application::Project'],
 )->{output};
}

1;

We first create a new Renderer instance within the setup runmode to dynamically load all the tables within the given database. Since we’re using CGI::Application::Plugin::AutoRunmode, the start runmode will always be the default runmode, thus, we don’t need to pass the name of the runmode to render_as_table() using queries. In the admin runmode, we are using render_as_menu() with CRUD access for admin users to manage all the relevant table records.

CGI

A typical CGI script to run the above CGI App (Application.pm) would be:

#!/usr/bin/perl
use strict;
use warnings;

use CGI;
use CGI::Carp qw(fatalsToBrowser);

use FindBin::libs;
use Application;

Application->new->run();

FCGI

The FCGI equivalent would be:

#!/usr/bin/perl
use warnings;
use strict;
use FCGI;
use Application;

my $request = FCGI::Request();
while($request->Accept() >= 0) {
   CGI::_reset_globals();
   Application->new->run;
   $request->Finish();
}

exit(0);

Clone this wiki locally