It is starting to look like this may actually work after all. Listview is the only...
groditi [Sat, 29 Sep 2007 20:40:12 +0000 (20:40 +0000)]
70 files changed:
componentui.conf
lib/ComponentUI.pm
lib/ComponentUI/Controller/Root.pm
lib/ComponentUI/View/Site.pm [new file with mode: 0644]
lib/ComponentUI/View/Site/Widget/Index.pm [new file with mode: 0644]
lib/ComponentUI/View/Site/Widget/Layout.pm [new file with mode: 0644]
lib/Reaction/UI/LayoutSet.pm
lib/Reaction/UI/LayoutSet/TT.pm
lib/Reaction/UI/View.pm
lib/Reaction/UI/ViewPort/ActionForm.pm
lib/Reaction/UI/ViewPort/DisplayField/Boolean.pm
lib/Reaction/UI/ViewPort/DisplayField/Collection.pm
lib/Reaction/UI/ViewPort/DisplayField/DateTime.pm
lib/Reaction/UI/ViewPort/DisplayField/List.pm
lib/Reaction/UI/ViewPort/DisplayField/Number.pm
lib/Reaction/UI/ViewPort/DisplayField/RelatedObject.pm
lib/Reaction/UI/ViewPort/DisplayField/String.pm
lib/Reaction/UI/ViewPort/DisplayField/Text.pm
lib/Reaction/UI/ViewPort/Field.pm
lib/Reaction/UI/ViewPort/Field/Boolean.pm
lib/Reaction/UI/ViewPort/Field/ChooseMany.pm
lib/Reaction/UI/ViewPort/Field/ChooseOne.pm
lib/Reaction/UI/ViewPort/Field/DateTime.pm
lib/Reaction/UI/ViewPort/Field/File.pm
lib/Reaction/UI/ViewPort/Field/Number.pm
lib/Reaction/UI/ViewPort/Field/Password.pm
lib/Reaction/UI/ViewPort/Field/String.pm
lib/Reaction/UI/ViewPort/Field/Text.pm
lib/Reaction/UI/ViewPort/Field/TimeRange.pm
lib/Reaction/UI/ViewPort/ObjectView.pm
lib/Reaction/UI/ViewPort/TimeRangeCollection.pm
lib/Reaction/UI/Widget/ActionForm.pm
lib/Reaction/UI/Widget/DisplayField.pm
lib/Reaction/UI/Widget/Field.pm
lib/Reaction/UI/Widget/Field/Boolean.pm
lib/Reaction/UI/Widget/Field/ChooseMany.pm
lib/Reaction/UI/Widget/Field/ChooseOne.pm
lib/Reaction/UI/Widget/Field/DateTime.pm
lib/Reaction/UI/Widget/Field/File.pm
lib/Reaction/UI/Widget/Field/HiddenArray.pm
lib/Reaction/UI/Widget/Field/Number.pm
lib/Reaction/UI/Widget/Field/Password.pm
lib/Reaction/UI/Widget/Field/String.pm
lib/Reaction/UI/Widget/Field/Text.pm
lib/Reaction/UI/Widget/Field/TimeRange.pm
lib/Reaction/UI/Widget/ListView.pm
lib/Reaction/UI/Widget/ObjectView.pm
share/skin/default/layout/action_form
share/skin/default/layout/display_field/boolean
share/skin/default/layout/display_field/collection
share/skin/default/layout/display_field/date_time
share/skin/default/layout/display_field/list
share/skin/default/layout/display_field/number
share/skin/default/layout/display_field/related_object
share/skin/default/layout/display_field/string
share/skin/default/layout/display_field/text
share/skin/default/layout/field/boolean
share/skin/default/layout/field/choose_many
share/skin/default/layout/field/choose_one
share/skin/default/layout/field/date_time
share/skin/default/layout/field/file
share/skin/default/layout/field/number
share/skin/default/layout/field/password
share/skin/default/layout/field/string
share/skin/default/layout/field/text
share/skin/default/layout/field/time_range
share/skin/default/layout/index [new file with mode: 0644]
share/skin/default/layout/layout [new file with mode: 0644]
share/skin/default/layout/object_view
share/skin/default/web/componentui-basic.css [new file with mode: 0644]

index 2d43094..9a0ed59 100644 (file)
@@ -9,3 +9,7 @@ using_frontend_proxy 1
     </ViewPort>
   </Action>
 </Controller>
+
+<View Site>
+  skin_name default
+</View>
\ No newline at end of file
index f1938c5..ae7751f 100644 (file)
@@ -13,7 +13,7 @@ use Catalyst::Runtime '5.70';
 # Static::Simple: will serve static files from the application's root
 #                 directory
 
-use Catalyst qw/-Debug ConfigLoader Static::Simple I18N/;
+use Catalyst qw/ ConfigLoader -Debug Static::Simple I18N /;
 
 our $VERSION = '0.01';
 
