NAME
   CatalystX::Action::Negotiate - ActionRole for content negotiation

VERSION
   Version 0.04

SYNOPSIS
       sub default :Path :Does('+CatalystX::Action::Negotiate') {
           my ($self, $c) = @_;

           # obtain variants (if you care)
           my @variants = @{$c->stash->{variants}};

           # maybe manipulate them? i dunno

           # set them back, or set entirely new ones
           $c->stash->{variants} = \@variants;

           # action role negotiates variants and returns the winner
       }

DESCRIPTION
   This module serves content-negotiated static content from the document
   root. It also affords mixing dynamic variants in with static variants,
   the list of which is passed directly into the "choose" in
   HTTP::Negotiate function. The winning variant is chosen from the various
   "Accept-*" request headers.

   As with Apache and other Web servers, dimensions for static variants are
   derived from file extensions. Currently the only supported dimension is
   MIME content type.

   There is a slight difference in the behaviour between this module and
   Apache: whereas there is one or more files of the form "foo.*" alongside
   a directory called "foo" containing one or more files with the slug
   "index", these will all be lumped into the set of variants. The
   customary trailing slash, however, will only be applied in the case that
   a "foo/index.*" file is chosen over a "foo.*" file. This is different
   from Apache in that the latter ignores "foo.*" files if there is also a
   directory present called "foo". The purpose of this change is to provide
   an easy way to style URIs *without* the trailing slash while still
   providing for descendants along the same URI path.

   Interacting with the action in a handler goes as follows:

   1.  The action runs and first attempts to collect any eligible static
       variants found by concatenating the request-URI to the document
       root. It puts what it finds in "$c->stash->{variants}". To indicate
       the indeterminate state of the response to the caller, the status is
       initially set to 404.

   2.  The action runs the calling handler, offering it an opportunity to
       manipulate the variant list or intercede in the response.

   3.  If the handler has not changed the response code to a value below
       400, the action proceeds to select a variant and set the appropriate
       headers.

   4.  The action performs a trailing-slash check to match the request-URI
       to the internal representation, redirecting if necessary with a code
       301.

   5.  An "If-Modified-Since" check is performed, which will return 304 if
       the client already has the latest version of the document.

   6.  If the action has not terminated the response by now, it sets the
       response body to the variant and the status to 200. If you need to,
       you can still manipulate it in a subsequent (e.g. "end") handler.

   The calling controller action is sandwiched between the
   variant-generating operation and the variant-selecting operation. It is
   placed as an "ARRAY" reference for your convenience in
   "$c->stash->{variants}". This structure is exactly the same as that
   which is passed into HTTP::Negotiate, save for these exceptions:

   1.  Variants do not need to be a string identifier, but in fact can be
       anything that can be consumed by a view or middleware component,
       e.g., a file handle or any other kind of supported object.

   2.  Path::Class::File objects get special treatment, as they are what
       the initial static variant list is made out of.

   3.  Append an additional integer to the end of a variant's record to
       supply an artificial "Last-Modified" value as a UNIX time stamp.

   Otherwise, consult HTTP::Negotiate for how to construct the records.
   This modification enables you to mix static variants in with dynamic
   ones, or overwrite the list with purely dynamic variants.

   Note that this module may conflict with
   Catalyst::Plugin::Static::Simple. In future releases I will attempt to
   bring this module up to par so that it can be a viable replacement, or
   at the very least be a better cohabitant.

SEE ALSO
   *   Catalyst::Action

   *   HTTP::Negotiate

   *   Role::MimeInfo

AUTHOR
   Dorian Taylor, "<dorian at cpan.org>"

BUGS
   Please report bugs on GitHub
   <https://github.com/doriantaylor/p5-catalystx-action-negotiate/issues>.

SUPPORT
   You can find documentation for this module with the perldoc command.

       perldoc CatalystX::Action::Negotiate

   You can also look for information at:

   *   MetaCPAN

       <http://metacpan.org/release/CatalystX-Action-Negotiate/>

   *   The source

       <https://github.com/doriantaylor/p5-catalystx-action-negotiate>

LICENSE AND COPYRIGHT
   Copyright 2019 Dorian Taylor.

   Licensed under the Apache License, Version 2.0 (the "License"); you may
   not use this file except in compliance with the License. You may obtain
   a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>.

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

POD ERRORS
   Hey! The above document had some coding errors, which are explained
   below:

   Around line 137:
       Unknown directive: =head