File Coverage

blib/lib/Dancer2/Plugin/Negotiate.pm
Criterion Covered Total %
statement 48 50 96.0
branch 18 26 69.2
condition 4 7 57.1
subroutine 9 10 90.0
pod n/a
total 79 93 84.9


line stmt bran cond sub pod time code
1 3     3   1476764 use strict;
  3         7  
  3         134  
2 3     3   15 use warnings;
  3         5  
  3         126  
3              
4             package Dancer2::Plugin::Negotiate;
5              
6             # ABSTRACT: Content negotiation plugin for Dancer2
7              
8 3     3   1449 use Dancer2::Plugin;
  3         6801  
  3         19  
9              
10 3     3   7814 use HTTP::Negotiate;
  3         87  
  3         1773  
11              
12             our $VERSION = '0.001'; # VERSION
13              
14             sub choose_variant {
15 7     7   101816 my $dsl = shift;
16 7         23 my $app = $dsl->app;
17 7         15 my $variants = [];
18 7         34 while ( my ( $variant, $options ) = ( shift, shift ) ) {
19 24 100 66     97 last unless defined $variant and defined $options;
20 17         89 push @$variants => [
21             $variant, $options->{Quality}, $options->{Type},
22             $options->{Encoding}, $options->{Charset}, $options->{Language},
23             $options->{Size}
24             ];
25             }
26 7         47 HTTP::Negotiate::choose( $variants, $app->request->headers, );
27             }
28              
29             sub apply_variant {
30 5     5   91106 my ( $dsl, %variants ) = @_;
31 5         16 my $app = $dsl->app;
32 5         19 my $variant = scalar choose_variant(@_);
33 5 50       1170 return unless defined $variant;
34 5         8 my %options = %{ $variants{$variant} };
  5         22  
35 5         119 my $R = $app->response;
36 5 100       51 $R->header( 'Content-Type' => $options{Type} ) if defined $options{Type};
37 5 50       1200 $R->header( 'Content-Encoding' => $options{Encoding} )
38             if defined $options{Encoding};
39 5 100       20 $R->header( 'Content-Charset' => $options{Charset} )
40             if defined $options{Charset};
41 5 100       193 $R->header( 'Content-Language' => $options{Language} )
42             if defined $options{Language};
43 5         496 $variant;
44             }
45              
46             sub _langmap {
47 0   50 0   0 my $grep = shift || sub { 1 };
  3     3   12  
48 3   50     13 my $langs = plugin_setting->{languages} || {};
49 6 50       33 return grep defined, map {
    50          
50 3         465 my $opt = {
51             Language => scalar( ref $_ eq 'HASH' ? ( keys %$_ )[0] : $_ ),
52             Quality => scalar( ref $_ eq 'HASH' ? ( values %$_ )[0] : 1 )
53             };
54 6         11 my $id = lc $opt->{Language};
55 6 50       11 $grep->($opt) ? ( $id => $opt ) : undef;
56             } @$langs;
57             }
58              
59             sub negotiate {
60 3     3   109776 my ( $dsl, $tplname, @rest ) = @_;
61 3         8 my $app = $dsl->app;
62 3         12 my $engine = $app->engine('template');
63             my @langmap = _langmap(
64             sub {
65 6     6   10 my $lang = shift->{Language};
66 6         28 my $view = $engine->view_pathname( $tplname . '.' . $lang );
67 6 50       1091 defined $view and -e $view ? 1 : 0;
    50          
68             }
69 3         127 );
70 3         24 my $lang = apply_variant( $dsl, 0, {}, @langmap );
71 3 100       10 $tplname .= '.' . $lang if $lang;
72 3 50       7 if (wantarray) {
73 3         18 return ( $tplname, @rest );
74             }
75             else {
76 0           return $tplname;
77             }
78             }
79              
80             register
81             choose_variant => \&choose_variant,
82             { is_global => 0 };
83             register
84             apply_variant => \&apply_variant,
85             { is_global => 0 };
86             register
87             negotiate => \&negotiate,
88             { is_global => 0 };
89              
90             register_plugin;
91              
92             1;
93              
94             __END__