Bigtop
view release on metacpan or search on metacpan
lib/Bigtop/Docs/Tutorial.pod view on Meta::CPAN
}
field city {
is varchar;
label City;
html_form_type text;
}
field state {
is varchar;
label State;
html_form_type text;
}
field zip {
is varchar;
label Zip;
html_form_type text;
}
field description {
is varchar;
label Description;
html_form_type text;
html_form_optional 1;
}
field contact_name {
is varchar;
label `Contact Name`;
html_form_type text;
html_form_optional 1;
}
field contact_email {
is varchar;
label `Contact Email`;
html_form_type text;
html_form_optional 1;
}
field contact_phone {
is varchar;
label `Contact Phone`;
html_form_type text;
html_form_optional 1;
}
}
Easy date handling is a key feature of Bigtop and Gantry. The line item
table has a due date for the task it describes:
sequence line_items_seq {}
table line_items {
sequence line_items_seq;
foreign_display `%name`;
field id { is int4, primary_key, assign_by_sequence; }
field due_date {
is date;
label `Due Date`;
date_select_text Select;
html_form_type text;
}
The date_select_text will appear as an HTML href link next to the entry
field for the date. If the user clicks the link, a popup will display
an intuitive calendar. If the user clicks a date on the popup calendar,
the text input box will be populated with that date.
Of course, this behavior is driven by the controller.
For example, see the LineItem controller below.
field name {
is varchar;
label Name;
html_form_type text;
}
field my_companies {
is int4;
label `My Company`;
refers_to my_companies;
html_form_type select;
}
Because we used the -> notation when running bigtop originally, the
foreign key fields are already present. But here is how to add one
manually: use the refers_to statement to say which table it points to.
Note that it must point to the primary key of the other table and we
generally assume that the key will be the unique id column.
Bigtop::Backend::SQL::Postgres does not currently (nor is it ever likely
to) generate genuine SQL foreign keys. If you want foreign
keys, and your database supports them, consider implementing your own SQL
backend to generate the SQL code for them.
Note that when we used bigtop, it chose the foreign key column names
to match the foreign table names exactly. Our original data model
diagram used slightly different names. If you want the bigtop file
to match the picture, change the names of the foreign key fields.
The Gantry html_form_type for foreign key columns is C<select> which
allows the user to pick one item from a pull down list.
field customers {
is int;
label Customer;
refers_to customers;
html_form_type select;
}
field invoices {
is int;
label `Invoice Number`;
refers_to invoices;
html_form_type select;
}
field hours {
is int;
label Hours;
html_form_type text;
}
field charge_per_hour {
is int;
label Rate;
html_form_type text;
}
field notes {
is text;
label `Notes to Customer`;
lib/Bigtop/Docs/Tutorial.pod view on Meta::CPAN
=back
controller Company is AutoCRUD {
controls_table my_companies;
rel_location company;
text_description company;
page_link_label Companies;
method do_main is main_listing {
title `My Companies`;
cols name, contact_phone;
header_options Add;
row_options Edit, Delete;
}
method form is AutoCRUD_form {
form_name company;
all_fields_but id;
extra_keys
legend => `$self->path_info =~ /edit/i ? 'Edit' : 'Add'`;
}
}
While we can list the fields we want in an AutoCRUD_form, we can also
use all_fields_but and list the fields we don't want.
controller Customer is AutoCRUD {
controls_table customers;
rel_location customer;
text_description customer;
page_link_label Customers;
method do_main is main_listing {
title `Customers`;
cols name, contact_name, contact_phone;
header_options Add;
row_options Edit, Delete;
}
method form is AutoCRUD_form {
form_name customer;
all_fields_but id;
extra_keys
legend => `$self->path_info =~ /edit/i ? 'Edit' : 'Add'`;
}
}
controller LineItem is AutoCRUD {
controls_table line_items;
rel_location lineitem;
uses Gantry::Plugins::Calendar;
text_description `line item`;
page_link_label `Line Items`;
method do_main is main_listing {
title `Line Items`;
cols name, due_date, customer_id;
header_options Add;
row_options Edit, Delete;
}
method form is AutoCRUD_form {
form_name line_item;
all_fields_but id;
extra_keys
legend => `$self->path_info =~ /edit/i ? 'Edit' : 'Add'`,
javascript => `$self->calendar_month_js( 'line_item' )`;
}
}
When we discussed the line_items table, I explained breifly how the
user may chose dates. There are really three steps in the process:
=over 4
=item 1.
Add a date_select_text statement to the field's block in the table.
The text can be anything (but remember to use backquotes if you want
spaces, or other funny characters, in it). The user will see it as
the html href link text.
=item 2.
Put C<Gantry::Plugins::Calendar> in the C<uses> list for the controller.
=item 3.
Include javascript in C<extra_keys> in the C<AutoCRUD_form> method block.
Use the value as shown here, but change C<line_item> to match your
C<form_name>.
=back
controller Invoice is AutoCRUD {
controls_table invoices;
rel_location invoice;
uses Gantry::Plugins::Calendar;
text_description invoice;
page_link_label Invoices;
method do_tasks is stub {
extra_args `$id`;
}
method do_pdf is stub {
extra_args `$id`;
}
method do_main is main_listing {
title `Invoices`;
cols number, status_id;
header_options Add;
row_options Tasks, PDF, Edit, Delete;
}
Row options can be anything. Usually they are Edit and Delete. Here we
add Tasks and PDF. While Add, Edit, and Delete are supported by
Gantry::Plugins::AutoCRUD, any others you name will require code you hand
write.
Here we want to be able to view the tasks associated with an invoice
and to generate a PDF of the invoice which we can email to the client.
Bigtop can help you by generating stubs for these methods. Simply include
method blocks of type stub. For gantry dispatching, the name of the
method must be do_ followed by the lowercase name of the row option. In
order for the methods to operate properly, they must know the id of the
row they will work on. Include this in an extra_args statement.
method form is AutoCRUD_form {
form_name invoice;
all_fields_but id;
extra_keys
legend => `$self->path_info =~ /edit/i ? 'Edit' : 'Add'`,
javascript => `$self->calendar_month_js( 'invoice' )`;
}
}
}
This concludes our walk through the bigtop description of the billing
application. Now it's time to build it.
=head2 Generation and Installation
Once you have a bigtop description of your application, you are ready
to build it.
If you began following along by using
bigtop --new Apps::Billing [...]
You can just move into the Apps-Billing directory and type
bigtop docs/app-billing.bigtop all
Otherwise, if you typed in the file (or are using billing.bigtop from
the examples directory of the bigtop distribution) do this instead:
bigtop --create billing.bigtop all
After a few seconds, all the files needed for your app will be built in
the app_dir. In my case that is /home/pcrow/Billing. Running ls
on that directory shows:
Build.PL MANIFEST.SKIP app.db html
Changes README app.server lib
MANIFEST app.cgi docs t
Of course, the README is meaningless and must be changed. As should the
pod sections of the generated code in lib. Further, the tests are minimal.
The check for broken or missing POD, whether the controller modules compile
(think C<use_ok>), and whether each controllers default page returns status
200.
But here is what you really get. In docs there is a file schema.sqlite, which
defines your database. To build the clean database do this:
sqlite app.db < docs/schema.sqlite
This builds the database, including populating the status table.
Note that bigtop tried to do this during initial building, so you won't
have to do this unless you don't have sqlite installed (go install it,
it's worth it) or it has a different name.
The app is useable at this point, but it doesn't generate PDF invoices.
To start it, type:
./app.server [ port ]
By default app.server runs on port 8080, type an alternate port number
if that isn't suitable.
If you prefer to use Postgres or MySQL at this point, look in the docs
directory for the schema file for your database. If it isn't there,
you need to add:
( run in 0.731 second using v1.01-cache-2.11-cpan-39bf76dae61 )