Commit | Line | Data |
7adfd53f |
1 | package Reaction::UI::Renderer::XHTML; |
2 | |
3 | use strict; |
4 | use base qw/Catalyst::View::TT Reaction::Object/; |
5 | use Reaction::Class; |
6 | |
7 | use HTML::Entities; |
8 | |
9 | __PACKAGE__->config({ |
10 | CATALYST_VAR => 'ctx', |
11 | RECURSION => 1, |
12 | }); |
13 | |
14 | sub render_window { |
15 | my ($self, $window) = @_; |
16 | my $root_vp = $window->focus_stack->vp_head; |
17 | confess "Can't flush view for window with empty focus stack" |
18 | unless defined($root_vp); |
19 | $self->render_viewport($window, $root_vp); |
20 | } |
21 | |
22 | sub render_viewport { |
23 | my ($self, $window, $vp) = @_; |
24 | my $ctx = $window->ctx; |
25 | my %args = ( |
26 | self => $vp, |
27 | ctx => $ctx, |
28 | window => $window, |
29 | type => $vp->layout |
30 | ); |
31 | unless (length $args{type}) { |
32 | my $type = (split('::', ref($vp)))[-1]; |
33 | $args{type} = lc($type); |
34 | } |
35 | return $self->render($ctx, 'component', \%args); |
36 | } |
37 | |
38 | around 'render' => sub { |
39 | my $super = shift; |
40 | my ($self,$args) = @_[0,3]; |
41 | local $self->template->{SERVICE}{CONTEXT}{BLKSTACK}; |
42 | local $self->template->{SERVICE}{CONTEXT}{BLOCKS}; |
43 | $args->{process_attrs} = \&process_attrs; |
44 | return $super->(@_); |
45 | }; |
46 | |
47 | sub process_attrs{ |
48 | my $attrs = shift; |
49 | return $attrs unless ref $attrs eq 'HASH'; |
50 | |
51 | my @processed_attrs; |
52 | while( my($k,$v) = each(%$attrs) ){ |
53 | my $enc_v = $v; |
54 | next if ($enc_v eq ""); |
55 | if ($k eq 'class' && ref $v eq 'ARRAY'){ |
56 | $enc_v = join ' ', map { encode_entities($_) } @$v; |
57 | } elsif ($k eq 'style' && ref $v eq 'HASH'){ |
58 | $enc_v = join '; ', map{ "${_}: ".encode_entities($v->{$_}) } keys %{$v}; |
59 | } |
60 | push(@processed_attrs, "${k}=\"${enc_v}\""); |
61 | } |
62 | |
63 | return ' '.join ' ', @processed_attrs if (scalar(@processed_attrs) > 0); |
64 | return; |
65 | } |
66 | |
67 | 1; |
68 | |
69 | =head1 NAME |
70 | |
71 | Reaction::UI::Renderer::XHTML |
72 | |
73 | =head1 DESCRIPTION |
74 | |
75 | =head1 METHODS |
76 | |
77 | =head2 render |
78 | |
79 | =head2 process_attrs |
80 | |
81 | =head1 AUTHORS |
82 | |
83 | See L<Reaction::Class> for authors. |
84 | |
85 | =head1 LICENSE |
86 | |
87 | See L<Reaction::Class> for the license. |
88 | |
89 | =cut |