|
|
| |
Rose::DBx::Object::Renderer(3) |
User Contributed Perl Documentation |
Rose::DBx::Object::Renderer(3) |
Rose::DBx::Object::Renderer - Web UI Rendering for Rose::DB::Object
use Rose::DBx::Object::Renderer;
use CGI;
my $query = new CGI;
print $query->header();
# Load all tables in the local MySQL database named 'company'
my $renderer = Rose::DBx::Object::Renderer->new(
config => {
db => {name => 'company', username => 'root', password => 'password'}
},
load => 1
);
# Render a form to add new employee
Company::Employee->render_as_form();
# Render an object as a form
my $e = Company::Employee->new(id => 1);
$e->load;
$e->render_as_form();
# Render the 'address' column as a link to a google map of the location
print $e->address_for_view();
# Render a table
Company::Employee::Manager->render_as_table();
# Render a table for all the employees who love 'Coding' with create, copy, edit, and delete access
Company::Employee::Manager->render_as_table(
get => {query => [hobby => 'Coding']}
order => ['first_name', 'email', 'address', 'phone'],
create => 1,
copy => 1,
edit => 1,
delete => 1,
searchable => ['first_name', 'address']
);
# Render a menu
my $menu = Company::Employee::Manager->render_as_menu(
order => ['Company::Employee', 'Company::Position'],
edit => 1,
delete => 1,
);
# Render a pie chart via Google Chart API
Company::Employee::Manager->render_as_chart(
type => 'pie',
values => ['Coding', 'Cooking'],
column => 'hobby',
);
# Render a bar chart
Company::Employee::Manager->render_as_chart(
type => 'bar',
title => 'The Employee Bar Chart',
description => 'A useful bar chart.',
columns => ['salary', 'tax'],
objects => [1, 2, 3],
options => {chco => 'ff6600,ffcc00'} # the color for each bar
);
Rose::DBx::Object::Renderer generates forms, tables, menus, and charts for
Rose::DB::Object. The generated UIs encapsulate sensible web conventions as
default behaviours, such as rendering email addresses as 'mailto' links and
enforce appropriate validation in forms. These default behaviours are highly
configurable.
Rose::DBx::Object::Renderer uses CGI::FormBuilder to generate
forms and the Google Chart API to render charts. Template::Toolkit is used
for template processing, although UIs can be generated out of the box
without using templates.
- Must follow the default conventions in Rose::DB::Object.
- Limited support for database tables with multiple primary keys.
To instantiate a new Renderer object:
my $renderer = Rose::DBx::Object::Renderer->new(config => {db => {name => 'company', username => 'root', password => 'root'}}, load => 1);
Since Renderer inherits from Rose::Object, the above line is
equivalent to:
my $renderer = Rose::DBx::Object::Renderer->new();
$renderer->config({db => {name => 'company', username => 'root', password => 'root'}});
$renderer->load();
A Renderer instance inherits the default configurations in Renderer, which is
accessible by:
my $config = $renderer->config();
"config" accepts a hashref for
configuring the Renderer object.
"db"
The "db" option is for
configuring database related settings, for instance:
$renderer->config({
db => {
name => 'product',
type => 'Pg', # defaulted to 'mysql'
host => '10.0.0.1',
port => '5432',
username => 'admin',
password => 'password',
tables_are_singular => 1, # defines table name conventions, defaulted to undef
table_prefix => 'app_', # specificies the prefix used in your table names if any, defaulted to undef
new_or_cached => 0, # whether to use Rose::DB's new_or_cached() method, defaulted to 1
check_class => 'Company::DB', # skip loading classes if the given class is already loaded (for persistent environments)
}
});
"template"
The "template" option specifies
the template toolkit "INCLUDE_PATH" and
the base URL for static contents, such as javascript libraries or
images:
$renderer->config({
...
template => {
path => '../templates:../alternative', # TT INCLUDE_PATH, defaulted to 'templates'
url => '../images', # defaulted to 'templates'
options => {ABSOLUTE => 1, RELATIVE => 1, POST_CHOMP => 1} # defaulted to undef
},
});
"upload"
Renderer needs a directory with write access to upload files. The
"upload" option defines file upload
related settings:
$renderer->config({
...
upload => {
path => '../files', # the upload directory path, defaulted to 'uploads'
url => '../files', # the corresponding URL path, defaulted to 'uploads'
keep_old_files => 1, # defaulted to undef
},
});
"form"
The "form" option defines the
global default behaviours of
"render_as_form":
$renderer->config({
...
form => {
download_message => 'View File', # the name of the link for uploaded files, defaulted to 'View'
remove_files => 1, # allow users to remove uploaded files, default to undef
remove_message => 'Remove File', # the label of the checkbox for removing files, defaulted to 'Remove'
cancel => 'Back', # the name of the built-in 'Cancel' controller, defaulted to 'Cancel'
delimiter => ' ' # the delimiter for handling column with muliple values, defaulted to ','
action => '/app' # set form action, defaulted to undef
},
});
These options can be also passed to
"render_as_form" directly to affect only
the particular instance.
"table"
The "table" option defines the
global default behaviours of
"render_as_table":
$renderer->config({
...
table => {
search_result_title => 'Looking for "[% q %]"?',
empty_message => 'No matching records.',
per_page => 25, # number of records per table, defaulted to 15
pages => 5, # the amount of page numbers in the table pagination, defaulted to 9
no_pagination => 1, # do not display pagination, defaulted to undef
or_filter => 1, # column filtering is joined by 'OR', defaulted to undef
delimiter => '/', # the delimiter for joining foreign objects in relationship columns, defaulted to ', '
keyword_delimiter => '\s+', # the delimiter for search keywords, defaulted to ','
like_operator => 'like', # only applicable to Postgres, defaulted to undef, i.e. render_as_table() uses 'ilike' for Postgres by default
form_options => ['order', 'template'], # options to be shared by other forms, defaulted to ['before', 'order', 'fields', 'template']
cascade => ['template_data', 'extra'], # options to be cascaded into all forms, defaulted to ['template_url', 'template_path', 'template_options', 'query', 'renderer_config', 'prepared']
},
});
These options can be also passed to
"render_as_table" directly to affect only
the particular instance.
"menu"
The "menu" option defines the
global default behaviours of
"render_as_menu":
$renderer->config({
...
menu => {
cascade => ['template_data', 'extra'], # options to be cascaded into all tables, defaulted to ['create', 'edit', 'copy', 'delete', 'ajax', 'prepared', 'searchable', 'template_url', 'template_path', 'template_options', 'query', 'renderer_config']
},
});
These options can be also passed to
"render_as_menu" directly to affect only
the particular instance.
"columns"
Renderer has a built-in list of column definitions that
encapsulate web conventions and behaviours. A column definition is a
collection of column options. Column definitions are used by the rendering
methods to generate web UIs. The built-in column definitions are stored
inside "columns":
my $config = $renderer->config();
print join (', ', keys %{$config->{columns}});
For example, the column definition for 'email' would be:
...
'email' => {
required => 1,
validate => 'EMAIL',
sortopts => 'LABELNAME',
comment => 'e.g. your.name@work.com',
format => {
for_view => sub {
my ($self, $column) = @_;
my $value = $self->$column;
return unless $value;
return qq(<a href="mailto:$value">$value</a>);}
}
},
...
We can also define new column definitions:
$renderer->config({
...
columns => {
hobby => {
label => 'Your Favourite Hobby',
sortopts => 'LABELNAME',
required => 1,
options => ['Reading', 'Coding', 'Shopping']
}
},
});
All options in each column definition are
"CGI::FormBuilder" field definitions, i.e.
they are passed to CGI::FormBuilder directly, except for:
- "format"
- The "format" option is a hash of
coderefs which get injected as object methods by
"load". For instance, based on the
'email' column definition, we can print a 'mailto' link for the email
address by calling:
print $object->email_for_view;
Similarly, based on other column definitions, we can:
# Print the date in 'DD/MM/YYYY' format
print $object->date_for_view;
# Store a password in MD5 hash
$object->password_for_update('p@$$W0rD');
$object->save();
# Display an image formatted in HTML <img> tags
print $object->image_for_view;
# Print the url of the image
print $object->image_url;
# Prints the file path of the image
print $object->image_path;
We can overwrite the existing formatting methods or define new
ones. For instance, we can use the HTML::Strip module to strip out HTML
tags for the 'description' column type:
use HTML::Strip;
...
$renderer->config({
...
columns => {
description => {
format => {
for_update => sub {
my ($self, $column, $value) = @_;
return unless $value;
my $hs = HTML::Strip->new(emit_spaces => 0);
my $clean_text = $hs->parse($value);
return $self->$column($clean_text);
}
}
}
},
});
$renderer->load();
...
$object->description_for_update('<html>The Lightweight UI Generator.</html>');
$p->save();
print $p->description;
# prints 'The Lightweight UI Generator.'
Formatting methods are utilised by rendering methods. They
take preference over the default CRUD methods. The
"for_create",
"for_edit", and
"for_update" methods are used by
"render_as_form". When creating new
objects, "render_as_form" triggers the
"for_create" methods to format the
default value of each column. When rendering an existing object as a
form, however, the "for_edit" methods
are triggered to format column values. During form submissions, the
"for_update" methods are triggered to
format the submitted form field values. The
"for_view",
"for_search", and
"for_filter" methods are used by
"render_as_table". The
"for_view" methods are triggered to
format column values for data presentation, the
"for_filter" methods are triggered
during data filtering, and the
"for_search" methods are triggered
during keyword searches.
- "unsortable"
- This option defines whether a column is sortable. For instance, the
'password' column definition has the
"unsortable" option set to 1. This
option is used by "render_as_table".
Custom columns are always unsortable.
- "stringify"
- This option specifies whether a column will be stringified by the
"stringify_me" object method.
"misc"
Other miscellaneous options are defined in
"misc":
my $custom_config = $renderer->config();
# Print the built-in doctype and CSS
print $custom_config->{misc}->{html_head};
# Change the object stringify delimiter
$custom_config->{misc}->{stringify_delimiter} = ', '; # defaulted to space
# Change time zone
$custom_config->{misc}->{time_zone} = 'Asia/Hong_Kong'; # defaulted to Australia/Sydney
# loaded the JS or CSS defined in $custom_config->{misc}->{js}, defaulted to the latest jQuery and jQuery UI hosted by Google
$custom_config->{misc}->{load_js} = 1; # defaulted to undef
$renderer->config($custom_config);
$renderer->load();
"load" uses Rose::DB::Object::Loader to load
Rose::DB::Object classes dynamically. In order to take advantage of the
built-in column definitions, "load" employs
the following logic to auto-assign column definitions to database columns:
Column name exists in the Renderer object's config?
Yes: Use that column definition.
No: Is the column a foreign key?
Yes: Apply the column options designed for foreign keys.
No: Column name matches (regex) a column definition name?
Yes: Use the first matching column definition.
No: Column's metadata object type exists as column definition name?
Yes: Use that column definition.
No: Create a custom column definition by aggregating database column information.
"load" accepts a hashref to pass
parameters to the "new" and
"make_classes" methods in
Rose::DB::Object::Loader.
- "loader"
- The "loader" option is a hashref that
gets passed to the "new" method in
Rose::DB::Object::Loader.
$renderer->load({
loader => {
class_prefix => 'MyCompany',
}
});
- "make_classes"
- Similarly, the "make_classes" option is
passed to the "make_classes" method.
$renderer->load({
make_classes => {
include_tables => ['customer', 'product'],
}
});
"load" returns an array of the
loaded classes via the "make_classes"
method in Rose::DB::Object::Loader. However, if the Rose::DB::Object
"base_class" for the particular database
already exists, which most likely happens in a persistent environment,
"load" will simply skip the loading
process and return undef.
"load" generates
CGI::FormBuilder validation subrefs to validate unique keys in forms.
However, since column definitions are identified by column names, custom
validation subrefs are required when there are multiple unique keys with the
same table column name across different tables loaded via Renderer.
Rendering methods are exported for Rose::DB::Object subclasses to generate web
UIs. Rose::DB::Object subclasses generated by calling
"load" will import the rendering methods
automatically. However, we can also import the rendering methods directly into
custom Rose::DB::Object subclasses:
# For object classes
package Company::Employee
use Rose::DBx::Object::Renderer qw(:object);
...
# For manager classes
package Company::Employee::Manager
use Rose::DBx::Object::Renderer qw(:manager);
...
The following is a list of common parameters for the rendering
methods:
- "template"
- The template file name. When it is set to 1, rendering methods will try to
find the default template based on the rendering method name. For example:
Company::Employee->render_as_form(template => 1);
# tries to use the template 'form.tt'
Company::Employee::Manager->render_as_table(template => 1);
# tries to use the template 'table.tt'
In "render_as_table" or
"render_as_menu", a hashref can be
used as a shortcut to specify the default templates for all the forms
and tables. For example:
Company::Employee::Manager->render_as_menu(
template => {menu => 'custom_menu.tt', table => 'custom_table.tt', form => 'custom_form.tt'}
);
- "template_path"
- The "Template Toolkit"'s
"INCLUDE_PATH".
- "template_url"
- An URL path variable that is passed to the templates.
- "template_options"
- Optional parameters to be passed to the "Template Toolkit"
constructor.
- "template_data"
- A hashref to overwrite the variables passed to the template.
- "query"
- Existing CGI query object. This is useful under a persistent environment,
such as Fast CGI. Rendering methods initiates new CGI query objects unless
an existing one has been provided.
- "html_head"
- This is specifying custom DOCTYPE, CSS, or Javascript for the particular
rendering method.
- "prefix"
- Define a prefix for the UI, e.g.:
Company::Employee::Manager->render_as_table(prefix => 'employee_admin');
A prefix should be URL friendly. Adding a
"prefix" can prevent CGI param
conflicts when rendering multiple UIs of the same class on the same web
page.
- "title"
- Define a title for the UI, e.g.:
Company::Employee::Manager->render_as_table(title => 'Employee Directory');
- "description"
- Define a short description for the UI, e.g.:
Company::Employee::Manager->render_as_table(description => 'Here you can view, search, and manage your employee details.');
- "no_head"
- When set to 1, rendering methods will not include the default DOCTYPE and
CSS defined in "html_head". This is
useful when rendering multiple UIs in the same page.
- "load_js"
- When set to 1, rendering methods will include the default
"js" into
"html_head".
- "output"
- When set to 1, the rendering methods will return the rendered UI instead
of printing it directly. For example:
my $form = Company::Employee->render_as_form(output => 1);
print $form->{output};
- "extra"
- A hashref of additional template variables. For example:
Company::Employee->render_as_form(extra => {hobby => 'basketball'});
# to access it within a template:
[% extra.hobby %]
- "before"
- A coderef to be executed prior to any rendering. This is useful for
augmenting arguments passed to the rendering methods, for example:
Company::Employee::Manager->render_as_table(
order => ['first_name', 'last_name', 'position_id'],
before => sub {
my ($object, $args) = @_;
# enable logged in users to access more data and functions
if ($ENV{REMOTE_USER}) {
$args->{order} = ['first_name', 'last_name', 'position_id', 'email', 'address'];
$args->{create} = 1;
$args->{edit} = 1;
}
}
);
- "prepared"
- When set to 1, rendering methods will not call
"prepare_renderer". This is useful for
physical Rose::DB::Object subclasses, when the formatting methods are
either handcrafted or loaded previously.
"render_as_form" renders forms and handles
their submission.
# Render a form for creating a new object
Company::Employee->render_as_form();
# Render a form for updating an existing object
my $e = Company::Employee->new(id => 1);
$e->load;
$e->render_as_form();
- "order"
- "order" is an arrayref for the order of
the form fields.
- "fields"
- A hashref to specify the CGI::FormBuilder field definitions for this
particular "render_as_form" call. Any
custom fields must be included in the
"order" arrayref in order to be shown.
Company::Employee->render_as_form(
order => ['username', 'favourite_cuisine'],
fields => {
favourite_cuisine => {required => 1, options => ['Chinese', 'French', 'Japanese']}
}
);
- "copy"
- Instead of updating the calling object, we can clone the object by setting
"copy" to 1.
...
$e->render_as_form(copy => 1);
- "queries"
- An arrayref of query parameters to be converted as hidden fields.
Company::Employee->render_as_form(
queries => {
'rm' => 'edit',
'favourite_cuisine' => ['French', 'Japanese']
});
Please note that when a prefix is used, all fields are renamed
to '"prefix_fieldname"'.
- "controllers" and "controller_order"
- Controllers are essentially callbacks. We can add multiple custom
controllers to a form. They are rendered as submit buttons.
"controller_order" defines the order of
the controllers, in other words, the order of the submit buttons.
my $form = Company::Employee->render_as_form(
output => 1,
controller_order => ['Hello', 'Good Bye'],
controllers => {
'Hello' => {
create => sub {
return if DateTime->now->day_name eq 'Sunday';
return 1;
},
callback => sub {
my $self = shift;
if (ref $self) {
return 'Welcome ' . $self->first_name;
}
else {
return 'Employees cannot be added on Sundays';
}
}
},
'Good Bye' => sub {return 'Have fun!'}
}
);
if (exists $form->{controller}) {
print $form->{controller};
}
else {
print $form->{output};
}
Within the "controllers"
hashref, we can set the "create"
parameter to 1 so that the object is always inserted into the database
before running the custom callback. We can also point
"create" to a coderef, in which case,
the object is inserted into the database only if the coderef returns
true.
When rendering an object instance as a form, we can use the
same mechanism to 'copy' or 'update' the object before running the
custom callback, for instance:
...
$e->render_as_form(
controllers => {
'Hello' => {
update => 1,
callback => sub{...}
}
}
);
Another parameter within the
"controllers" hashref is
"hide_form", which informs
"render_as_form" not to render the
form after executing the controller.
- "form"
- A hashref that gets passed to the CGI::FormBuilder constructor.
- "validate"
- Parameters for the CGI::FormBuilder's
"validate" method.
- "jserror"
- When a template is used,
"render_as_form" sets CGI::FormBuilder's
"jserror" function name to
'"notify_error"' so that we can always
customise the error alert mechanism within the template (see the included
'form.tt' template).
"render_as_form" passes the
following list of variables to a template:
[% self %] - the calling object instance or class
[% form %] - CGI::FormBuilder's form object
[% field_order %] - the order of the form fields
[% form_id %] - the form id
[% form_submit %] - the form submit buttons with a custom 'Cancel' button
[% title %] - the form title
[% description %] - the form description
[% doctype %] - the default html doctype
[% html_head %] - the default html doctype and css
[% no_head %] - the 'no_head' option
[% cancel %] - the name of the 'Cancel' controller
[% template_url %] - the default template URL
[% extra %] - extra template variables
"render_as_table" renders tables for CRUD
operations.
- "columns"
- The "columns" parameter can be used to
set the label and value of a column, as well as whether the column is
sortable. It can also be used to create custom columns, which do not exist
in the underlying database.
Company::Employee::Manager->render_as_table(
order => ['first_name', 'custom_column'],
columns => {
'first_name' => {
unsortable => 1
},
'custom_column' => {
label => 'Favourite Drink',
value => {
1 => 'Tea', # 1 is the primary key of the object
2 => 'Coffee'
},
}
}
);
We can also nominate a custom
"accessor", such that the table column
values are populated via the nominated accessor, as opposed to the
default column one. For example:
Company::Employee::Manager->render_as_table(
order => ['first_name', 'salary'],
columns => {
'salary' => {
accessor => 'salary_with_bonus'
},
}
);
In this case, the values of the 'salary' column in the table
are populated by calling
"salary_with_bonus", instead of
"salary".
- "order"
- "order" accepts an arrayref to define
the order of the columns to be shown. The
"order" parameter also determines which
columns are allowed to be filtered via URL when
"filterable" is not defined.
- "or_filter"
- "render_as_table" allows columns to be
filtered via URL. For example:
http://www.yoursite.com/yourscript.cgi?first_name=Danny&last_name=Liang
returns the records where 'first_name' is 'Danny' and
'last_name' is 'Liang'. By default, column queries are joined by
"AND", unless "or_filter" is
set to 1.
- "filterable"
- This specifies an arrayref of columns that are filterable via URL. This
can be used to filter data in columns that are not shown, e.g.:
Company::Employee::Manager->render_as_table(
order => ['first_name', 'last_name', 'email'],
filterable => ['first_name', 'last_name', 'email', 'state'],
);
- "searchable"
- The "searchable" option enables keyword
searches accross multiple table columns using the LIKE operator in SQL,
including the columns of foreign objects:
Company::Employee::Manager->render_as_table(
get => {with_objects => [ 'position' ]},
searchable => ['first_name', 'last_name', 'position.title'],
);
This option adds a text field named 'q' in the rendered table
for entering keywords.
"render_as_table()" grabs the value of
the argument "q" if it exists,
otherwise pulls the value of the param 'q' from querystring.
Since PostgreSQL does not like mixing table aliases with real
table names in queries,
"render_as_table()" tries to perform
basic table aliasing for non-character based columns in PostgreSQL
automatically. Please note that the corresponding tables in chained
relationships defined via 'with_objects' and 'require_objects', such as
'vendor.region', will still require manual table aliasing if their
columns are specified in the
"searchable" array.
In order to use the LIKE operator in SQL queries,
"render_as_table()" also performs type
casting for non-character based columns, such as date, in PostgreSQL and
SQLite.
By default, comma is the delimiter for seperating multiple
keywords. This is configurable via
"config()".
Instead of an arrayref, you can also pass in 1, e.g.:
Company::Employee::Manager->render_as_table(
searchable => 1,
);
In this case, all the columns of the given table will be
searched.
- "like_operator"
- The 'LIKE' operator for generating SQL queries when
"searchable" is used. Set this to 'like'
to perform a case-sensitive search for PostgreSQL.
- "get"
- "get" accepts a hashref to construct
database queries. "get" is directly
passed to the "get" method of the
manager class.
Company::Employee::Manager->render_as_table(
get => {
per_page = 5,
require_objects => [ 'position' ],
query => ['position.title' => 'Manager'],
});
- "get_from_sql"
- "get_from_sql" accepts arguments, such
as an SQL statement, supported by the
"get_objects_from_sql" method from
Rose::DB::Object::Manager.
Company::Employee::Manager->render_as_table(
order => ['id', 'first_name', 'email'],
get_from_sql => 'SELECT id, first_name, email FROM employee WHERE id % 2 = 0 ORDER BY id',
);
"get_from_sql" takes
precedence over "get". The default
table pagination will be also disabled.
- "objects"
- "objects" accepts an array of
Rose::DB::Object objects.
Company::Employee::Manager->render_as_table(
objects => Company::Employee::Manager->get_objects(query => [hobby => 'Coding']),
);
"objects" takes precedence
over "get_from_sql". The default table
pagination will be also disabled.
- "controllers" and "controller_order"
- The "controllers" parameter works very
similar to "render_as_form".
"controller_order" defines the order of
the controllers.
Company::Employee::Manager->render_as_table(
controller_order => ['edit', 'Review', 'approve'],
controllers => {
'Review' => sub{my $self = shift; do_something_with($self);}
'approve' => {
label => 'Approve',
hide_table => 1,
queries => {approve => '1'},
callback => sub {my $self = shift; do_something_else_with($self);
}
}
);
Within the "controllers"
hashref, the "queries" parameter
allows us to define custom query strings for the controller. The
"hide_table" parameter informs
"render_as_table" not to render the
table after executing the controller.
- "create"
- This enables the built-in 'create' controller when set to 1.
Company::Employee::Manager->render_as_table(create => 1);
Since "render_as_form" is
used to render the form, we can also pass a hashref to manipulate the
generated form.
Company::Employee::Manager->render_as_table(
create => {title => 'Add New Employee', fields => {...}}
);
- "edit"
- Similar to "create",
"edit" enables the built-in 'edit'
controller for updating objects.
- "copy"
- "copy" enables the built-in 'copy'
controller for cloning objects.
- "delete"
- When set to 1, "delete" enables the
built-in 'delete' controller for removing objects.
- "queries"
- Similar to the "queries" parameter in
"render_as_form",
"queries" is an arrayref of query
parameters, which will be converted to query strings. Please note that
when a prefix is used, all query strings are renamed to
'"prefix_querystring"'.
- "form_options"
- An arrayref of form options that can be inherited by other forms.
Company::Employee::Manager->render_as_table(
form_options => ['order', 'template'],
order => ['photo', 'first_name', 'last_name', 'email'],
create => {
before => sub {
my ($object, $args) = @_;
$args->{fields}->{status} = {static => 1, value => 'Pending'};
},
order => ['first_name', 'last_name', 'photo', 'email', 'phone', 'status'],
template => 'custom_form.tt',
},
edit => 1,
copy => 1,
);
In the above example, both the form for 'edit' and 'copy' will
share the exact same field order and TT template with the form for
'create', despite the fact that none of those options are defined
directly. However, the 'before' callback will not be triggered in the
'edit' or 'copy' form since the
"form_options" parameter prevents that
option being inherited.
- "url"
- Unless a url is specified in "url",
"render_as_table" will resolve the self
url using CGI.
- "ajax" and "ajax_template"
- These two parameters are designed for rendering Ajax-enabled tables. When
"ajax" is set to 1,
"render_as_table" tries to use the
template 'table_ajax.tt' for rendering, unless it is defined via
"ajax_template".
"render_as_table" also passes a variable
called 'ajax' to the template and sets it to 1 when a CGI param named
'ajax' (assuming no prefix is in use) is found, indicating the current
request is an ajax request.
Within a template, we can loop through objects using the
"[% table %]" variable. Alternatively, we
can use the "[% objects %]" variable.
"render_as_table" passes the
following list of variables to a template:
[% table %] - the hash for the formatted table, see the sample template 'table.tt'
[% objects %] - the raw objects returned by the 'get_object' method
[% column_order %] - the order of the columns
[% template_url %] - the default template URL
[% table_id %] - the table id
[% title %] - the table title
[% description %] - the table description
[% no_pagination %] - the 'no_pagination' option
[% q %] - the keyword query for search
[% query_string %] - a hash of URL encoded query strings
[% query_hidden_fields %] - CGI queries converted into hidden fields; it is used by the keyword search form
[% param_list %] - a list of CGI param names with the table prefix, e.g. the name of the keyword search box is [% param_list.q %]
[% searchable %] - the 'searchable' option
[% sort_by_column %] - the column to be sorted
[% doctype %] - the default html doctype
[% html_head %] - the default html doctype and css
[% no_head %] - the 'no_head' option
[% ajax %] - the ajax variable for checking whether the current CGI request is a ajax request
[% url %] - the base url
[% extra %] - extra template variables
"render_as_menu" generates a menu with the
given list of classes and renders a table for the current class. We can have
fine-grained control over each table within the menu. For example, we can
alter the 'date_of_birth' field inside the 'create' form of the
'Company::Employee' table inside the menu:
Company::Employee::Manager->render_as_menu (
create => 1,
edit => 1,
delete => 1,
copy => 1,
searchable => 1,
order => ['Company::Employee', 'Company::Position'],
items => {
'Company::Employee' => {
create => {
fields => {date_of_birth => {required => 1}}
}
},
'Company::Position' => {
title => 'Current Positions',
}
},
);
- "order"
- The "order" parameter defines the list
of classes to be shown in the menu as well as their order. The current
item of the menu is always the calling class, i.e.
"Company::Employee::Manager" in the
example.
- "items"
- The "items" parameter is a hashref of
parameters to control each table within the menu.
- "create", "edit", "copy",
"delete", "searchable", "template",
"ajax", and "prepared"
- These parameters are shortcuts which get passed to all the underlying
tables rendered by the menu.
- "current"
- The class name for the current tab. By default, the caller class is the
current tab.
"render_as_menu" passes the
following list of variables to a template:
[% template_url %] - the default template URL
[% menu_id %] - the menu id
[% title %] - the menu title
[% description %] - the menu description
[% items %] - the hash for the menu items
[% item_order %] - the order of the menu items
[% current %] - the current menu item
[% content %] - the output of the table
[% hide %] - whether the menu should be hidden
[% doctype %] - the default html doctype
[% html_head %] - the default html doctype and css
[% no_head %] - the 'no_head' option
[% extra %] - extra template variables
"render_as_chart" renders pie, line, and
vertical bar charts via the Google Chart API.
- "type"
- This can be 'pie', 'bar', or 'line', which maps to the Google chart type
(cht) 'p', 'bvg', and 'ls' respectively.
- "column" and "values"
- These two parameters are only applicable to pie charts.
"column" defines the column of the table
in which the values are compared. The
"values" parameter is a list of values
to be compared in that column, i.e. the slices.
- "columns" and "objects"
- These two parameters are only applicable to bar and line charts.
"columns" defines the columns of the
object to be compared. The "objects"
parameter is a list of object IDs representing the objects to be
compared.
- "options"
- A hashref for specifying Google Chart API options, such as the chart type,
size, labels, or data. This hashref is serialised into a query
string.
- "engine"
- Accepts a coderef to plug in your own charting engine.
"render_as_chart" passes the
following list of variables to a template:
[% template_url %] - the default template URL
[% chart_id %] - the chart id
[% title %] - the chart title
[% description %] - the chart description
[% chart %] - the chart
[% options %] - the 'options' hash
[% doctype %] - the default html doctype
[% html_head %] - the default html doctype and css
[% no_head %] - the 'no_head' option
[% extra %] - extra template variables
Apart from the formatting methods injected by
"load", there are several lesser-used object
methods:
This is a wrapper of the object's "delete"
method to remove any uploaded files associated:
$object->delete_with_file();
Stringifies the object instance, e.g.:
$object->first_name('John');
$object->last_name('Smith');
print $object->stringify_me();
# prints 'John Smith';
It also accept the "prepared"
parameter.
Stringifies the class name:
print Company::Employee->stringify_class();
# prints 'company_employee'
This is called by Renderer's "load" method
internally. It generates the column formatting methods, column definition
methods, as well as a "renderer_config"
method for the Rose::DB::Object subclass. These generated methods are called
by the rendering methods, e.g.
"render_as_form". Thus, it would be useful
for physical Rose::DB::Object subclasses to call
"prepare_renderer" explicitly, prior to
running the rendering methods, unless those relevant methods are handcrafted.
"prepare_renderer" returns the renderer
config hashref generated for the calling Rose::DB::Object subclass.
my $config = Company::Employee->prepare_renderer();
$config->{upload}->{path} = '/path/for/file/uploads'; # set the path for file upload
print Company::Employee->email_for_view(); # call the 'for view' method of the email column
my $employee_config = Company::Employee->renderer_config(); # retrieve the complete config hashref
my $email_definition = Company::Employee->email_definition(); # retrieve just the column definition hashref for the email column
There are four sample templates: 'form.tt', 'table.tt', 'menu.tt', and
'chart.tt' in the 'templates' folder of the TAR archive.
Rose::DB::Object, CGI::FormBuilder, Template::Toolkit,
<http://code.google.com/apis/chart/>
Xufeng (Danny) Liang (danny.glue@gmail.com)
Copyright 2008-2010 Xufeng (Danny) Liang, All Rights Reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
Visit the GSP FreeBSD Man Page Interface. Output converted with ManDoc. |