Checking in changes prior to tagging of version 1.004. Changelog diff is:
[catagits/Catalyst-View-ContentNegotiation-XHTML.git] / lib / Catalyst / View / TT / XHTML.pm
CommitLineData
0f9bcf09 1package Catalyst::View::TT::XHTML;
2use strict;
3use warnings;
06cf3efb 4use HTTP::Negotiate qw(choose);
d58e822e 5use MRO::Compat;
0f9bcf09 6use base qw/Catalyst::View::TT/;
7
b612c798 8our $VERSION = '1.004';
06cf3efb 9
10our $variants = [
11 [qw| xhtml 1.000 application/xhtml+xml |],
56f18daf 12 [qw| html 0.900 text/html |],
06cf3efb 13];
0f9bcf09 14
15sub process {
16 my $self = shift;
17 my ($c) = @_;
06cf3efb 18 my $return = $self->next::method(@_);
06cf3efb 19 if ($c->request->header('Accept') && $c->response->headers->{'content-type'} =~ m|text/html|) {
56f18daf 20 $self->pragmatic_accept($c);
06cf3efb 21 my $var = choose($variants, $c->request->headers);
22 if ($var eq 'xhtml') {
23 $c->response->headers->{'content-type'} =~ s|text/html|application/xhtml+xml|;
24 }
0f9bcf09 25 }
06cf3efb 26 return $return;
0f9bcf09 27}
28
56f18daf 29sub pragmatic_accept {
30 my ($self, $c) = @_;
31 my $accept = $c->request->header('Accept');
32 if ($accept =~ m|text/html|) {
33 $accept =~ s!\*/\*\s*([,]+|$)!*/*;q=0.5$1!;
34 } else {
35 $accept =~ s!\*/\*\s*([,]+|$)!text/html,*/*;q=0.5$1!;
36 }
37 $c->request->header('Accept' => $accept);
38}
39
0f9bcf09 401;
41
42__END__
43
44=head1 NAME
45
46Catalyst::View::TT::XHTML - A sub-class of the standard TT view which
47serves application/xhtml+xml content if the browser accepts it.
48
49=head1 SYNOPSIS
50
51 package MyApp::View::XHTML;
52 use strict;
53 use warnings;
54 use base qw/Catalyst::View::TT::XHTML MyApp::View::TT/;
56f18daf 55
0f9bcf09 56 1;
56f18daf 57
0f9bcf09 58=head1 DESCRIPTION
59
60This is a very simple sub-class of L<Catalyst::View::TT>, which sets
61the response C<Content-Type> to be C<application/xhtml+xml> if the
62user's browser sends an C<Accept> header indicating that it is willing
63to process that MIME type.
64
65Changing the C<Content-Type> causes browsers to interpret the page as
56f18daf 66XML, meaning that the markup must be well formed.
0f9bcf09 67
68This is useful when you're developing your application, as you know that
56f18daf 69all pages you view are parsed as XML, so any errors caused by your markup
70not being well-formed will show up at once.
0f9bcf09 71
72=head1 METHODS
73
74=head2 process
75
76Overrides the standard process method, delegating to L<Catalyst::View::TT>
77to render the template, and then changing the response C<Content-Type> if
78appropriate (from the requests C<Accept> header).
79
56f18daf 80=head2 pragmatic_accept
81
82Some browsers (such as Internet Explorer) have a nasty way of sending
83Accept */* and this claiming to support XHTML just as well as HTML.
84Saving to a file on disk or opening with another application does
85count as accepting, but it really should have a lower q value then
86text/html. This sub takes a pragmatic approach and corrects this mistake
87by modifying the Accept header before passing it to content negotiation.
88
0f9bcf09 89=head1 BUGS
90
91There should be a more elegant way to inherit the config of your normal
92TT view.
93
94Configuration (as loaded by L<Catalyst::Plugin::ConfigLoader>) for the TT
95view is not used.
96
97No helper to generate the view file needed (just copy the code in the
98SYNOPSIS).
99
100=head1 AUTHOR
101
102Tomas Doran C<< <bobtfish@bobtfish.net> >>
103
c2ec1d6a 104=head1 CONTRIBUTORS
105
106=over
107
56f18daf 108=item David Dorward - test patches and */* pragmatism.
c2ec1d6a 109
110=back
111
0f9bcf09 112=head1 COPYRIGHT
113
114This module itself is copyright (c) 2008 Tomas Doran and is licensed under the same terms as Perl itself.
115
116=cut