The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

CGI::Builder::CgiAppAPI - Use CGI::Application API with CGI::Builder

VERSION 1.27

The latest versions changes are reported in the Changes file in this distribution. To have the complete list of all the extensions of the CBF, see "Extensions List" in CGI::Builder

INSTALLATION

Prerequisites
    CGI::Builder >= 1.3
    
CPAN
    perl -MCPAN -e 'install CGI::Builder::CgiAppAPI'

You have also the possibility to use the Bundle to install all the extensions and prerequisites of the CBF in just one step. Please, notice that the Bundle will install A LOT of modules that you might not need, so use it specially if you want to extensively try the CBF.

    perl -MCPAN -e 'install Bundle::CGI::Builder::Complete'
Standard installation

From the directory where this file is located, type:

    perl Makefile.PL
    make
    make test
    make install

SYNOPSIS

   # In your old cgiapp implementation
   # change the follow line
   # use base qw( CGI::Application ) ; # or 'CGI::Application::Plus'
   
   # with this (to use the same cgiapp under CBF)
   use CGI::Builder
   qw| CGI::Builder::CgiAppAPI
     |;
   
   # this will provide you useful hints
   $CGI::Builder::CgiAppAPI::hints = 1 ;
   
   # when your migration is completed
   # just get rid of the CGI::Builder::CgiAppAPI
   use CGI::Builder ;
   

DESCRIPTION

Note: You should know CGI::Builder.

This module supplies an API compatible with the CGI::Application or CGI::Application::Plus APIs. It transparently provides all the aliases, defaults and method redefinition to make the old cgiapps work unchanged under CBF as well. Besides, it provides also very useful run-time hints that will suggest you what to change in your old code and what to read in this documentation in order to smoothly trasform your old cgiapp into a CGI::Builder application or simply learn the CBF faster.

WARNING: This module is not intended to be used neither as an alternative API for the CBF nor in a production environment. You should use it only as:

  • the glue-code to add new CBF methods and capability to your old cgiapps, thus temporarily running applications implementing mixed APIs

  • a substantial aid to the migration process from an old cgiapp to the CBF

  • a startup aid to learn (faster) the CBF API (just if you are familiar with the cgiapp API)

IMPORTANT: This API is compatible with the CGI::Application 3.1. The API of successive CGI::Application versions may or may not work as well; I have no plan to update this module to maintain API compatibility.

LEARNING WITH THIS API

If you are familiar with cgiapp API, you can use this module as an aid to quickly learn how to change your 'cgiapp abits'. Just build your application including it, and switch the hints ON:

   # define your build
   use CGI::Builder
   qw| CGI::Builder::CgiAppAPI
     |;
   
   # switch the hints ON
   $CGI::Builder::CgiAppAPI::hints = 1 ;

Then start to code as you already know (i.e. use the old cgiapp API), and run your code as soon as it is ready to be tried. You will receive the warnings that will 'teach' you the new API, and will suggest you what to change and what to read in the documentation.

When you have learned enough, just get rid of this module, and use the CBF API alone.

MIGRATING

Step by step instructions

1 Define the CBB including this API

As the first step just change the old dependency with the new one. For example:

    # take off this statement
    use base qw(CGI::Application);
    
    # and substitute it with the following one
    use CGI::Builder
    qw| CGI::Builder::CgiAppAPI
      |;

These are all the possible configurations for all the possible modules covered by this API. Use the one that apply:

CGI::Application
   use CGI::Builder
   qw| CGI::Builder::CgiAppAPI
     |;
CGI::Application::Plus
   use CGI::Builder
   qw| CGI::Builder::CgiAppAPI
     |;
Apache::Application::Plus
   use Apache::CGI::Builder
   qw| CGI::Builder::CgiAppAPI
     |;
CGI::Application::Magic
   use CGI::Builder
   qw| CGI::Builder::Magic
       CGI::Builder::CgiAppAPI
     |;
Apache::Application::Magic
   use Apache::CGI::Builder
   qw| CGI::Builder::Magic
       CGI::Builder::CgiAppAPI
     |;
CGI::Application::CheckRM

Just add CGI::Builder::DFVCheck to some of the previous configurations:

   use CGI::Builder
   qw| ...
       CGI::Builder::DFVCheck
       CGI::Builder::CgiAppAPI
     |;
2 Check it

Try to run your application. It should run without errors, but if you have some problem, please refer to the "COMPATIBILITY" section before continuing.

3 Include the hints

This module provides all the hints that you need in order to change your code to the new API. Just add this line:

   $CGI::Builder::CgiAppAPI::hints = 1 ;

