1 package Reaction::UI::Skin;
5 # declaring dependencies
6 use Reaction::UI::LayoutSet;
7 use Reaction::UI::RenderingContext;
9 use aliased 'Path::Class::Dir';
13 has '_layout_set_cache' => (is => 'ro', default => sub { {} });
15 has 'skin_base_path' => (is => 'ro', isa => Dir, required => 1);
17 has 'widget_search_path' => (is => 'rw', isa => 'ArrayRef', lazy_fail => 1);
20 is => 'ro', required => 1, weak_ref => 1,
21 handles => [ qw(layout_set_class widget_class_for) ],
25 is => 'rw', isa => Skin, required => 0, predicate => 'has_super',
30 $self->_load_skin_config;
33 implements '_load_skin_config' => as {
35 my $base = $self->skin_base_path;
36 confess "No such skin base directory ${base}"
38 my $lst = sub { (ref $_[0] eq 'ARRAY') ? $_[0]: [$_[0]] };
40 $base->parent->file('defaults.conf'), $base->file('skin.conf')
42 # we get [ { $file => $conf }, ... ]
43 my %cfg = (map { %{(values %{$_})[0]} }
44 @{Config::Any->load_files({
45 files => [ grep { -e $_ } @files ],
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
56 if (exists $cfg{widget_search_path}) {
57 $self->widget_search_path($lst->($cfg{widget_search_path}));
59 confess "No widget_search_path in defaults.conf or skin.conf";
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),
71 if ($self->has_super) {
72 return $self->super->create_layout_set($name);
74 confess "Couldn't find layout set file for ${name}";
77 implements 'layout_set_args_for' => as {
78 my ($self, $name) = @_;
82 ($self->has_super ? (next_skin => $self->super) : ()),
83 $self->view->layout_set_args_for($name),
87 implements 'layout_path_for' => as {
88 my ($self, $layout) = @_;
90 '.', $layout, $self->view->layout_set_file_extension
92 my $path = $self->our_path_for_type('layout')
94 return (-e $path ? $path : undef);
97 implements 'search_path_for_type' => as {
98 my ($self, $type) = @_;
100 $self->our_path_for_type($type),
102 ? @{$self->super->search_path_for_type($type)}
108 implements 'our_path_for_type' => as {
109 my ($self, $type) = @_;
110 return $self->skin_base_path->subdir($type)