index 1d7bd58..567cf3b 100644 (file)
@@ -12,15 +12,14 @@ use aliased 'Reaction::UI::ViewPort';
 # so they function identically to actions created in MyApp.pm
 #
 __PACKAGE__->config(
-  view_name => 'XHTML',
+  view_name => 'Site',
   window_title => 'Reaction Test App',
-  content_type => 'text/html',
-  namespace => '',
+  namespace => ''
 );
 
 sub base :Chained('/') :PathPart('') :CaptureArgs(0) {
   my ($self, $c) = @_;
-  $self->push_viewport(ViewPort, layout => 'xhtml');
+  $self->push_viewport(ViewPort, layout => 'layout');
 }
 
 sub root :Chained('base') :PathPart('') :Args(0) {
@@ -28,4 +27,16 @@ sub root :Chained('base') :PathPart('') :Args(0) {
   $self->push_viewport(ViewPort, layout => 'index');
 }
 
+sub static :Chained('base') :PathPart('static') :Args {
+  my ($self, $c, @args) = @_;
+  return if $c->stash->{window}->view->serve_static_file($c, \@args);
+  $c->forward('error_404');
+}
+
+sub error_404 :Private {
+  my ($self, $c) = @_;
+  $c->res->body("Error 404");
+  $c->res->status(404);
+}
+
 1;
diff --git a/lib/ComponentUI/View/Site.pm b/lib/ComponentUI/View/Site.pm
new file mode 100644 (file)
index 0000000..cbb2d28
--- /dev/null
@@ -0,0 +1,36 @@
+package ComponentUI::View::Site;
+
+use Reaction::Class;
+use aliased 'Reaction::UI::View::TT';
+
+class Site is TT, which {
+
+};
+
+
+use Class::MOP;
+
+{
+  my @reflect_widgets = qw(ActionForm ObjectView ListView
+                           Field::File
+                           Field::Password
+                           Field::Text        DisplayField::Text
+                           Field::Number      DisplayField::Number
+                           Field::String      DisplayField::String
+                           Field::Boolean     DisplayField::Boolean
+                           Field::DateTime    DisplayField::DateTime
+                           Field::ChooseOne   DisplayField::RelatedObject
+                           Field::ChooseMany  DisplayField::Collection
+                           Field::HiddenArray DisplayField::List
+                          );
+
+
+  for (@reflect_widgets){
+    my $base = "Reaction::UI::Widget::${_}";
+    my $target = "ComponentUI::View::Site::Widget::${_}";
+    Class::MOP::load_class( $base );
+    $base->meta->create($target, superclasses => [$base]);
+  }
+}
+
+1;
diff --git a/lib/ComponentUI/View/Site/Widget/Index.pm b/lib/ComponentUI/View/Site/Widget/Index.pm
new file mode 100644 (file)
index 0000000..21175ae
--- /dev/null
@@ -0,0 +1,11 @@
+package ComponentUI::View::Site::Widget::Index;
+
+use Reaction::UI::WidgetClass;
+
+class Index which {
+
+  widget renders  [ string {"DUMMY"} ];
+
+};
+
+1;
diff --git a/lib/ComponentUI/View/Site/Widget/Layout.pm b/lib/ComponentUI/View/Site/Widget/Layout.pm
new file mode 100644 (file)
index 0000000..380a03a
--- /dev/null
@@ -0,0 +1,17 @@
+package ComponentUI::View::Site::Widget::Layout;
+
+use Reaction::UI::WidgetClass;
+
+class Layout which {
+
+  widget renders  [ qw(menu sidebar header main_content) =>
+                    { viewport => func('self', 'viewport') } ];
+
+  menu         renders [ string { "DUMMY" }        ];
+  sidebar      renders [ string { "Sidebar Shit" } ];
+  header       renders [ string { "DUMMY" }        ];
+  main_content renders [ viewport over func('viewport', 'inner')];
+
+};
+
+1;
index 60d68d9..1cdb0e9 100644 (file)
@@ -18,6 +18,7 @@ class LayoutSet which {
     my $found;
     SEARCH: foreach my $path (@path) {
       my $cand = $path->file($self->name);
+      print STDERR $cand,"\n";
       if ($cand->stat) {
         $self->_load_file($cand);
         $found = 1;
@@ -44,7 +45,12 @@ class LayoutSet which {
 
   implements 'widget_type' => as {
     my ($self) = @_;
-    return join('', map { ucfirst($_) } split('_', $self->name));
+    my $widget = join('',   map { ucfirst($_) } split('_', $self->name));
+    $widget    = join('::', map { ucfirst($_) } split('/', $widget));
+
+    print STDERR "--- ", $self->name, " maps to widget $widget \n";
+
+    return $widget;
   };
 
 };
index 72d3fad..02b3cde 100644 (file)
@@ -23,6 +23,7 @@ class TT is LayoutSet, which {
       || confess "tt_object not provided to new()";
     my $tt_args = { data => {} };
     my $name = $self->name;
+    $name =~ s/\//__/g; #slashes are not happy here...
     my $fragments = $self->fragments;
     my $tt_source = qq{[% VIEW ${name};\n\n}.
                     join("\n\n",
@@ -39,6 +40,6 @@ class TT is LayoutSet, which {
     return $tt_args->{data}{view};
   };
 
-}; 
+};
 
 1;
index aa30878..987909c 100644 (file)
@@ -59,19 +59,23 @@ class View which {
     my $base = $self->blessed;
     my $tail = $layout_set->widget_type;
     my $class = join('::', $base, 'Widget', $tail);
-    Class::MOP::load_class($class);
+    eval { Class::MOP::load_class($class) };
+    confess "Couldn't load widget '$class': $@" if $@;
     return $class;
   };
 
   implements 'layout_set_for' => as {
     my ($self, $vp) = @_;
+    print STDERR "Getting layoutset for VP ".(ref($vp) || "SC:".$vp)."\n";
     my $lset_name = eval { $vp->layout };
     confess "Couldn't call layout method on \$vp arg ${vp}: $@" if $@;
     unless (length($lset_name)) {
-      my $last = (split('::', ref($vp)))[-1];
-      #previously: join("_", map { lc($_) } split(/(?=[A-Z])/, $last))
-      $last =~ s/([a-z0-9])([A-Z])/${1}_${2}/g
-      $lset_name = lc($last);
+      my $vp_class = ref($vp) || $vp;
+      my ($last) = ($vp_class =~ /.*(?:::ViewPort::)(.+?)$/);
+      my @fragments = split('::', $last);
+      $_ = join("_", split(/(?=[A-Z])/, $_)) for @fragments;
+      $lset_name = lc(join('/', @fragments));
+      print STDERR "--- $vp_class is rendered as $lset_name\n";
     }
     my $cache = $self->_layout_set_cache;
     return $cache->{$lset_name} ||= $self->create_layout_set($lset_name);
@@ -86,7 +90,7 @@ class View which {
 
   implements 'find_related_class' => as {
     my ($self, $rel) = @_;
-    my $own_class = ref($self)||$self;
+    my $own_class = ref($self) || $self;
     confess View." is abstract, you must subclass it" if $own_class eq View;
     foreach my $super ($own_class->meta->class_precedence_list) {
       next if $super eq View;
index bb97bf3..b28c25d 100644 (file)
@@ -16,45 +16,45 @@ use aliased 'Reaction::UI::ViewPort::Field::TimeRange';
 
 class ActionForm is 'Reaction::UI::ViewPort', which {
   has action => (
-    isa => 'Reaction::InterfaceModel::Action', is => 'ro', required => 1
-  );
+                 isa => 'Reaction::InterfaceModel::Action', is => 'ro', required => 1
+                );
 
   has ordered_fields => (is => 'rw', isa => 'ArrayRef', lazy_build => 1);
 
   has _field_map => (
-    isa => 'HashRef', is => 'rw', init_arg => 'fields', lazy_build => 1,
-  );
+                     isa => 'HashRef', is => 'rw', init_arg => 'fields', lazy_build => 1,
+                    );
 
   has changed => (
-    isa => 'Int', is => 'rw', reader => 'is_changed', default => sub { 0 }
-  );
+                  isa => 'Int', is => 'rw', reader => 'is_changed', default => sub { 0 }
+                 );
 
   has next_action => (
-    isa => 'ArrayRef', is => 'rw', required => 0, predicate => 'has_next_action'
-  );
+                      isa => 'ArrayRef', is => 'rw', required => 0, predicate => 'has_next_action'
+                     );
 
   has on_apply_callback => (
-    isa => 'CodeRef', is => 'rw', required => 0,
-    predicate => 'has_on_apply_callback'
-  );
+                            isa => 'CodeRef', is => 'rw', required => 0,
+                            predicate => 'has_on_apply_callback'
+                           );
 
   has ok_label => (
-    isa => 'Str', is => 'rw', required => 1, default => sub { 'ok' }
-  );
+                   isa => 'Str', is => 'rw', required => 1, default => sub { 'ok' }
+                  );
 
   has apply_label => (
-    isa  => 'Str', is => 'rw', required => 1, default => sub { 'apply' }
-  );
+                      isa  => 'Str', is => 'rw', required => 1, default => sub { 'apply' }
+                     );
 
   has close_label => (isa => 'Str', is => 'rw', lazy_fail => 1);
 
   has close_label_close => (
-    isa => 'Str', is => 'rw', required => 1, default => sub { 'close' }
-  );
+                            isa => 'Str', is => 'rw', required => 1, default => sub { 'close' }
+                           );
 
   has close_label_cancel => (
-    isa => 'Str', is => 'rw', required => 1, default => sub { 'cancel' }
-  );
+                             isa => 'Str', is => 'rw', required => 1, default => sub { 'cancel' }
+                            );
 
   sub fields { shift->_field_map }
 
@@ -83,7 +83,7 @@ class ActionForm is 'Reaction::UI::ViewPort', which {
       my $constraint = $attr->type_constraint;
       my $base_name = $constraint->name;
       my $tried_isa = 0;
-      CONSTRAINT: while (defined($constraint)) {
+    CONSTRAINT: while (defined($constraint)) {
         my $name = $constraint->name;
         if (eval { $name->can('meta') } && !$tried_isa++) {
           foreach my $class ($name->meta->class_precedence_list) {
@@ -125,16 +125,17 @@ class ActionForm is 'Reaction::UI::ViewPort', which {
 
   implements build_ordered_fields => as {
     my $self = shift;
-    $self->sort_by_spec($self->column_order, [keys %{$self->_field_map_}])};
+    my $ordered = $self->sort_by_spec($self->column_order, [keys %{$self->_field_map}]);
+    return [@{$self->_field_map}{@$ordered}];
   };
 
   implements can_apply => as {
     my ($self) = @_;
-    foreach my $field (values %{$self->_field_map}) {
+    foreach my $field ( @{ $self->ordered_fields } ) {
       return 0 if $field->needs_sync;
-        # if e.g. a datetime field has an invalid value that can't be re-assembled
-        # into a datetime object, the action may be in a consistent state but
-        # not synchronized from the fields; in this case, we must not apply
+      # if e.g. a datetime field has an invalid value that can't be re-assembled
+      # into a datetime object, the action may be in a consistent state but
+      # not synchronized from the fields; in this case, we must not apply
     }
     return $self->action->can_apply;
   };
@@ -212,13 +213,13 @@ class ActionForm is 'Reaction::UI::ViewPort', which {
       %extra = %$config;
     }
     my $field = $class->new(
-                  action => $self->action,
-                  attribute => $attr,
-                  name => $attr->name,
-                  location => join('-', $self->location, 'field', $attr->name),
-                  ctx => $self->ctx,
-                  %extra
-                );
+                            action => $self->action,
+                            attribute => $attr,
+                            name => $attr->name,
+                            location => join('-', $self->location, 'field', $attr->name),
+                            ctx => $self->ctx,
+                            %extra
+                           );
     return ($attr_name => $field);
   };
 
@@ -297,7 +298,7 @@ class ActionForm is 'Reaction::UI::ViewPort', which {
 
 };
 
-1;
+  1;
 
 =head1 NAME
 
index 9389436..1502fe6 100644 (file)
@@ -5,7 +5,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class Boolean, is DisplayField, which {
     has '+value' => (isa => 'Bool');
-    has '+layout' => (default => 'displayfield/value_string');
+    #has '+layout' => (default => 'displayfield/value_string');
 
     has value_string => (isa => 'Str', is => 'rw', lazy_build => 1);
 
index f4cec97..02383cf 100644 (file)
@@ -5,7 +5,7 @@ use Scalar::Util 'blessed';
 
 class Collection is 'Reaction::UI::ViewPort::DisplayField', which {
   has '+value' => (isa => 'ArrayRef');
-  has '+layout' => (default => 'displayfield/list');
+  #has '+layout' => (default => 'displayfield/list');
 
   has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
 
index 92d5b81..b8e8d89 100644 (file)
@@ -6,7 +6,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class DateTime is DisplayField, which {
   has '+value' => (isa => 'DateTime');
-  has '+layout' => (default => 'displayfield/value_string');
+  #has '+layout' => (default => 'displayfield/value_string');
 
   has value_string => (isa => 'Str',  is => 'rw', lazy_build => 1);
 
index d70f1ed..76fa250 100644 (file)
@@ -6,7 +6,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class List is DisplayField, which {
   has '+value' => (isa => 'ArrayRef');
-  has '+layout' => (default => 'displayfield/list');
+  #has '+layout' => (default => 'displayfield/list');
 
   has value_names => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
 
index 7c46d06..358154d 100644 (file)
@@ -4,7 +4,7 @@ use Reaction::Class;
 use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class Number is DisplayField, which {
-  has '+layout' => (default => 'displayfield/string');
+  #has '+layout' => (default => 'displayfield/string');
 };
 
 1;
index 3cd217c..9700ac0 100644 (file)
@@ -6,7 +6,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class RelatedObject is DisplayField, which {
 
-  has '+layout' => (default => 'displayfield/value_string');
+  #has '+layout' => (default => 'displayfield/value_string');
 
   has value_string => (isa => 'Str', is => 'ro', lazy_build => 1);
 
index 3aab498..530cd08 100644 (file)
@@ -5,7 +5,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class String is DisplayField, which {
   has '+value' => (isa => 'Str');
-  has '+layout' => (default => 'displayfield/string');
+  #has '+layout' => (default => 'displayfield/string');
 };
 
 1;
index c9e2c27..ea68e8c 100644 (file)
@@ -5,7 +5,7 @@ use aliased 'Reaction::UI::ViewPort::DisplayField';
 
 class Text is DisplayField, which {
   has '+value' => (isa => 'Str');
-  has '+layout' => (default => 'displayfield/text');
+  #has '+layout' => (default => 'displayfield/text');
 };
 
 1;
index 41a7c42..06d0598 100644 (file)
@@ -42,7 +42,9 @@ class Field is 'Reaction::UI::ViewPort', which {
 
   implements build_label => as {
     my ($self) = @_;
-    return join(' ', map { ucfirst } split('_', $self->name));
+    my $label = join(' ', map { ucfirst } split('_', $self->name));
+    print STDERR "Field " . $self->name . " has label '$label'\n";
+    return $label;
   };
 
   implements build_value => as {
index 34f7aae..fb0d886 100644 (file)
@@ -5,11 +5,11 @@ use Reaction::Class;
 class Boolean is 'Reaction::UI::ViewPort::Field', which {
 
   has '+value' => (isa => 'Bool');
-  has '+layout' => (default => 'checkbox');
+  #has '+layout' => (default => 'checkbox');
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index 35f6710..9337a3c 100644 (file)
@@ -4,7 +4,7 @@ use Reaction::Class;
 
 class ChooseMany is 'Reaction::UI::ViewPort::Field::ChooseOne', which {
 
-  has '+layout' => (default => 'dual_select_group');
+  #has '+layout' => (default => 'dual_select_group');
   has '+value' => (isa => 'ArrayRef');
 
   my $listify = sub {                  # quick utility function, $listify->($arg)
index 0d44fd7..703a26f 100644 (file)
@@ -6,7 +6,7 @@ use Scalar::Util 'blessed';
 
 class ChooseOne is 'Reaction::UI::ViewPort::Field', which {
 
-  has '+layout' => (default => 'select');
+  #has '+layout' => (default => 'select');
 
   has valid_values  => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
   has value_choices => (isa => 'ArrayRef', is => 'ro', lazy_build => 1);
index 2b8509f..6d2958f 100644 (file)
@@ -7,18 +7,18 @@ use Time::ParseDate ();
 class DateTime is 'Reaction::UI::ViewPort::Field', which {
 
   has '+value' => (isa => 'DateTime');
-  
-  has '+layout' => (default => 'dt_textfield');
-  
+
+  #has '+layout' => (default => 'dt_textfield');
+
   has value_string => (
     isa => 'Str', is => 'rw', lazy_build => 1,
     trigger_adopt('value_string')
   );
-  
+
   has value_string_default_format => (
     isa => 'Str', is => 'rw', required => 1, default => sub { "%F %H:%M:%S" }
   );
-  
+
   implements build_value_string => as {
     my $self = shift;
 
@@ -29,11 +29,11 @@ class DateTime is 'Reaction::UI::ViewPort::Field', which {
     #<mst> eval { $self->value } ... is probably the best solution atm
     my $value = eval { $self->value };
     return '' unless $self->has_value;
-    my $format = $self->value_string_default_format;  
+    my $format = $self->value_string_default_format;
     return $value->strftime($format) if $value;
     return '';
   };
-  
+
   implements adopt_value_string => as {
     my ($self) = @_;
     my $value = $self->value_string;
@@ -47,14 +47,14 @@ class DateTime is 'Reaction::UI::ViewPort::Field', which {
       $self->needs_sync(1);
     }
   };
-  
+
   override accept_events => sub {
     ('value_string', super());
   };
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index 557826d..a1d181c 100644 (file)
@@ -6,9 +6,9 @@ use Reaction::Types::File;
 class File is 'Reaction::UI::ViewPort::Field', which {
 
   has '+value' => (isa => 'File', required => 0);
-  
-  has '+layout' => (default => 'file');
-  
+
+  #has '+layout' => (default => 'file');
+
   override apply_our_events => sub {
     my ($self, $ctx, $events) = @_;
     my $value_key = join(':', $self->location, 'value');
index e4e925f..f66e03d 100644 (file)
@@ -4,11 +4,11 @@ use Reaction::Class;
 
 class Number is 'Reaction::UI::ViewPort::Field', which {
 
-  has '+layout' => (default => 'textfield');
+  #has '+layout' => (default => 'textfield');
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index d70ed62..bc86341 100644 (file)
@@ -5,11 +5,11 @@ use Reaction::Class;
 class Password is 'Reaction::UI::ViewPort::Field::String', which {
 
   has '+value' => (isa => 'SimpleStr');
-  has '+layout' => (default => 'password');
+  #has '+layout' => (default => 'password');
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index 4be6bdc..6075592 100644 (file)
@@ -6,12 +6,12 @@ class String is 'Reaction::UI::ViewPort::Field', which {
 
   has '+value' => (isa => 'Str'); # accept over 255 chars in case, upstream
                                   # constraint from model should catch it
-  
-  has '+layout' => (default => 'textfield');
+
+  #has '+layout' => (default => 'textfield');
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index d4e89f8..16d4e56 100644 (file)
@@ -5,11 +5,11 @@ use Reaction::Class;
 class Text is 'Reaction::UI::ViewPort::Field', which {
 
   has '+value' => (isa => 'Str');
-  has '+layout' => (default => 'textarea');
+  #has '+layout' => (default => 'textarea');
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index 3619b5e..fb11841 100644 (file)
@@ -9,34 +9,34 @@ use Time::ParseDate ();
 class TimeRange is 'Reaction::UI::ViewPort::Field', which {
 
   has '+value' => (isa => 'DateTime::SpanSet');
-  
-  has '+layout' => (default => 'timerange');
-  
-  has value_string => 
+
+  #has '+layout' => (default => 'timerange');
+
+  has value_string =>
     (isa => 'Str',  is => 'rw', lazy_fail => 1, trigger_adopt('value_string'));
-  
+
   has delete_label => (
     isa => 'Str', is => 'rw', required => 1, default => sub { 'Delete' },
   );
-  
+
   has parent => (
     isa => 'Reaction::UI::ViewPort::TimeRangeCollection',
     is => 'ro',
     required => 1,
     is_weak_ref => 1
   );
-  
+
   implements build_value_string => as {
     my $self = shift;
     #return '' unless $self->has_value;
     #return $self->value_string;
   };
-  
+
   implements value_array => as {
     my $self = shift;
     return split(',', $self->value_string);
   };
-  
+
   implements adopt_value_string => as {
     my ($self) = @_;
     my @values = $self->value_array;
@@ -44,11 +44,11 @@ class TimeRange is 'Reaction::UI::ViewPort::Field', which {
       if (length $values[$idx]) {
         my ($epoch) = Time::ParseDate::parsedate($values[$idx], UK => 1);
         $values[$idx] = DateTime->from_epoch( epoch => $epoch );
-      } 
+      }
     }
     $self->value($self->range_to_spanset(@values));
   };
-  
+
   implements range_to_spanset => as {
     my ($self, $time_from, $time_to, $repeat_from, $repeat_to, $pattern) = @_;
     my $spanset = DateTime::SpanSet->empty_set;
@@ -63,7 +63,7 @@ class TimeRange is 'Reaction::UI::ViewPort::Field', which {
                   hours => $time_from->hour,
                 minutes => $time_from->minute,
                 seconds => $time_from->second );
-  
+
       delete $args{'days'} if ($pattern eq 'daily');
       delete @args{qw/hours days/} if ($pattern eq 'hourly');
       $args{'days'} = $time_from->day if ($pattern eq 'monthly');
@@ -80,17 +80,17 @@ class TimeRange is 'Reaction::UI::ViewPort::Field', which {
     }
     return $spanset;
   };
-  
+
   implements delete => as {
     my ($self) = @_;
     $self->parent->remove_range_vp($self);
   };
-  
+
   override accept_events => sub { ('value_string', 'delete', super()) };
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
index cbb4c7b..7e1cac1 100644 (file)
@@ -37,7 +37,8 @@ class ObjectView is 'Reaction::UI::ViewPort', which {
         push(@field_map, $self->build_fields_for($attr => $args));
       }
 
-      $self->_field_map({ @field_map });
+      my %field_map = @field_map;
+      $self->_field_map( \%field_map );
     }
   };
 
@@ -94,7 +95,8 @@ class ObjectView is 'Reaction::UI::ViewPort', which {
 
   implements build_ordered_fields => as {
     my $self = shift;
-    $self->sort_by_spec($self->column_order, [keys %{$self->_field_map_}])};
+    my $ordered = $self->sort_by_spec($self->column_order, [keys %{$self->_field_map}]);
+    return [@{$self->_field_map}{@$ordered}];
   };
 
   implements build_simple_field => as {
@@ -152,7 +154,6 @@ class ObjectView is 'Reaction::UI::ViewPort', which {
     return $self->build_simple_field(String, $attr, $args);
   };
 
-
   implements build_fields_for_type_ArrayRef => as {
     my ($self, $attr, $args) = @_;
     return $self->build_simple_field(List, $attr, $args)
@@ -168,7 +169,6 @@ class ObjectView is 'Reaction::UI::ViewPort', which {
     return $self->build_simple_field(RelatedObject, $attr, $args);
   };
 
-
   no Moose;
 
   no strict 'refs';
index eb1b680..1ebc03b 100644 (file)
@@ -11,89 +11,89 @@ use aliased 'Reaction::UI::ViewPort::Field::TimeRange';
 
 class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
 
-  has '+layout' => (default => 'timerangecollection');
-  
+  #has '+layout' => (default => 'timerangecollection');
+
   has '+column_order' => (
     default => sub{[ qw/ time_from time_to pattern repeat_from repeat_to / ]},
   );
-  
+
   has time_from => (
     isa => 'Reaction::UI::ViewPort::Field::DateTime',
     is => 'rw', lazy_build => 1,
   );
-  
+
   has time_to => (
     isa => 'Reaction::UI::ViewPort::Field::DateTime',
     is => 'rw', lazy_build => 1,
   );
-  
+
   has repeat_from => (
     isa => 'Reaction::UI::ViewPort::Field::DateTime',
     is => 'rw', lazy_build => 1,
   );
-  
+
   has repeat_to => (
     isa => 'Reaction::UI::ViewPort::Field::DateTime',
     is => 'rw', lazy_build => 1,
   );
-  
+
   has pattern => (
     isa => 'Reaction::UI::ViewPort::Field::String',
   #  valid_values => [ qw/none daily weekly monthly/ ],
     is => 'rw', lazy_build => 1,
   );
-  
+
   has range_vps => (isa => 'ArrayRef', is => 'rw', lazy_build => 1,);
-  
+
   has max_range_vps => (isa => 'Int', is => 'rw', lazy_build => 1,);
-  
+
   has error => (
     isa => 'Str',
     is => 'rw',
     required => 0,
   );
-  
+
   has field_names => (
     isa => 'ArrayRef', is => 'rw',
     lazy_build => 1, clearer => 'clear_field_names',
   );
-  
+
   has _field_map => (
     isa => 'HashRef', is => 'rw', init_arg => 'fields',
     clearer => '_clear_field_map',
     predicate => '_has_field_map',
     set_or_lazy_build('field_map'),
   );
-  
+
   has on_next_callback => (
     isa => 'CodeRef',
     is => 'rw',
     predicate => 'has_on_next_callback',
   );
-  
+
   implements fields => as { shift->_field_map };
-  
+
   implements build_range_vps => as { [] };
-  
+
   implements spanset => as {
     my ($self) = @_;
     my $spanset = DateTime::SpanSet->empty_set;
     $spanset = $spanset->union($_->value) for @{$self->range_vps};
     return $spanset;
   };
-  
+
   implements range_strings => as {
     my ($self) = @_;
     return [ map { $_->value_string } @{$self->range_vps} ];
   };
-  
+
   implements remove_range_vp => as {
-    my ($self, $to_remove) = @_; 
+    my ($self, $to_remove) = @_;
     $self->range_vps([ grep { $_ != $to_remove } @{$self->range_vps} ]);
     $self->_clear_field_map;
     $self->clear_field_names;
   };
-  
+
   implements add_range_vp => as {
     my ($self) = @_;
     if ($self->can_add) {
@@ -124,7 +124,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
       push(@{$self->range_vps}, $field);
     }
   };
-  
+
   implements build_field_map => as {
     my ($self) = @_;
     my %map;
@@ -136,7 +136,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
     }
     return \%map;
   };
-  
+
   implements build_field_names => as {
     my ($self) = @_;
     return [
@@ -144,19 +144,19 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
       @{$self->column_order}
     ];
   };
-  
+
   implements can_add => as {
     my ($self) = @_;
     my $error;
     if ($self->time_to->has_value && $self->time_from->has_value) {
       my $time_to = $self->time_to->value;
       my $time_from = $self->time_from->value;
-  
+
       my ($pattern, $repeat_from, $repeat_to) = ('','','');
       $pattern = $self->pattern->value if $self->pattern->has_value;
       $repeat_from = $self->repeat_from->value if $self->repeat_from->has_value;
       $repeat_to = $self->repeat_to->value if $self->repeat_to->has_value;
-  
+
       my $duration = $time_to - $time_from;
       if ($time_to < $time_from) {
         $error = 'Please make sure that the Time To is after the Time From.';
@@ -191,7 +191,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
     $self->error($error);
     return !defined($error);
   };
-  
+
   implements build_simple_field => as {
     my ($self, $class, $name, $args) = @_;
     return $class->new(
@@ -201,53 +201,53 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
              %$args
            );
   };
-  
+
   implements build_time_to => as {
     my ($self) = @_;
     return $self->build_simple_field(DateTime, 'time_to', {});
   };
-  
+
   implements build_time_from => as {
     my ($self) = @_;
     return $self->build_simple_field(DateTime, 'time_from', {});
   };
-  
+
   implements build_repeat_to => as {
     my ($self) = @_;
     return $self->build_simple_field(DateTime, 'repeat_to', {});
   };
-  
+
   implements build_repeat_from => as {
     my ($self) = @_;
     return $self->build_simple_field(DateTime, 'repeat_from', {});
   };
-  
+
   implements build_pattern => as {
     my ($self) = @_;
     return $self->build_simple_field(String, 'pattern', {});
   };
-  
+
   implements next => as {
     $_[0]->on_next_callback->(@_);
   };
-  
+
   override accept_events => sub {
     my $self = shift;
     ('add_range_vp', ($self->has_on_next_callback ? ('next') : ()), super());
   };
-  
+
   override child_event_sinks => sub {
     my ($self) = @_;
     return ((grep { ref($_) =~ 'Hidden' } values %{$self->_field_map}),
             (grep { ref($_) !~ 'Hidden' } values %{$self->_field_map}),
             super());
   };
-  
+
   override apply_events => sub {
     my ($self, $ctx, $events) = @_;
-  
+
     # auto-inflate range fields based on number from hidden field
-  
+
     my $max = $events->{$self->location.':max_range_vps'};
     my @range_vps = map {
       TimeRange->new(
@@ -260,15 +260,15 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
     $self->range_vps(\@range_vps);
     $self->_clear_field_map;
     $self->clear_field_names;
-  
+
     # call original event handling
-  
+
     super();
-  
-    # repack range VPs in case of deletion  
-  
+
+    # repack range VPs in case of deletion
+
     my $prev_idx = -1;
-  
+
     foreach my $vp (@{$self->range_vps}) {
       my $cur_idx = ($vp->name =~ m/range-(\d+)/);
       if (($cur_idx - $prev_idx) > 1) {
@@ -283,7 +283,7 @@ class TimeRangeCollection is 'Reaction::UI::ViewPort', which {
 
 };
 
-1;  
+1;
 
 =head1 NAME
 
@@ -347,11 +347,11 @@ Returns: $spanset consisting of all the TimeRange spans combined
 
 Returns: ArrayRef of Str consisting of the value_strings of all TimeRange
 VPs
+
 =head2 remove_range_vp
 
 Arguments: $to_remove
-  
+
 =head2 add_range_vp
 
 Arguments: $to_add
index a631130..1f32afb 100644 (file)
@@ -6,9 +6,11 @@ class ActionForm, which {
   widget renders [qw/header fields buttons footer/
                   => { viewport => func('self','viewport') } ];
 
-  fields renders [viewport over func('viewport','ordered_fields')];
+  fields renders [field over func('viewport','ordered_fields')];
+  field  renders [ 'viewport' ];
 
-  buttons renders [ string {"DUMMY"} ], {message => func('viewport','message');
+  buttons renders [ string {"DUMMY"} ],
+    {message => sub{ $_{viewport}->can('message') ? $_{viewport}->message : "" } };
   header  renders [ string {"DUMMY"} ];
   footer  renders [ string {"DUMMY"} ];
 
@@ -18,7 +20,6 @@ class ActionForm, which {
 
 __END__;
 
-
 =head1 NAME
 
 Reaction::UI::Widget::ActionForm
index c454188..2521dd3 100644 (file)
@@ -2,7 +2,7 @@ package Reaction::UI::Widget::DisplayField;
 
 use Reaction::UI::WidgetClass;
 
-class Text, which {
+class DisplayField, which {
   widget renders [ qw/label value/ => { viewport => func(self => 'viewport') } ];
   label  renders [ string { $_{viewport}->label } ];
   value  renders [ string { $_{viewport}->value } ];
@@ -10,6 +10,8 @@ class Text, which {
 
 1;
 
+__END__;
+
 =head1 NAME
 
 Reaction::UI::Widget::DisplayField
index 6425f15..11f2c67 100644 (file)
@@ -25,6 +25,8 @@ class Field, which {
 
 1;
 
+__END__;
+
 =head1 NAME
 
 Reaction::UI::Widget::Field
index 536764c..a4defcd 100644 (file)
@@ -8,6 +8,8 @@ class Boolean is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
+
 =head1 NAME
 
 Reaction::UI::Widget::Field::Boolean
index bd11672..6e9ef47 100644 (file)
@@ -12,11 +12,13 @@ class ChooseMany is 'Reaction::UI::Widget::Field', which {
   available_values renders [ option over func('viewport', 'available_value_choices') ];
   selected_values  renders [ option over func('viewport', 'current_value_choices')   ];
   option renders [string {"DUMMY"}], { v_value => sub {$_->{value}}, v_name => sub {$_->{name}} };
+  action_buttons renders [ string {"DUMMY"} ];
 
 };
 
 1;
 
+__END__;
 
 =head1 NAME
 
index 7ac1898..9754e71 100644 (file)
@@ -18,6 +18,7 @@ class ChooseOne is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index 9181387..deea805 100644 (file)
@@ -10,6 +10,7 @@ class DateTime is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index aa079c7..ad17c83 100644 (file)
@@ -8,6 +8,7 @@ class File is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index 05cdd45..7ccead9 100644 (file)
@@ -11,6 +11,7 @@ class HiddenArray is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index 859e7c2..48ef120 100644 (file)
@@ -8,6 +8,7 @@ class Number is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index 3b53b54..7525530 100644 (file)
@@ -8,6 +8,7 @@ class Password is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index eb25c8f..7e64510 100644 (file)
@@ -8,6 +8,8 @@ class String is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
+
 =head1 NAME
 
 Reaction::UI::Widget::Field::String
index 1066633..9d5e603 100644 (file)
@@ -8,6 +8,7 @@ class Text is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index f96a2c8..bc2ba05 100644 (file)
@@ -8,6 +8,7 @@ class TimeRange is 'Reaction::UI::Widget::Field', which {
 
 1;
 
+__END__;
 
 =head1 NAME
 
index ab80d93..7d9801c 100644 (file)
@@ -3,24 +3,24 @@ package Reaction::UI::Widget::ListView;
 use Reaction::UI::WidgetClass;
 use aliased 'Reaction::UI::ViewPort::ListView' => 'ListView_VP';
 
-class ListView which {
+class ListView, which {
 
   has 'viewport' => (isa => ListView_VP, is => 'ro', required => 1);
 
   widget renders [
     qw(header body) => { viewport => func(self => 'viewport') }
   ];
-  
+
   header renders [ header_entry over func(viewport => 'field_names') ];
-  
+
   header_entry renders [ string { $_{viewport}->field_label_map->{ $_ } } ];
-  
+
   body renders [ row over func(viewport => 'current_page_collection') ];
-  
+
   row renders [
     col_entry over func(viewport => 'field_names') => { row => $_ }
   ];
-  
+
   col_entry renders [
     string {
       my $proto = $_{row}->$_;
@@ -35,6 +35,8 @@ class ListView which {
 
 1;
 
+__END__;
+
 =head1 NAME
 
 Reaction::UI::Widget::ListView
index 28614b6..067b73c 100644 (file)
@@ -3,8 +3,9 @@ package Reaction::UI::Widget::ObjectView;
 use Reaction::UI::WidgetClass;
 
 class ObjectView, which {
-  widget renders [ fields => { viewport   => func('self', 'viewport') } ];
-  fields renders [ viewport over func('viewport','ordered_fields')    } ];
+  widget renders [ fields => { viewport => func('self', 'viewport') } ];
+  fields renders [ field over func('viewport', 'ordered_fields')   ];
+  field renders  [ 'viewport' ];
 };
 
 1;
index fbbeb17..0e18a36 100644 (file)
 
 =for layout fields
 
+<p> [% content %] </p>
+
+=for layout field
+
 [% content %] <br />
 
 =for layout buttons
index dae2f22..74e02e4 100644 (file)
@@ -4,10 +4,10 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong > [% content | html %]: </strong>
 
 =for layout value
 
-[% content %]
+[% content | html %]
 
 =cut
\ No newline at end of file
index bea7fa5..3bc65a9 100644 (file)
@@ -5,16 +5,16 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong > [% content | html %]: </strong>
 
 =for layout list
 
 <ul>
-[% item %]
+[% content %]
 </ul>
 
 =for layout item
 
-<li>[% content %]</li>
+<li>[% content | html %]</li>
 
 =cut
index e531148..1fcad1a 100644 (file)
@@ -4,10 +4,10 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong> [% content | html %]: </strong>
 
 =for layout value
 
-[% content %]
+[% content | html %]
 
 =cut
index e000875..2b049b5 100644 (file)
@@ -5,16 +5,16 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong > [% content | html %]: </strong>
 
 =for layout list
 
 <ul>
-[% item %]
+[% content %]
 </ul>
 
 =for layout item
 
-<li>[% content %]</li>
+<li>[% content | html %]</li>
 
 =cut
\ No newline at end of file
index e531148..1fcad1a 100644 (file)
@@ -4,10 +4,10 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong> [% content | html %]: </strong>
 
 =for layout value
 
-[% content %]
+[% content | html %]
 
 =cut
index e531148..1fcad1a 100644 (file)
@@ -4,10 +4,10 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong> [% content | html %]: </strong>
 
 =for layout value
 
-[% content %]
+[% content | html %]
 
 =cut
index dae2f22..831cad4 100644 (file)
@@ -4,10 +4,10 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong> [% content | html %]: </strong>
 
 =for layout value
 
-[% content %]
+[% content | html %]
 
 =cut
\ No newline at end of file
index dae2f22..831cad4 100644 (file)
@@ -4,10 +4,10 @@
 
 =for layout label
 
-<strong > [ % content %]: </strong>
+<strong> [% content | html %]: </strong>
 
 =for layout value
 
-[% content %]
+[% content | html %]
 
 =cut
\ No newline at end of file
index 2ee1da2..73b817e 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index 8781021..1479de8 100644 (file)
@@ -44,7 +44,7 @@
 
 =for layout action_buttons
 
-<input type="submit" value="&gt;&gt;" name="[% viewport.event_id_for('add_all_values') | html %]" />
+<input type="submit" value="&gt;&gt;" name="[% viewport.event_id_for('add_all_values') | html %]" /> <br />
 <input type="submit" value="&gt;" name="[% viewport.event_id_for('do_add_values') | html %]" /> <br />
 <input type="submit" value="&lt;" name="[% viewport.event_id_for('do_remove_values') | html %]" /> <br />
 <input type="submit" value="&lt;&lt;" name="[% viewport.event_id_for('remove_all_values') | html %]" /> <br />
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span> <br />
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index 2378ff5..2fd39d6 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index b8dd3ea..4dbd294 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index 4c95907..7d323d8 100644 (file)
@@ -9,15 +9,17 @@
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index eaa9593..201220f 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
-=cut
\ No newline at end of file
+=cut
index ec42e2a..e29029a 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
-=cut
\ No newline at end of file
+=cut
index a17c243..40f3789 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index 0c6118a..b68ce67 100644 (file)
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
index 7b3bb6b..954c40b 100644 (file)
@@ -9,15 +9,17 @@ TODO
 =for layout label
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <label for="[% id | html %]"> [% content | html %]: </label>
-[% END %]
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <label> [% content_str | html %]: </label>
+[% END; %]
 
 =for layout message
 
 <!-- This conditional goes away when mst comes up with something better -->
-[% IF content %]
-  <span> [% content | html %] </span>
+[% content_str = GET content; %]
+[% IF content_str.length; %]
+  <span> [% content_str | html %] </span> <br />
 [% END %]
 
 =cut
diff --git a/share/skin/default/layout/index b/share/skin/default/layout/index
new file mode 100644 (file)
index 0000000..9a9bc9c
--- /dev/null
@@ -0,0 +1,5 @@
+=for layout widget
+
+<p>I hate programming.</p>
+
+=cut
\ No newline at end of file
diff --git a/share/skin/default/layout/layout b/share/skin/default/layout/layout
new file mode 100644 (file)
index 0000000..af59032
--- /dev/null
@@ -0,0 +1,56 @@
+=for layout widget
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+
+<head>
+  <title>Component UI Test Title</title>
+  
+  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+  <link rel="stylesheet" type="text/css" href="/static/componentui-basic.css" />
+
+</head>
+
+<body>
+  <div id="container">
+    <div id="header">
+     [% header %]
+    </div>
+
+    <div id="nav">
+       [% menu %]
+    </div>
+
+    <div id="contents">
+      <div id="wrapper">
+        [% sidebar %]
+        [% main_content %]
+      </div>
+      <div class="spacer"></div>
+    </div>
+  </div>
+</body>
+
+</html>
+
+=for layout main_content
+
+    [% content %]
+
+=for layout header
+
+<h1>Component UI Header</h1>
+
+=for layout sidebar
+        <div class="sidebar">
+          [% content %]
+        </div>
+
+=for layout menu
+        <ul class="menu">
+          <li> <a href="/testmodel/foo">Foo</a> </li>
+          <li> <a href="/testmodel/bar">Bar</a> </li>
+          <li> <a href="/testmodel/baz">Baz</a> </li>
+        </ul>
+=cut
\ No newline at end of file
index 41a16e8..4e6e1b3 100644 (file)
@@ -4,6 +4,12 @@
 
 =for layout fields
 
-  [% content %]<br>
+ <p> [% content %] </p>
+
+=cut
+
+=for layout field
+
+  [% content %] <br>
 
 =cut
diff --git a/share/skin/default/web/componentui-basic.css b/share/skin/default/web/componentui-basic.css
new file mode 100644 (file)
index 0000000..a22dbdf
--- /dev/null
@@ -0,0 +1,146 @@
+html {
+        min-width: 915px;
+} /*IE7*/
+
+body {
+        color: #393733;
+        margin: 0;
+        padding: 0 20px;
+        text-align: center;
+        background: #DDDDDD;
+}
+
+img {
+        border: none;
+}
+
+p {
+        line-height: 1.4;
+}
+
+input{
+        line-height: 1;
+}
+
+#container {
+        text-align: left;
+        margin: 0 auto;
+        max-width: 1200px;
+        position: relative;
+}
+
+#wrapper {
+        padding: 15px 0 0 19px;
+        min-height: 500px;
+} /*IE6*/
+
+#contents {
+        clear: both;
+        padding: 0 15px 30px 0;
+        margin-top: 7px;
+        background: #FFFFFF;
+}
+
+.spacer{ clear: both; }
+.sidebar {
+        float: right;
+        width: 300px;
+        clear: both;
+        margin: 0 0 2em 0;
+        min-height: 500px;
+}
+.sidebar_section {
+        margin: 1em 0 1em 0;
+        min-height: 100px;
+}
+
+.sidebar_section h2{
+        border-bottom: 2px solid #036;
+        padding: 0 1em 0 0em;
+        font-size: 120%;
+        text-align: right;
+}
+
+#header {
+        background: #036;
+        color: #fff;
+        float: left;
+        width: 100%;
+        margin-bottom: 0px;
+        border-bottom: 1px solid white;
+        position: relative;
+        text-align: left;
+}
+
+#header h1 {
+        font-size: 150%;
+        padding: .2em;
+        margin: .2em;
+}
+
+#nav {
+        background: #036;
+        color: #fff;
+        float: left;
+        width: 100%;
+        margin-bottom: 5px;
+        position: relative;
+        text-align: right;
+}
+
+#nav .menu {
+    display: inline
+    width:   75%;
+    float:   left; 
+    margin:  0px;
+    padding: 0px;
+    list-style-type: none;
+    color: #FFFFFF;
+    background: #036
+}
+
+#nav .menu li {
+    display: inline;
+}
+
+#nav .menu li a {
+    float: left;
+    width: 7em;
+    color: #FFFFFF;
+    background:color #036;
+    padding: 0.2em .2em;
+    text-decoration: none;
+    border-right: 1px solid #fff;
+    text-align: center;
+    font-size: 105%;
+    font-weight: bold;
+}
+
+#nav .menu li a:hover {
+    background-color: #369;
+    color: #fff;
+}
+
+#login-status{
+   padding: .2em 1em 0 0;
+   font-size: 80%;
+}
+
+#search{
+        float: right;
+        width: 300;
+        padding: 1em;
+}
+#searchbox{
+        line-height: 1.4;
+        font-size: 90%;
+        border: 2px solid #FFF;
+        padding-left: 3px;
+}
+#searchsub{
+        background-color: #036;
+        font-weight: bold;
+        font-size: 90%;
+        color: white;
+        border: 2px solid #369;
+}
\ No newline at end of file