1 package Reaction::UI::LayoutSet;
6 class LayoutSet which {
8 has 'layouts' => (is => 'ro', default => sub { {} });
10 has 'name' => (is => 'ro', required => 1);
12 has 'source_file' => (is => 'rw', lazy_fail => 1);
13 has 'file_extension'=> (isa => 'Str', is => 'rw', lazy_build => 1);
15 has 'widget_class' => (
16 is => 'rw', lazy_fail => 1, predicate => 'has_widget_class'
19 has 'super' => (is => 'rw', predicate => 'has_super');
21 implements _build_file_extension => as { 'html' };
23 implements 'BUILD' => as {
24 my ($self, $args) = @_;
25 my @path = @{$args->{search_path}||[]};
26 confess "No search_path provided" unless @path;
27 confess "No view object provided" unless $args->{view};
29 my $ext = $self->file_extension;
30 SEARCH: foreach my $path (@path) {
31 my $cand = $path->file($self->name . ".${ext}");
32 #print STDERR $cand,"\n";
34 $self->_load_file($cand, $args);
39 confess "Unable to load file for LayoutSet ".$self->name unless $found;
40 unless ($self->has_widget_class) {
41 $self->widget_class($args->{view}->widget_class_for($self));
45 implements 'widget_order_for' => as {
46 my ($self, $name) = @_;
48 ($self->has_layout($name)
49 ? ([ $self->widget_class, $self ]) #;
52 ? ($self->super->widget_order_for($name))
57 implements 'layout_names' => as {
62 keys %{shift->layouts},
64 ? (@{$self->super->layout_names})
69 implements 'has_layout' => as { exists $_[0]->layouts->{$_[1]} };
71 implements '_load_file' => as {
72 my ($self, $file, $build_args) = @_;
73 my $data = $file->slurp;
74 my $layouts = $self->layouts;
75 # cheesy match for "=for layout name ... =something"
76 # final split group also handles last in file, (?==) is lookahead
77 # assertion for '=' so "=for layout name1 ... =for layout name2"
78 # doesn't have the match pos go past the latter = and lose name2
79 while ($data =~ m/=(.*?)\n(.*?)(?:\n(?==)|$)/sg) {
80 my ($data, $text) = ($1, $2);
81 if ($data =~ /^for layout (\S+)/) {
83 $layouts->{$fname} = $text;
84 } elsif ($data =~ /^extends (\S+)/) {
86 $self->super($build_args->{view}->create_layout_set($super_name))
87 } elsif ($data =~ /^cut/) {
90 confess "Unparseable directive ${data}";
93 $self->source_file($file);
96 implements 'widget_type' => as {
98 my $widget = join('', map { ucfirst($_) } split('_', $self->name));
99 $widget = join('::', map { ucfirst($_) } split('/', $widget));
101 #print STDERR "--- ", $self->name, " maps to widget $widget \n";