diff options
-rw-r--r-- | componentui.conf | 10 | ||||
-rw-r--r-- | lib/ComponentUI/Controller/TestModel/Bar.pm | 5 | ||||
-rw-r--r-- | lib/Reaction/UI/ViewPort/GridView.pm | 203 | ||||
-rw-r--r-- | lib/Reaction/UI/ViewPort/GridView/Row.pm | 3 | ||||
-rw-r--r-- | lib/Reaction/UI/ViewPort/ListView.pm | 4 | ||||
-rw-r--r-- | lib/Reaction/UI/Widget/GridView.pm | 57 | ||||
-rw-r--r-- | lib/Reaction/UI/Widget/GridView/Row.pm | 4 | ||||
-rw-r--r-- | lib/Reaction/UI/WidgetClass.pm | 24 | ||||
-rw-r--r-- | share/skin/default/layout/action_form.tt (renamed from share/skin/default/layout/action_form) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/boolean.tt (renamed from share/skin/default/layout/display_field/boolean) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/collection.tt (renamed from share/skin/default/layout/display_field/collection) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/date_time.tt (renamed from share/skin/default/layout/display_field/date_time) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/list.tt (renamed from share/skin/default/layout/display_field/list) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/number.tt (renamed from share/skin/default/layout/display_field/number) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/related_object.tt (renamed from share/skin/default/layout/display_field/related_object) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/string.tt (renamed from share/skin/default/layout/display_field/string) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/display_field/text.tt (renamed from share/skin/default/layout/display_field/text) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/boolean.tt (renamed from share/skin/default/layout/field/boolean) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/choose_many.tt (renamed from share/skin/default/layout/field/choose_many) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/choose_one.tt (renamed from share/skin/default/layout/field/choose_one) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/date_time.tt (renamed from share/skin/default/layout/field/date_time) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/file.tt (renamed from share/skin/default/layout/field/file) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/hidden_array.tt (renamed from share/skin/default/layout/field/hidden_array) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/number.tt (renamed from share/skin/default/layout/field/number) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/password.tt (renamed from share/skin/default/layout/field/password) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/string.tt (renamed from share/skin/default/layout/field/string) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/text.tt (renamed from share/skin/default/layout/field/text) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/field/time_range.tt (renamed from share/skin/default/layout/field/time_range) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/grid_view.tt (renamed from share/skin/default/layout/grid_view) | 16 | ||||
-rw-r--r-- | share/skin/default/layout/index.tt (renamed from share/skin/default/layout/index) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/layout.tt (renamed from share/skin/default/layout/layout) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/list_view.tt (renamed from share/skin/default/layout/list_view) | 16 | ||||
-rw-r--r-- | share/skin/default/layout/object_view.tt (renamed from share/skin/default/layout/object_view) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/boolean.tt (renamed from share/skin/default/layout/value/boolean) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/collection.tt (renamed from share/skin/default/layout/value/collection) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/date_time.tt (renamed from share/skin/default/layout/value/date_time) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/list.tt (renamed from share/skin/default/layout/value/list) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/number.tt (renamed from share/skin/default/layout/value/number) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/related_object.tt (renamed from share/skin/default/layout/value/related_object) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/string.tt (renamed from share/skin/default/layout/value/string) | 0 | ||||
-rw-r--r-- | share/skin/default/layout/value/text.tt (renamed from share/skin/default/layout/value/text) | 0 |
41 files changed, 226 insertions, 116 deletions
diff --git a/componentui.conf b/componentui.conf index 9a0ed59..008ce1d 100644 --- a/componentui.conf +++ b/componentui.conf @@ -1,15 +1,5 @@ using_frontend_proxy 1 -<Controller Foo> - <action update> - <ViewPort> - <Field baz_list> - layout checkbox_group - </Field> - </ViewPort> - </Action> -</Controller> - <View Site> skin_name default </View>
\ No newline at end of file diff --git a/lib/ComponentUI/Controller/TestModel/Bar.pm b/lib/ComponentUI/Controller/TestModel/Bar.pm index 2cf7681..644a20f 100644 --- a/lib/ComponentUI/Controller/TestModel/Bar.pm +++ b/lib/ComponentUI/Controller/TestModel/Bar.pm @@ -6,10 +6,7 @@ use Reaction::Class; __PACKAGE__->config( model_base => 'TestModel', model_name => 'Bar', - action => { base => { Chained => '/base', PathPart => 'testmodel/bar' }, - list => { ViewPort => { layout => 'bar_list' } }, - update => { ViewPort => { layout => 'bar_form' } }, - create => { ViewPort => { layout => 'bar_form' } } }, + action => { base => { Chained => '/base', PathPart => 'testmodel/bar' }}, ); 1; diff --git a/lib/Reaction/UI/ViewPort/GridView.pm b/lib/Reaction/UI/ViewPort/GridView.pm index 542af62..5691ff1 100644 --- a/lib/Reaction/UI/ViewPort/GridView.pm +++ b/lib/Reaction/UI/ViewPort/GridView.pm @@ -2,8 +2,14 @@ package Reaction::UI::ViewPort::GridView; use Reaction::Class; -use aliased 'Reaction::UI::ViewPort::GridView::Row'; -use aliased 'Reaction::InterfaceModel::Collection'; +use aliased 'Reaction::UI::ViewPort::DisplayField::Text'; +use aliased 'Reaction::UI::ViewPort::DisplayField::Number'; +use aliased 'Reaction::UI::ViewPort::DisplayField::Boolean'; +use aliased 'Reaction::UI::ViewPort::DisplayField::String'; +use aliased 'Reaction::UI::ViewPort::DisplayField::DateTime'; +use aliased 'Reaction::UI::ViewPort::DisplayField::RelatedObject'; + +use aliased 'Reaction::InterfaceModel::Collection' => 'IM_Collection'; class GridView is 'Reaction::UI::ViewPort', which { @@ -12,38 +18,23 @@ class GridView is 'Reaction::UI::ViewPort', which { has rows => ( isa => 'ArrayRef', is => 'ro', lazy_build => 1); has row_args => ( isa => 'HashRef', is => 'ro'); - has collection => (isa => Collection, is => 'ro', required => 1); - has current_collection => (isa => Collection, is => 'rw', lazy_build => 1); - - implements build_rows => as{ - my $self = shift; + has collection => (isa => IM_Collection, is => 'ro', required => 1); + has current_collection => (isa => IM_Collection, is => 'rw', lazy_build => 1); - my (@rows, $i); - for my $object ( $self->current_collection->members ){ - my $row = Row->new - ( - ctx => $self->ctx, - object => $object, - location => join('-', $self->location, 'row', ++$i), - column_order => $self->column_order, #XXX clean from ViewPort - exclude_fields => $self->exclude_columns || [], - $self->has_row_args ? %{ $self->row_args } : (), - - ); - push(@rows, $row); - } - return \@rows; - }; + has ordered_columns => (is => 'ro', isa => 'ArrayRef', lazy_build => 1); - implements build_column_names => as { + implements build_ordered_columns => as { my ($self) = @_; my %excluded = map { $_ => undef } @{ $self->has_exclude_columns ? $self->exclude_columns : [] }; #XXX this abuse of '_im_class' needs to be fixed ASAP my $object_class = $self->collection->_im_class; - my @fields = $object_class->meta->compute_all_applicable_attributes; + my @fields = $object_class->meta->parameter_attributes; + #obviously only get fields with readers. + @fields = grep { $_->get_read_method } @fields; #eliminate excluded fields & treat names that start with an underscore as private @fields = grep {$_->name !~ /^_/ && !exists $excluded{$_->name} } @fields; + #eliminate fields marked as collections, or fields that are arrayrefs @fields = grep { !($_->has_type_constraint && @@ -54,14 +45,172 @@ class GridView is 'Reaction::UI::ViewPort', which { ) } @fields; #order the columns all nice and pretty, and only get fields with readers, duh - return $self->sort_by_spec - ( $self->column_order, [ map { (($_->get_read_method) || ()) } @fields] ); + my $ordered = $self->sort_by_spec + ( $self->column_order, [ map { (($_->name) || ()) } @fields] ); + + return $ordered; }; implements build_current_collection => as { shift->collection; }; + implements build_column_names => as { + my $self = shift; + [ map{ join(' ', map{ ucfirst } split('_', $_)) } @{$self->ordered_columns} ]; + } + + implements build_rows => as { + my ($self) = @_; + my @columns = @{ $self->ordered_columns }; + + my (@rows, $i); + my $builders = {}; + for my $obj ( $self->current_collection->members ) { + $i++; + my @cells; + for my $col (@columns) { + my $attr = $obj->meta->find_attribute_by_name($col); + my $build_meth = $builders->{$col} ||= $self->build_fields_for($attr); + my $loc = join('-', $self->location, 'row', $i, 'field', $attr->name); + my $args = {Field => { $attr->name => {location => $loc} } }; + my $cell = $self->$build_meth($obj, $attr, $args); + push(@cells, $cell) if $cell; + } + push(@rows,\@cells) + } + + return \@rows; + }; + + implements build_fields_for => as { + my ($self, $attr) = @_; + my $attr_name = $attr->name; + my $builder = "build_fields_for_name_${attr_name}"; + return $builder if $self->can($builder); + if ($attr->has_type_constraint) { + my $constraint = $attr->type_constraint; + my $base_name = $constraint->name; + my $tried_isa = 0; + CONSTRAINT: while (defined($constraint)) { + my $name = $constraint->name; + if (eval { $name->can('meta') } && !$tried_isa++) { + foreach my $class ($name->meta->class_precedence_list) { + my $mangled_name = $class; + $mangled_name =~ s/:+/_/g; + my $builder = "build_fields_for_type_${mangled_name}"; + return $builder if $self->can($builder); + } + } + if (defined($name)) { + unless (defined($base_name)) { + $base_name = "(anon subtype of ${name})"; + } + my $mangled_name = $name; + $mangled_name =~ s/:+/_/g; + my $builder = "build_fields_for_type_${mangled_name}"; + return $builder if $self->can($builder); + } + $constraint = $constraint->parent; + } + if (!defined($constraint)) { + confess "Can't build field ${attr_name} of type ${base_name} without $builder method or build_fields_for_type_<type> method for type or any supertype"; + } + } else { + confess "Can't build field ${attr} without $builder method or type constraint"; + } + }; + + + implements build_simple_field => as { + my ($self, $class, $obj, $attr, $args) = @_; + my $attr_name = $attr->name; + my %extra; + if (my $config = $args->{Field}{$attr_name}) { + %extra = %$config; + } + + return $class->new( + object => $obj, + attribute => $attr, + name => $attr->name, + ctx => $self->ctx, + %extra + ); + }; + + implements build_fields_for_type_Num => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/number' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(Number, $obj, $attr, $args); + }; + + implements build_fields_for_type_Int => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/number' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(Number, $obj, $attr, $args); + }; + + implements build_fields_for_type_Bool => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/boolean' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(Boolean, $obj, $attr, $args); + }; + + implements build_fields_for_type_Password => as { return }; + + implements build_fields_for_type_Str => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/string' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(String, $obj, $attr, $args); + }; + + implements build_fields_for_type_SimpleStr => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/string' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(String, $obj, $attr, $args); + }; + + implements build_fields_for_type_DateTime => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/date_time' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(DateTime, $obj, $attr, $args); + }; + + implements build_fields_for_type_Enum => as { + my ($self, $obj, $attr, $args) = @_; + $args->{Field}{$attr->name}{layout} = 'value/string' + unless( exists $args->{Field}{$attr->name} && + exists $args->{Field}{$attr->name}{layout} && + defined $args->{Field}{$attr->name}{layout} + ); + return $self->build_simple_field(String, $obj, $attr, $args); + }; + }; diff --git a/lib/Reaction/UI/ViewPort/GridView/Row.pm b/lib/Reaction/UI/ViewPort/GridView/Row.pm index 2edb06a..6c84967 100644 --- a/lib/Reaction/UI/ViewPort/GridView/Row.pm +++ b/lib/Reaction/UI/ViewPort/GridView/Row.pm @@ -77,6 +77,7 @@ class Row is 'Reaction::UI::ViewPort::ObjectView', which { around build_fields_for_type_ArrayRef => sub { my ($orig, $self, $attr, $args) = @_; + return; $args->{Field}{$attr->name}{layout} = 'value/list' unless( exists $args->{Field}{$attr->name} && exists $args->{Field}{$attr->name}{layout} && @@ -87,6 +88,7 @@ class Row is 'Reaction::UI::ViewPort::ObjectView', which { around build_fields_for_type_Reaction_InterfaceModel_Collection => sub { my ($orig, $self, $attr, $args) = @_; + return; $args->{Field}{$attr->name}{layout} = 'value/collection' unless( exists $args->{Field}{$attr->name} && exists $args->{Field}{$attr->name}{layout} && @@ -97,6 +99,7 @@ class Row is 'Reaction::UI::ViewPort::ObjectView', which { around build_fields_for_type_Reaction_InterfaceModel_Object => sub { my ($orig, $self, $attr, $args) = @_; + return; $args->{Field}{$attr->name}{layout} = 'value/related_object' unless( exists $args->{Field}{$attr->name} && exists $args->{Field}{$attr->name}{layout} && diff --git a/lib/Reaction/UI/ViewPort/ListView.pm b/lib/Reaction/UI/ViewPort/ListView.pm index 94e4de1..7430413 100644 --- a/lib/Reaction/UI/ViewPort/ListView.pm +++ b/lib/Reaction/UI/ViewPort/ListView.pm @@ -4,8 +4,8 @@ use Reaction::Class; class ListView is 'Reaction::UI::ViewPort::GridView', which { - does 'Reaction::UI::ViewPort::GridView::Role::Order'; - does 'Reaction::UI::ViewPort::GridView::Role::Pager'; + #does 'Reaction::UI::ViewPort::GridView::Role::Order'; + #does 'Reaction::UI::ViewPort::GridView::Role::Pager'; }; diff --git a/lib/Reaction/UI/Widget/GridView.pm b/lib/Reaction/UI/Widget/GridView.pm index bb2f526..bb7494c 100644 --- a/lib/Reaction/UI/Widget/GridView.pm +++ b/lib/Reaction/UI/Widget/GridView.pm @@ -3,7 +3,7 @@ package Reaction::UI::Widget::GridView; use Reaction::UI::WidgetClass; class GridView, which { - widget renders [ qw/header rows footer/ + widget renders [ qw/header body footer/ => { viewport => func('self', 'viewport') } ]; @@ -15,58 +15,11 @@ class GridView, which { footer_row renders [ footer_cell over func('viewport', 'column_names') ]; footer_cell renders [ string { $_ } ]; - rows renders [ viewport over func('viewport','rows') ]; + + body renders [ body_row over func('viewport','rows')]; + body_row renders [ body_cell over $_ ]; #over $_ ? heeelp + body_cell renders [ 'viewport' ]; }; 1; - - -=for layout widget -<table> - [% header %] -<tbody> - [% rows %] -</tbody> -<tfoot> - [% footer %] -</tfoot> -</table> - -=for layout header - -<thead> - [% content %] -</thead> - -=for layout header_row - -<tr> - [% content %] -</tr> - -=for layout header_cell - -<th> [% content %] </th> - -=for layout footer - -<tfoot> - [% content %] -</tfoot> - -=for layout footer_row - -<tr> [% content %] </tr> - -=for layout footer_cell - -<td> [% content %] </td> - -=for layout rows - -<tbody> - [% content %] -</tbody> - -=cut diff --git a/lib/Reaction/UI/Widget/GridView/Row.pm b/lib/Reaction/UI/Widget/GridView/Row.pm index 8ed46e0..24cb098 100644 --- a/lib/Reaction/UI/Widget/GridView/Row.pm +++ b/lib/Reaction/UI/Widget/GridView/Row.pm @@ -1,8 +1,8 @@ -package Reaction::UI::Widget::ObjectView; +package Reaction::UI::Widget::GridView::Row; use Reaction::UI::WidgetClass; -class ObjectView, which { +class Row, which { widget renders [ cells => { viewport => func('self', 'viewport') } ]; cells renders [ cell over func('viewport', 'ordered_fields') ]; cell renders [ 'viewport' ]; diff --git a/lib/Reaction/UI/WidgetClass.pm b/lib/Reaction/UI/WidgetClass.pm index 9e40936..83e3076 100644 --- a/lib/Reaction/UI/WidgetClass.pm +++ b/lib/Reaction/UI/WidgetClass.pm @@ -65,11 +65,11 @@ class WidgetClass, which { if (defined($args) && (ref($args) ne 'HASH')); $sig .= ' - where content spec is [ fragment_name over func(...), \%args? ] +where content spec is [ fragment_name over (func(...)|$_|$_{keyname}), \%args? ] or [ qw(list of fragment names), \%args ]'; # explain the mistake, yea my $inner_args = ((ref($content->[-1]) eq 'HASH') ? pop(@$content) : {}); - # [ blah over func(...), { ... } ] or [ qw(foo bar), { ... } ] + # [ blah over (func(...)|$_|$_{keyname}), { ... } ] or [ qw(foo bar), { ... } ] # predeclare since content_gen gets populated somewhere in an if # and inner_args_gen wants to be closed over by content_gen @@ -95,13 +95,23 @@ class WidgetClass, which { # - if arrayref, render fragment per entry # - if obj and can('next') call that until undef # - else scream loudly - my ($func_key, $func_meth) = @$func; + unless ((ref($func) eq 'ARRAY') || ($func =~ /^-topic:(.*)$/)) { + confess "over value wrong, should be ${sig}"; + } $content_gen = sub { my ($widget, $args) = @_; - my $topic = eval { $args->{$func_key}->$func_meth }; - confess "Error calling ${func_meth} on ${func_key} argument " - .($args->{$func_key}||'').": $@" - if $@; + my $topic; + if (ref($func) eq 'ARRAY') { + my ($func_key, $func_meth) = @$func; + $topic = eval { $args->{$func_key}->$func_meth }; + confess "Error calling ${func_meth} on ${func_key} argument " + .($args->{$func_key}||'').": $@" + if $@; + } elsif ($func =~ /^-topic:(.*)$/) { + $topic = $args->{$1}; + } else { + confess "Shouldn't get here"; + } my $iter_sub; if (ref $topic eq 'ARRAY') { my @copy = @$topic; # non-destructive on original data diff --git a/share/skin/default/layout/action_form b/share/skin/default/layout/action_form.tt index 0e18a36..0e18a36 100644 --- a/share/skin/default/layout/action_form +++ b/share/skin/default/layout/action_form.tt diff --git a/share/skin/default/layout/display_field/boolean b/share/skin/default/layout/display_field/boolean.tt index 74e02e4..74e02e4 100644 --- a/share/skin/default/layout/display_field/boolean +++ b/share/skin/default/layout/display_field/boolean.tt diff --git a/share/skin/default/layout/display_field/collection b/share/skin/default/layout/display_field/collection.tt index 3bc65a9..3bc65a9 100644 --- a/share/skin/default/layout/display_field/collection +++ b/share/skin/default/layout/display_field/collection.tt diff --git a/share/skin/default/layout/display_field/date_time b/share/skin/default/layout/display_field/date_time.tt index 1fcad1a..1fcad1a 100644 --- a/share/skin/default/layout/display_field/date_time +++ b/share/skin/default/layout/display_field/date_time.tt diff --git a/share/skin/default/layout/display_field/list b/share/skin/default/layout/display_field/list.tt index 2b049b5..2b049b5 100644 --- a/share/skin/default/layout/display_field/list +++ b/share/skin/default/layout/display_field/list.tt diff --git a/share/skin/default/layout/display_field/number b/share/skin/default/layout/display_field/number.tt index 1fcad1a..1fcad1a 100644 --- a/share/skin/default/layout/display_field/number +++ b/share/skin/default/layout/display_field/number.tt diff --git a/share/skin/default/layout/display_field/related_object b/share/skin/default/layout/display_field/related_object.tt index 1fcad1a..1fcad1a 100644 --- a/share/skin/default/layout/display_field/related_object +++ b/share/skin/default/layout/display_field/related_object.tt diff --git a/share/skin/default/layout/display_field/string b/share/skin/default/layout/display_field/string.tt index 831cad4..831cad4 100644 --- a/share/skin/default/layout/display_field/string +++ b/share/skin/default/layout/display_field/string.tt diff --git a/share/skin/default/layout/display_field/text b/share/skin/default/layout/display_field/text.tt index 831cad4..831cad4 100644 --- a/share/skin/default/layout/display_field/text +++ b/share/skin/default/layout/display_field/text.tt diff --git a/share/skin/default/layout/field/boolean b/share/skin/default/layout/field/boolean.tt index 73b817e..73b817e 100644 --- a/share/skin/default/layout/field/boolean +++ b/share/skin/default/layout/field/boolean.tt diff --git a/share/skin/default/layout/field/choose_many b/share/skin/default/layout/field/choose_many.tt index 1479de8..1479de8 100644 --- a/share/skin/default/layout/field/choose_many +++ b/share/skin/default/layout/field/choose_many.tt diff --git a/share/skin/default/layout/field/choose_one b/share/skin/default/layout/field/choose_one.tt index 2fd39d6..2fd39d6 100644 --- a/share/skin/default/layout/field/choose_one +++ b/share/skin/default/layout/field/choose_one.tt diff --git a/share/skin/default/layout/field/date_time b/share/skin/default/layout/field/date_time.tt index 4dbd294..4dbd294 100644 --- a/share/skin/default/layout/field/date_time +++ b/share/skin/default/layout/field/date_time.tt diff --git a/share/skin/default/layout/field/file b/share/skin/default/layout/field/file.tt index 7d323d8..7d323d8 100644 --- a/share/skin/default/layout/field/file +++ b/share/skin/default/layout/field/file.tt diff --git a/share/skin/default/layout/field/hidden_array b/share/skin/default/layout/field/hidden_array.tt index ebc06af..ebc06af 100644 --- a/share/skin/default/layout/field/hidden_array +++ b/share/skin/default/layout/field/hidden_array.tt diff --git a/share/skin/default/layout/field/number b/share/skin/default/layout/field/number.tt index 201220f..201220f 100644 --- a/share/skin/default/layout/field/number +++ b/share/skin/default/layout/field/number.tt diff --git a/share/skin/default/layout/field/password b/share/skin/default/layout/field/password.tt index e29029a..e29029a 100644 --- a/share/skin/default/layout/field/password +++ b/share/skin/default/layout/field/password.tt diff --git a/share/skin/default/layout/field/string b/share/skin/default/layout/field/string.tt index 40f3789..40f3789 100644 --- a/share/skin/default/layout/field/string +++ b/share/skin/default/layout/field/string.tt diff --git a/share/skin/default/layout/field/text b/share/skin/default/layout/field/text.tt index b68ce67..b68ce67 100644 --- a/share/skin/default/layout/field/text +++ b/share/skin/default/layout/field/text.tt diff --git a/share/skin/default/layout/field/time_range b/share/skin/default/layout/field/time_range.tt index 954c40b..954c40b 100644 --- a/share/skin/default/layout/field/time_range +++ b/share/skin/default/layout/field/time_range.tt diff --git a/share/skin/default/layout/grid_view b/share/skin/default/layout/grid_view.tt index d4826b0..3205e60 100644 --- a/share/skin/default/layout/grid_view +++ b/share/skin/default/layout/grid_view.tt @@ -2,12 +2,8 @@ <table> [% header %] -<tbody> - [% rows %] -</tbody> -<tfoot> + [% body %] [% footer %] -</tfoot> </table> =for layout header @@ -40,10 +36,18 @@ <td> [% content %] </td> -=for layout rows +=for layout body <tbody> [% content %] </tbody> +=for layout body_row + +<tr> [% content %] </tr> + +=for layout body_cell + +<td> [% content %] </td> + =cut diff --git a/share/skin/default/layout/index b/share/skin/default/layout/index.tt index 9a9bc9c..9a9bc9c 100644 --- a/share/skin/default/layout/index +++ b/share/skin/default/layout/index.tt diff --git a/share/skin/default/layout/layout b/share/skin/default/layout/layout.tt index af59032..af59032 100644 --- a/share/skin/default/layout/layout +++ b/share/skin/default/layout/layout.tt diff --git a/share/skin/default/layout/list_view b/share/skin/default/layout/list_view.tt index d4826b0..3205e60 100644 --- a/share/skin/default/layout/list_view +++ b/share/skin/default/layout/list_view.tt @@ -2,12 +2,8 @@ <table> [% header %] -<tbody> - [% rows %] -</tbody> -<tfoot> + [% body %] [% footer %] -</tfoot> </table> =for layout header @@ -40,10 +36,18 @@ <td> [% content %] </td> -=for layout rows +=for layout body <tbody> [% content %] </tbody> +=for layout body_row + +<tr> [% content %] </tr> + +=for layout body_cell + +<td> [% content %] </td> + =cut diff --git a/share/skin/default/layout/object_view b/share/skin/default/layout/object_view.tt index 4e6e1b3..4e6e1b3 100644 --- a/share/skin/default/layout/object_view +++ b/share/skin/default/layout/object_view.tt diff --git a/share/skin/default/layout/value/boolean b/share/skin/default/layout/value/boolean.tt index 1ce3367..1ce3367 100644 --- a/share/skin/default/layout/value/boolean +++ b/share/skin/default/layout/value/boolean.tt diff --git a/share/skin/default/layout/value/collection b/share/skin/default/layout/value/collection.tt index d376ecc..d376ecc 100644 --- a/share/skin/default/layout/value/collection +++ b/share/skin/default/layout/value/collection.tt diff --git a/share/skin/default/layout/value/date_time b/share/skin/default/layout/value/date_time.tt index e35741c..e35741c 100644 --- a/share/skin/default/layout/value/date_time +++ b/share/skin/default/layout/value/date_time.tt diff --git a/share/skin/default/layout/value/list b/share/skin/default/layout/value/list.tt index eea4e02..eea4e02 100644 --- a/share/skin/default/layout/value/list +++ b/share/skin/default/layout/value/list.tt diff --git a/share/skin/default/layout/value/number b/share/skin/default/layout/value/number.tt index e35741c..e35741c 100644 --- a/share/skin/default/layout/value/number +++ b/share/skin/default/layout/value/number.tt diff --git a/share/skin/default/layout/value/related_object b/share/skin/default/layout/value/related_object.tt index e35741c..e35741c 100644 --- a/share/skin/default/layout/value/related_object +++ b/share/skin/default/layout/value/related_object.tt diff --git a/share/skin/default/layout/value/string b/share/skin/default/layout/value/string.tt index 1ce3367..1ce3367 100644 --- a/share/skin/default/layout/value/string +++ b/share/skin/default/layout/value/string.tt diff --git a/share/skin/default/layout/value/text b/share/skin/default/layout/value/text.tt index 1ce3367..1ce3367 100644 --- a/share/skin/default/layout/value/text +++ b/share/skin/default/layout/value/text.tt |