Bigtop::Backend::Control::Gantry - controller generator for the Gantry framework
Build a file like this called my.bigtop:
config {
base_dir `/home/username`;
Control Gantry {}
}
app App::Name {
controller SomeController {}
}
Then run this command:
bigtop my.bigtop Control
When your bigtop config includes Control Gantry, this module will be loaded by
Bigtop::Parser when bigtop is run with all or Control in its build list.
This module builds files in the lib subdirectory of
base_dir/App-Name. (But you can change name by supplying app_dir, as
explained in Bigtop::Parser's pod.)
There will generally be two files for each controller you define.
One will have the name you give it with the app name in front. For the
SYNOPSIS example, that file will be called
/home/username/App-Name/lib/App/Name/SomeController.pm
I call this file the stub. It won't have much useful code in it,
though it might have method stubs depending on what's in its controller
block.
The other file will have generated code in it. As such it will go
in the GEN subdirectory of the directory where the stub lives. In the
example, the name will be:
/home/username/App-Name/lib/App/Name/GEN/SomeController.pm
During the intial build, both of these files will be made.
Subsequently, the stub will not be regenerated (unless you delete it), but
the GEN file will be. To prevent regeneration you may either put no_gen in
the Control Gantry block of the config, like this:
config {
...
Control Gantry { no_gen 1; }
}
or you may mark the controller itself:
controller SomeController {
no_gen 1;
}
Each controller has the form
controller name is type {
keyword arg, list;
method name is type {
keyword arg, list;
}
}
For a list of the keywords you can include in the controller block
see the pod for Bigtop::Control. For a list of the keywords you can include
in the method block, see below (and note that most of these vary by the
method's type).
The controller phrase 'is type' is optional and defaults to 'is
stub' which has no effect. The supported types are:
- AutoCRUD
- This simply adds Gantry::Plugins::AutoCRUD to your uses list (it will
create the list if you don't have one). Do not manually put
Gantry::Plugins::AutoCRUD in the uses list if you use type AutoCRUD, or it
will have two use statements.
- CRUD
- This adds Gantry::Plugins::CRUD to your uses list (it will create the list
if you don't have one). As with AutoCRUD, don't manually put
Gantry::Plugins::CRUD in your uses list if you set the type to CRUD.
In addition to modifying your uses list, this type will make
extra code. Each time it sees a method of type AutoCRUD_form, it will
make the following things (suppose the AutoCRUD_form method is called
my_crud_form):
- form method
- This method will be suitable for use as the form named parameter to the
Gantry::Plugins::CRUD constructor.
You get this whether you set the controller type to CRUD or
not.
- constructed crud object
-
my $my_crud = Gantry::Plugins::CRUD->new(
add_action => \&my_crud_add,
edit_action => \&my_crud_edit,
delete_action => \&my_crud_delete,
form => \&my_crud_form,
redirect => \&my_crud_redirect,
text_descr => 'your text_description here',
);
- redirect method
- Replicates the default behavior of always sending the user back to
$self->location on successful save or
cancel.
- do_* methods
- A set of methods for add, edit, and delete which Gantry's handler will
call. These are stubs. Example:
#-------------------------------------------------
# $self->do_add( )
#-------------------------------------------------
sub do_add {
my $self = shift;
$crud->add( $self, { data => \@_ } );
}
Note that you should do something better with the data. This
method leaves you having to fish through an array in the action method,
and therefore makes it harder for code readers to find out what is in
the data.
- action methods
- A set of methods corresponding to do_add, do_edit, and do_delete which are
specified during the construction of the crud object. Example:
#-------------------------------------------------
# $self->my_crud_add( $id )
#-------------------------------------------------
sub my_crud_add {
my ( $self, $params, $data ) = @_;
my $row = $YOUR_CONTROLLED_TABLE->create( $param );
$row->dbi_commit();
}
Note that the new object creation code a Class::DBI style API
can be called against the model alias of the table this controller
controls. That won't work if you are controlling multiple tables. The
same holds for the edit and delete methods.
Note that all generated names are based on the name of the form
method. The name is made with a brain dead regex which simply strips _form
from that name.
Most of the method keywords depend on the method's type. This one doesn't:
- extra_args
- Make this a comma separated list of arguments your method should expect.
Example:
extra_args `$cust_id`, `@params`;
Note that there is almost no magic here. These will simply be
added to the method's opening comment and argument capturing code. So if
the above example appeared in a handler method, the stub would look
roughly like this:
#--------------------------------------------------
# $self->method_name( $cust_id, @params )
#--------------------------------------------------
sub method_name {
my ( $self, $cust_id, @params ) = @_;
}
Note Well: Gantry's handlers must be called do_*. The leading do_ will not be
magically supplied. Type it yourself.
Each method must have a type. This backend supports the following
types (where support may vary depending on the type):
- stub
- Generates an empty method body. (But it handles arguments, see extra_args
above.)
- main_listing
- Generates a method, which you should probably name do_main, which produces
a listing of all the items in a table sorted by the columns in the table's
foreign_display.
You may include the following keys in the method block:
- rows
- An integer number of rows to display on each page of main listing output.
There is no default. If you omit this, you get all the rows, which is
painful if there are very many.
You must be using DBIx::Class for this to be effective.
- cols
- This is the list of columns that should appear in the listing. More than 5
or 6 will likely look funny. Use the field names from the table you are
controlling.
- col_labels
- This optional list allows you to specify labels for the columns instead of
using the label specfied in the field block of the controlled table. Each
list element is either a simple string which becomes the label or a pair
in which the key is the label and the value is a url (or code which builds
one) which becomes the href of an html link. Example:
col_labels `Better Text`,
Label => `$self->location() . '/exotic/locaiton'`;
Note that for pairs, you may use any valid Perl in the link
text. Enclose it in backquotes. It will not be modified, mind your own
quotes.
- extra_args
- See above.
- header_options
- These are the options that will appear at the end of the column label
stripe at the top of the output table. Typically this is just:
header_options Add;
But you can expand on that in a couple of ways. You can have
other options:
header_options AddBuyer, AddSeller;
These will translate into href links in the html page as
current_base_uri/addbuyer
current_base_uri/addseller
(In Gantry this means you should have do_addbuyer and
do_addseller methods in the same .pm file where the main_listing
lives.)
You can also control the generated url:
header_options AddUser => `$self->exotic_location() . "/strange_add"`;
Put valid Perl inside the backquotes. It will NOT be changed
in any way. You must ensure that the code will work in the final app. In
this case that likely means that exotic_location should return a uri
which is mentioned in a Location block in httpd.conf. Further, the
module set as the handler for that location must have a method called
do_strange_add.
- html_template
- The name of the Template Toolkit file to use as the view for this page. By
default this is results.tt for main_listing methods and main.tt for
base_link methods.
- row_options
- These yield href links at the end of each row in the output table. Typical
example:
row_options Edit, Delete;
These work just like header_options with one exception. The
url has the id of the row appended at the end.
If you say
row_options Edit => `$url`;
You must make sure that the url is exactly correct (including
appending '/$id' to it). Supplied values will be taken literally.
- title
- The browser window title for this page.
- AutoCRUD_form
- Generates a method, usually called _form, which Gantry::Plugins::AutoCRUD
calls from its do_add and do_edit methods.
You may include the following keys in the method block:
- all_fields_but
- A comma separated list of fields that should not appear on the form.
Typical example:
all_fields_but id;
- extra_args
- See above. Note that for the extra_args to be available, they must be
passed from the AutoCRUD calling method.
- extra_keys
- List key/value pairs you want to appear in the hash returned by the
method. Example:
extra_keys
legend => `$self->path_info =~ /edit/i ? 'Edit' : 'Add'`,
javascript => `$self->calendar_month_js( 'customer' )`;
The javascript entry is exactly correct for a form named
customer using Gantry::Plugins::Calendar.
Note that whatever you put inside the backquotes appears
EXACTLY as is in the generated output. Nothing will be done to it, not
even quote escaping.
- fields
- A comma separated list of the fields to include on the form. The names
must match fields of table you are controlling. Example:
fields first_name, last_name, street, city, state, zip;
Note that all_fields_but is usually easier, but directly using
fields allows you to change the order in which the entry widgets
appear.
- form_name
- The name of the html form. This is important if you are using javascript
which needs to refer to the form (for example if you are using
Gantry::Plugins::Calendar).
- CRUD_form
- Takes the same keywords as AutoCRUD_form but makes a form method suitable
for use with Gantry::Plugins::CRUD. Note that due to the callback scheme
used in that module, the name you give the generated method is entirely up
to you. Note that the method is generated in the stub and therefore must
be included during initial building to avoid gymnastics (like renaming the
stub, genning, renaming the regened stub, moving the form method from that
file back into the real stub...).
To keep podcoverage tests happy.
- backend_block_keywords
- Tells tentmaker that I understand these config section backend block
keywords:
no_gen
dbix
full_use
template
- what_do_you_make
- Tells tentmaker what this module makes. Summary: Gantry controller
modules.
- gen_Control
- Called by Bigtop::Parser to get me to do my thing.
- build_config_lists
- What I call on the various AST packages to do my thing.
- build_init_sub
- What I call on the various AST packages to do my thing.
- setup_template
- Called by Bigtop::Parser so the user can substitute an alternate template
for the hard coded one here.
Phil Crow <crow.phil@gmail.com>
Copyright (C) 2005 by Phil Crow
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself, either Perl version 5.8.6 or,
at your option, any later version of Perl 5 you may have available.
After this paragraph, you will likely see other POD. It belongs to the generated
modules. I just couldn't figure out how to hide it.
[% IF sub_module %] [% package_name %] - A controller in the [% app_name %]
application [% ELSE %] [% package_name %] - the base module of this web app [%
END %]
This package is meant to be used in a stand alone server/CGI script or the Perl
block of an httpd.conf file.
Stand Alone Server or CGI script:
use [% package_name %];
my $cgi = Gantry::Engine::CGI->new( {
config => {
#...
},
locations => {
[% IF sub_module %]
'/someurl' => '[% package_name %]',
[% ELSE %]
'/' => '[% package_name %]',
[% END %]
#...
},
} );
httpd.conf:
<Perl>
# ...
use [% package_name %];
</Perl>
[% IF sub_module %]
<Location /someurl>
SetHandler perl-script
PerlHandler [% package_name +%]
</Location>
[% END %]
If all went well, one of these was correctly written during app
generation.
This module was originally generated by Bigtop. But feel free to edit it. You
might even want to describe the table this module controls here.
[% IF sub_module %] =head1 METHODS [% ELSIF gen_package_name AND
NOT sub_modules %] =head1 METHODS (inherited from [% gen_package_name %]) [%
ELSE %] =head1 METHODS [% END %]
[% FOREACH method IN methods %] =item [% method %]
[% END %]
[% IF gen_package_name AND mixins %]
[% FOREACH mixin IN mixins %] =item [% mixin %]
[% END %]
[% END -%]
[% FOREACH used_module IN used_modules %]
[% used_module +%] [% END %] [% FOREACH see_also IN sub_modules %]
[% see_also +%] [% END %]
[% FOREACH author IN authors %] [% author.0 %][% IF author.1 %], <[% author.1
%]>[% END +%]
[% END %] [%- IF contact_us %] =head1 CONTACT US
[% contact_us +%]
[% END -%] =head1 COPYRIGHT AND LICENSE
Copyright (C) [% year %] [% copyright_holder %]
[% IF license_text %] [% license_text %]
[% ELSE %] This library is free software; you can redistribute it
and/or modify it under the same terms as Perl itself, either Perl version
5.8.6 or, at your option, any later version of Perl 5 you may have
available. [% END %]
[% gen_package_name %] - generated support module for [% package_name +%]
In [% package_name %]:
use base '[% gen_package_name %]';
This module was generated by Bigtop (and IS subject to regeneration) to provide
methods in support of the whole [% package_name +%] application.
[% package_name %] should inherit from this module.
[% FOREACH method IN methods %] =item [% method +%]
[% END %]
[% FOREACH author IN authors %] [% author.0 %][% IF author.1 %], <[% author.1
%]>[% END +%]
[% END %] [%- IF contact_us %] =head1 CONTACT US
[% contact_us +%]
[% END -%] =head1 COPYRIGHT AND LICENSE
Copyright (C) [% year %] [% copyright_holder %]
[% IF license_text %] [% license_text %]
[% ELSE %] This library is free software; you can redistribute it
and/or modify it under the same terms as Perl itself, either Perl version
5.8.6 or, at your option, any later version of Perl 5 you may have
available. [% END %]
[% gen_package_name %] - generated support module for [% package_name +%]
In [% package_name %]:
use base '[% gen_package_name %]';
This module was generated by bigtop and IS subject to regeneration. Use it in [%
package_name %] to provide the methods below. Feel free to override them.
[% FOREACH method IN gen_methods %] =item [% method +%]
[% END %]
Generated by bigtop and subject to regeneration.