root of componentUI renders
[catagits/Reaction.git] / lib / Reaction / UI / LayoutSet.pm
CommitLineData
7adfd53f 1package Reaction::UI::LayoutSet;
2
3use Reaction::Class;
4use File::Spec;
5
6class LayoutSet which {
7
f2fef590 8 has 'layouts' => (is => 'ro', default => sub { {} });
7adfd53f 9
10 has 'name' => (is => 'ro', required => 1);
11
12 has 'source_file' => (is => 'rw', lazy_fail => 1);
e22de101 13 has 'file_extension'=> (isa => 'Str', is => 'rw', lazy_build => 1);
14
f2fef590 15 has 'widget_class' => (is => 'rw', lazy_fail => 1);
16
89939ff9 17 implements _build_file_extension => as { 'html' };
7adfd53f 18
19 implements 'BUILD' => as {
20 my ($self, $args) = @_;
21 my @path = @{$args->{search_path}||[]};
22 confess "No search_path provided" unless @path;
23 my $found;
e22de101 24 my $ext = $self->file_extension;
7adfd53f 25 SEARCH: foreach my $path (@path) {
e22de101 26 my $cand = $path->file($self->name . ".${ext}");
27 #print STDERR $cand,"\n";
7adfd53f 28 if ($cand->stat) {
29 $self->_load_file($cand);
30 $found = 1;
31 last SEARCH;
32 }
33 }
34 confess "Unable to load file for LayoutSet ".$self->name unless $found;
f2fef590 35 confess "No view object provided" unless $args->{view};
36 $self->widget_class($args->{view}->widget_class_for($self));
37 };
38
39 implements 'widget_order_for' => as {
40 my ($self, $name) = @_;
41 if ($self->has_layout($name)) {
42 return ([ $self->widget_class, $self ]);
43 } else {
44 return ();
45 }
7adfd53f 46 };
47
f2fef590 48 implements 'layout_names' => as { [ keys %{shift->layouts} ] };
49
50 implements 'has_layout' => as { exists $_[0]->layouts->{$_[1]} };
51
7adfd53f 52 implements '_load_file' => as {
53 my ($self, $file) = @_;
54 my $data = $file->slurp;
f2fef590 55 my $layouts = $self->layouts;
56 # cheesy match for "=for layout name ... =something"
7adfd53f 57 # final split group also handles last in file, (?==) is lookahead
f2fef590 58 # assertion for '=' so "=for layout name1 ... =for layout name2"
59 # doesn't have the match pos go past the latter = and lose name2
7adfd53f 60 while ($data =~ m/=for layout (.*?)\n(.+?)(?:\n(?==)|$)/sg) {
61 my ($fname, $text) = ($1, $2);
f2fef590 62 $layouts->{$fname} = $text;
7adfd53f 63 }
64 $self->source_file($file);
65 };
66
67 implements 'widget_type' => as {
68 my ($self) = @_;
6ab43711 69 my $widget = join('', map { ucfirst($_) } split('_', $self->name));
70 $widget = join('::', map { ucfirst($_) } split('/', $widget));
71
e22de101 72 #print STDERR "--- ", $self->name, " maps to widget $widget \n";
6ab43711 73
74 return $widget;
7adfd53f 75 };
7b78a39d 76
7adfd53f 77};
78
791;