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