Examples:
embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(1-2)
embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(19-23)
embed:lithium\tests\cases\net\http\MediaTest::testMediaTypes(43-44)
Alternatively, can be used to detect the type name of a registered content type:
Media::type('application/json'); // returns 'json'
Media::type('application/javascript'); // returns 'javascript'
Media::type('text/javascript'); // also returns 'javascript'
Media::type('text/html'); // returns 'html'
Media::type('application/xhtml+xml'); // also returns 'html'
#### Content negotiation
When creating custom media types, specifying which content-type(s) to match isn't always
enough. For example, if you wish to serve a different set of templates to mobile web
browsers, you'd still want those templates served as HTML. You might add something like this:
Media::type('mobile', array('application/xhtml+xml', 'text/html'));
However, this would cause _all_ requests for HTML content to be interpreted as
'mobile'-type requests. Instead, we can use _content negotiation_ to granularly specify how
to match a particular type. Content negotiation is the process of examining the HTTP headers
provided in the request (including the content-types listed in the
Accept header, and
optionally other things as well, like the
Accept-Language or
User-Agent headers), in
order to produce the best representation of the requested resource for the client; in other
words, the resource that most closely matches what the client is asking for.
Content negotiation with media types is made possible through the
'conditions' key of the
$options parameter, which contains an array of assertions made against the
Request
object. Each assertion (array key) can be one of three different things:
-
'type' _boolean_: In the default routing, some routes have
{:type} keys, which are
designed to match file extensions in URLs. These values act as overrides for the
HTTP
Accept header, allowing different formats to be served with the same content
type. For example, if you're serving JSONP, you'll want to serve it with the same
content-type as JavaScript (since it is JavaScript), but you probably won't want to
use the same template(s) or other settings. Therefore, when serving JSONP content, you
can specify that the extension defined in the type must be present in the URL:
Media::type('jsonp', array('application/json'), array(
template settings...
'conditions' => array('type' => true)
));
Then, JSONP content will only ever be served when the request URL ends in
.jsonp.
-
':' _string_: This type of assertion can be used to match against arbitrary
information in the request, including headers (i.e.
'http:user_agent'), environment
variables (i.e.
'env:home'), GET and POST data (i.e.
'query:foo' or
'data:foo',
respectively), and the HTTP method (
'http:method') of the request. For more information
on possible keys, see
lithium\action\Request::get().
-
'' _boolean_: Uses detector checks added to the
Request object to make
boolean assertions against the request. For example, if a detector called
'iPhone' is
attached, you can add
'iPhone' => true to the
'conditions' array in order to filter for
iPhone requests only. See
lithium\action\Request::detect() for more information on adding
detectors.