aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Reaction/UI/LayoutSet.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Reaction/UI/LayoutSet.pm')
-rw-r--r--lib/Reaction/UI/LayoutSet.pm58
1 files changed, 44 insertions, 14 deletions
diff --git a/lib/Reaction/UI/LayoutSet.pm b/lib/Reaction/UI/LayoutSet.pm
index 68d23d1..4a9c533 100644
--- a/lib/Reaction/UI/LayoutSet.pm
+++ b/lib/Reaction/UI/LayoutSet.pm
@@ -12,7 +12,11 @@ class LayoutSet which {
has 'source_file' => (is => 'rw', lazy_fail => 1);
has 'file_extension'=> (isa => 'Str', is => 'rw', lazy_build => 1);
- has 'widget_class' => (is => 'rw', lazy_fail => 1);
+ has 'widget_class' => (
+ is => 'rw', lazy_fail => 1, predicate => 'has_widget_class'
+ );
+
+ has 'super' => (is => 'rw', predicate => 'has_super');
implements _build_file_extension => as { 'html' };
@@ -20,46 +24,72 @@ class LayoutSet which {
my ($self, $args) = @_;
my @path = @{$args->{search_path}||[]};
confess "No search_path provided" unless @path;
+ confess "No view object provided" unless $args->{view};
my $found;
my $ext = $self->file_extension;
SEARCH: foreach my $path (@path) {
my $cand = $path->file($self->name . ".${ext}");
#print STDERR $cand,"\n";
if ($cand->stat) {
- $self->_load_file($cand);
+ $self->_load_file($cand, $args);
$found = 1;
last SEARCH;
}
}
confess "Unable to load file for LayoutSet ".$self->name unless $found;
- confess "No view object provided" unless $args->{view};
- $self->widget_class($args->{view}->widget_class_for($self));
+ unless ($self->has_widget_class) {
+ $self->widget_class($args->{view}->widget_class_for($self));
+ }
};
implements 'widget_order_for' => as {
my ($self, $name) = @_;
- if ($self->has_layout($name)) {
- return ([ $self->widget_class, $self ]);
- } else {
- return ();
- }
+ return (
+ ($self->has_layout($name)
+ ? ([ $self->widget_class, $self ]) #;
+ : ()),
+ ($self->has_super
+ ? ($self->super->widget_order_for($name))
+ : ()),
+ );
};
- implements 'layout_names' => as { [ keys %{shift->layouts} ] };
+ implements 'layout_names' => as {
+ my ($self) = @_;
+ my %seen;
+ return [
+ grep { !$seen{$_}++ }
+ keys %{shift->layouts},
+ ($self->has_super
+ ? (@{$self->super->layout_names})
+ : ())
+ ];
+ };
implements 'has_layout' => as { exists $_[0]->layouts->{$_[1]} };
implements '_load_file' => as {
- my ($self, $file) = @_;
+ my ($self, $file, $build_args) = @_;
my $data = $file->slurp;
my $layouts = $self->layouts;
# cheesy match for "=for layout name ... =something"
# final split group also handles last in file, (?==) is lookahead
# assertion for '=' so "=for layout name1 ... =for layout name2"
# doesn't have the match pos go past the latter = and lose name2
- while ($data =~ m/=for layout (.*?)\n(.+?)(?:\n(?==)|$)/sg) {
- my ($fname, $text) = ($1, $2);
- $layouts->{$fname} = $text;
+ while ($data =~ m/=(.*?)\n(.*?)(?:\n(?==)|$)/sg) {
+ my ($data, $text) = ($1, $2);
+
+ if ($data =~ /^for layout (\S+)/) {
+ my $fname = $1;
+ $layouts->{$fname} = $text;
+ } elsif ($data =~ /^extends (\S+)/) {
+ my $super_name = $1;
+ $self->super($build_args->{view}->create_layout_set($super_name))
+ } elsif ($data =~ /^cut/) {
+ # no-op
+ } else {
+ confess "Unparseable directive ${data}";
+ }
}
$self->source_file($file);
};