From now on, when you run your application you will receive a ton of warnings :-), telling you things such as "Just change "this" with "that" ....". Don't worry, you are about to change everything in a very short time.

3 Get rid of warnings

Every single old API statement is producing a warning, but this does not mean that you have to go through every single line in your code one by one. Most warnings can be eliminated just by doing a "Serch and Replace" in your code.

You can recognize these warning because they start with "Just change...", so take the first one of them and do a "Search and Replace" in your code as suggested. Then re-run your application and take the next "Just change..." hint, do another "Search and Replace" with its suggested changes and so on.

In very few steps, the hints will be reduced to a very few. Please, remember that the hints explain you just the basics about the needed change, but you should take a look to the specific details in the section "CHANGES".

Known Issue: Although the description hint is always right, the indication of the line that needs to be changed in your code might be incorrect for a few handlers.

4 Get rid of this API

When you will not receive any warning any more, you will have done with the migration and with this module. Just take off the 'CGI::Builder::CgiAppAPI' from the build list.

5 Use the new defaults

at this point your CBB is running with the new CBF defaults, so remember that:

  • The default page_name is now 'index' instead of 'start'

  • The default prefix for your page handlers is 'PH_' instead of 'RM_'

  • The default cgi_page_param (former mode_param) is now 'p' instead of 'rm'

COMPATIBILITY

Note: An old cgiapp implementation should run unchanged under CGI::Builder::CgiAppAPI as well, but the compatibility could be compromised if your application uses some dirty hack that bypass accessors i.e. some statements that interacts with the internal hash structure of the old class, something like $self->{__PARAMS}, because CGI::Builder implements a more consistent but different internal structure (see "The Internal Structure" in CGI::Builder).

param() ( CGI::Application specific )

CGI::Builder::CgiAppAPI implements on purpose a little but useful difference that could eventually break your old cgiapp code but ONLY in the rare case that your code rely on the returned value of the param() method in scalar context.

This are the differences:

    # CGI::Application param() in scalar context
    $par = $s->param() ;                  # $par == number of params || undef
    $par = $s->param(myPar =>'myPARAM') ; # $par eq 'myPARAM'
    $par = $s->param(myPar1=>'myPARAM1',  # $par is undef
                     myPar2=>'myPARAM2') ;
    $par = $s->param('myPar') ;           # $par eq 'myPARAM'
    @params = $s->param()                 # keys %$par
    
    # CGI::Builder::CgiAppAPI::param() in scalar context
    $par = $s->param() ;                  # ref $par eq 'HASH'
    $par = $s->param(myPar =>'myPARAM') ; # ref $par eq 'HASH'
    $par = $s->param(myPar1=>'myPARAM1',  # ref $par eq 'HASH'
                     myPar2=>'myPARAM2') ;
    $par = $s->param('myPar') ;           # $par eq 'myPARAM'
    %params = $s->param()                 # dereferenced

As you see, in scalar context the param() method returns the reference to the underlying hash containing the parameters. This allows you to interact directly with the whole hash, or checking and deleting single parameters very easily:

    $P = $s->param ;
    while ( my ($p, $v) = each %$P )
    { do_something_useful }
    
    # check if exists a parameter
    exists $s->param->{myPar} ;
    
    # delete a parameter
    delete $s->param->{myPar} ;

In list context the param() returns a copy of the parameter hash.

API CONVERSION TABLE (quick reference)

    CGI::Application[::Plus]      CGI::Builder
    ========================      ============
    mode_param [default:'rm']     cgi_page_param [default:'p']
    start_mode [default:'start']  page_name  [default:'index']
    get_current_runmode           page_name
    QUERY                         cgi
    query                         cgi
    cgiapp_get_query              cgi_new
    PARAMS                        param
    TMPL_PATH                     page_path
    tmpl_path                     page_path
    prerun_mode                   switch_to
    header_prop                   header
    header_add                    header
    header_type                   redirect | dont_send_header | -
    run_modes                     page_handler_map
    run                           process
    cgiapp_init                   OH_init
    startup                       OH_init
    cgiapp_prerun                 OH_pre_process
    cgiapp_postrun                OH_fixup
    teardown                      OH_cleanup
    dump                          CGI::Builder::Test::dump
    dump_html                     CGI::Builder::Test::dump_html
    load_tmpl                     - | CGI::Builder::HTMLtmpl
    $ENV{CGI_APP_RETURN_ONLY}     capture('process')

    CGI::Application::Plus        CGI::Builder
    ======================        ============
    runmode [default:'start']     page_name [default:'index']
    RM_prefix [default:'RM_']     'PH_' (constant value)
    page                          page_content
    start_capture                 capture
    stop_capture                  capture
    qparam                        --

