removed view arg to LayoutSet, moved to using skin to resolve widget class, added...
[catagits/Reaction.git] / lib / Reaction / UI / Skin.pm
CommitLineData
8a293e2e 1package Reaction::UI::Skin;
2
3use Reaction::Class;
4
5# declaring dependencies
6use Reaction::UI::LayoutSet;
7use Reaction::UI::RenderingContext;
8
9use aliased 'Path::Class::Dir';
10
11class Skin which {
12
13 has '_layout_set_cache' => (is => 'ro', default => sub { {} });
14
15 has 'skin_base_path' => (is => 'ro', isa => Dir, required => 1);
16
349a57a4 17 has 'widget_search_path' => (is => 'rw', isa => 'ArrayRef', lazy_fail => 1);
18
8a293e2e 19 has 'view' => (
20 is => 'ro', required => 1, weak_ref => 1,
f6b79841 21 handles => [ qw(layout_set_class widget_class_for) ],
8a293e2e 22 );
23
24 has 'super' => (
25 is => 'rw', isa => Skin, required => 0, predicate => 'has_super',
26 );
27
28 sub BUILD {
29 my ($self) = @_;
30 $self->_load_skin_config;
31 }
32
33 implements '_load_skin_config' => as {
34 my ($self) = @_;
35 my $base = $self->skin_base_path;
36 confess "No such skin base directory ${base}"
37 unless -d $base;
349a57a4 38 my $lst = sub { (ref $_[0] eq 'ARRAY') ? $_[0]: [$_[0]] };
39 my @files = (
40 $base->parent->file('defaults.conf'), $base->file('skin.conf')
41 );
42 # we get [ { $file => $conf }, ... ]
43 my %cfg = (map { %{(values %{$_})[0]} }
44 @{Config::Any->load_files({
45 files => [ grep { -e $_ } @files ],
46 use_ext => 1,
47 })}
48 );
49 if (my $super_name = $cfg{extends}) {
50 my $super_dir = $base->parent->subdir($super_name);
51 my $super = $self->new(
52 view => $self->view, skin_base_path => $super_dir
53 );
54 $self->super($super);
55 }
56 if (exists $cfg{widget_search_path}) {
57 $self->widget_search_path($lst->($cfg{widget_search_path}));
58 } else {
59 confess "No widget_search_path in defaults.conf or skin.conf";
7c2bcb55 60 }
8a293e2e 61 }
62
63 implements 'create_layout_set' => as {
64 my ($self, $name) = @_;
65 if (my $path = $self->layout_path_for($name)) {
66 return $self->layout_set_class->new(
67 $self->layout_set_args_for($name),
68 source_file => $path,
69 );
70 }
71 if ($self->has_super) {
72 return $self->super->create_layout_set($name);
73 }
74 confess "Couldn't find layout set file for ${name}";
75 };
76
77 implements 'layout_set_args_for' => as {
78 my ($self, $name) = @_;
79 return (
80 name => $name,
8a293e2e 81 skin => $self,
82 ($self->has_super ? (next_skin => $self->super) : ()),
83 $self->view->layout_set_args_for($name),
84 );
85 };
86
87 implements 'layout_path_for' => as {
88 my ($self, $layout) = @_;
89 my $file_name = join(
349a57a4 90 '.', $layout, $self->view->layout_set_file_extension
8a293e2e 91 );
92 my $path = $self->our_path_for_type('layout')
93 ->file($file_name);
94 return (-e $path ? $path : undef);
95 };
96
97 implements 'search_path_for_type' => as {
98 my ($self, $type) = @_;
99 return [
100 $self->our_path_for_type($type),
101 ($self->has_super
102 ? @{$self->super->search_path_for_type($type)}
103 : ()
104 )
105 ];
106 };
107
108 implements 'our_path_for_type' => as {
109 my ($self, $type) = @_;
110 return $self->skin_base_path->subdir($type)
111 };
112
113};
114
1151;