CHANGES

The CBF implements a different metaphor based on 'processing pages' instead of 'running applications'. This should be simpler to understand (specially for beginners) because it is more consistent with the specific task that a CGI::Builder application performs.

Even if the internal implementation of similar methods is greatly improved and has a completely different internal code, from the user point of view most changes here don't require more than a simple translation of identifier from one concept to the other, while just a few changes need little more attention.

The CGI::Application philosophy is very simple: the application defines several run methods, and each run method is organized to produce and return its own output page. You have to set a map in the application to define what run method has to be called for each run mode (the runmodes() method does that map). This creates a pretty rigid structure.

The CBF let you organize your application in a far more flexible way, it just need to find some page_content to send to the client: it does not matter what method or handler has set it during the process, (and the page_content itself might even be a reference to some CODE that will print the output on its own).

This flexible structure open several handy and powerful possibilities to your application and to the extension system. If you want to know some more details about that, you could read "Exclusive Features and Improvements" in CGI::Application::Plus which is the ancestor of the CBF framework.

Note: The changes reported below are needed just if you want to completely convert your old cgiapp to the CBF. Until you include this API in your build, they are transparently added to your application.

mode_param

Change it with cgi_page_param.

mode_param is used to define the query parameter that holds the run mode, and its default is 'rm'. The CGI::Builder property to use is the cgi_page_param and its default is 'p', so if your old cgiapp rely on the default, you should either set exlicitly the cgi_page_param property to the old default 'rm', or change all the links to the new default 'p'.

    # (simpler) solution 1: put this line in the OH_init()
    $s->cgi_page_param = 'rm';
    
    # solution 2: change the links like: '/webapp.cgi?rm=myRunmode'
    # to '/webapp.cgi?p=myRunmode'

Besides, the old mode_param accepted as well a CODE reference returning the page name, while cgi_page_param doesn't. In this case - if you want to generate the page name by some sub - you should just override the get_page_name() method, and set explicitly the page_name property:

    sub get_page_name {
        my $s= shift;
        ... your code to get the page name ...
        $s->page_name = $resulting_page_name
    }

start_mode, get_current_runmode, runmode

Change them with page_name (i.e. the cgiapp runmode).

start_mode, get_current_runmode (and runmode in CGI::Application::Plus) are used to set and get the (start) run mode (i.e. the CGI::Builder page name). You should use the page_name property instead.

    $s->page_name = 'mystart'
    $s->page_name  # always returns the current page name

Important Note: Remember that the default page_name is 'index' while the default run mode was 'start' so if you get rid of this API after a migration you should consider this new default.

QUERY and query

Change them with cgi.

QUERY (and query in CGI::Application::Plus) are used to pass a cgi object with the new() method. You should use cgi property instead.

    $webapp = WebApp->new(cgi=>CGI->new) ;
    # or
    $s->cgi = CGI->new ;

cgiapp_get_query

Just change it with cgi_new.

PARAMS

Change them with param.

PARAMS is used to pass a reference to an hash containing some param with the new() method or to set some application param. The CBF accessor to set and retrieve your application param is the param() property group accessor, you should use it instead.

TMPL_PATH and tmpl_path

Change them with page_path.

TMPL_PATH (and tmpl_path in CGI::Application::Plus) are used to pass a template path with the new() method. You should use page_path property instead

    $webapp = WebApp->new(page_path=>'/mypath')

prerun_mode

Just change it with switch_to.

Used to set the prerun mode. You should use switch_to() method instead.

    $s->switch_to('myRunmode')

header_prop and header_add

Change it with header().

header_prop() and header_add() are used to manage header. You should use the header() property group accessor instead. With it you can add, delete, retrieve, check for existance, ...

header_type

Used to set the type of header among 'header', 'redirect' and 'none'. You don't need to use it anymore. When you want to redirect you should use the redirect(url) method, and if you don't want to send any header, just set the dont_send_header property to a true value.

run_modes

Change it with page_handler_map.

run_modes is used to define a run method for each run mode, but since the CGI::Builder uses the Page Handler prefix (default 'PH_') to find and execute the page handler for each page_name, you need to use page_handler_map just if you want to map some page_name to a specific page handler. For example:

    # this page Handler (run method) does not need to be
    # declared with page_handler_map()  and will be
    # executed automatically by page_name 'myPage'
    
    sub PH_myPage {
        do_something_useful
    }

    # the 'some_special_handler' method will be executed
    # when the page_name will be 'mySpecialPage'
    $s->page_handler_map(mySpecialPage => 'some_special_handler')

run

Just change it with process.

cgiapp_init and startup

Just change them with OH_init.

cgiapp_prerun

Just change it with OH_pre_process.

cgiapp_postrun

Change it with OH_fixup.

Under CGI::Builder::CgiAppAPI the cgiapp_postrun will receive the reference to the output content in $_[1] as usual, but the CGI::Builder OH_fixup() will not receive that parameter, so it should handle this by using the page_content property.

    sub OH_fixup {
       # my ($s) = @_ ;
       my $content = $s->page_content ;
    }

teardown

Just change it with OH_cleanup.

dump and dump_html

You should include CGI::Builder::Test in order to use dump and dump_html methods:

    use CGI::Builder
    qw| CGI::Builder::Test
        ... other inclusions ...
      |;

load_tmpl

This module supply the old load_tmpl method, but you should include the CGI::Builder::HTMLtmpl in your CBB that offers a more powerful integration with HTML::Template.

    use CGI::Builder
    qw| CGI::Builder::HTMLtmpl
        ... other inclusions ...
      |;

$ENV{CGI_APP_RETURN_ONLY}

This works only with run() and not with process(): use the capture method if you need to test the output.

    $webapp = WebApp->new();
    $ref_to_output = $webapp->capture('process')

AUTOLOAD runmode

Under CGI::Builder the AUTOLOAD run method will not receive the runmode as the argument because it is always available with the page_name property, so you should use that property instead:

    sub myAutoloadRM {
       # my ($s, $runmode) = @_ ;
       # previous line changed with the following two lines
       my ($s) = @_ ;
       my $runmode = $s->page_name ;
    }

CHANGES (CGI::Application::Plus Specific)

The changes reported in this section are specific for CGI::Application::Plus only: i.e. they don't apply to simple CGI::Application.

RM_prefix

This property accessor is not supported by the CBF which uses the 'PH_' constant prefix instead. You should change the prefix of all your methods to the 'PH_' constant:

    # sub RM_foo { ... }
    # become
    sub PH_foo { ... }

page

Just change it with page_content.

start_capture and stop_capture

Use capture instead.

start_capture and stop_capture methods are used to capture the output, either for testing purpose or in a cgiapp_postrun method. You should use the new CGI::Builder method capture that does the same in a simpler and efficient way.

    # old way
    $s->start_capture() ;
    $s->run();                       # CBF process()
    $$captured = $s->stop_capture ;
    # now $captured is the ref to the captured output
    
    # becomes
    $captured = $s->capture('process')
    # now $captured is the ref to the captured output

Used in a cgiapp_postrun it was:

    sub cgiapp_postrun
    {
      my ($s, $ref) = @_ ;         # $ref always the same as $s->page
      if (ref $ref eq 'CODE')
      {
        $s->start_capture() ;
        $ref->($s) ;               # executes $ref CODE (print)
        $$ref = $s->stop_capture ; # now $ref is the ref to the content
      }
      # do something with $ref as usual
    }

Now, used in a CGI::Builder OH_fixup becomes more explicitly:

  sub OH_fixup {
      my $s = shift ;
      if (ref $s->page_content eq 'CODE')  {
          # executes the referenced CODE and captures the output
          $s->page_content = $s->capture($s->page_content)
      }
      # do something with $s->page_content as usual
  }

qparam

This property group accessor is not supported by the CBF. You can use the $s->cgi->param(), the $s->cgi->Vars() methods or - if you really like it - you can implement it in your own CBB by just adding these lines:

    use Object::groups
        ( { name    => 'qparam',
            default => sub { eval{ scalar $_[0]->cgi->Vars }
                              || croak qq(The cgi object cannot "Vars", you )
                                     . qq(cannot use the "qparam" property.)
                           }
          }
        );

checkRM

Change the checkRM() method provided by CGI::Application::CheckRM with the dfv_check() method provided by CGI::Builder::DFVCheck.

tm_defaults

Change the tm_defaults() group accessor provided by CGI::Application::Magic with the tm_new_args() group accessor provided by CGI::Builder::Magic.

request

Change the request() property accessor provided by Apache::Application::Plus with the r property accessor provided by Apache::CGI::Builder.

SUPPORT

See "SUPPORT" in CGI::Builder.

AUTHOR and COPYRIGHT

© 2004 by Domizio Demichelis (http://perl.4pro.net)

All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the same terms as perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 1020:

Non-ASCII character seen before =encoding in '©'. Assuming CP1252