mirror of
https://github.com/getgrav/grav.git
synced 2025-10-26 07:56:07 +01:00
Supporting negotiated content types
This commit is contained in:
@@ -48,7 +48,8 @@
|
||||
"miljar/php-exif": "^0.6.4",
|
||||
"composer/ca-bundle": "^1.0",
|
||||
"dragonmantank/cron-expression": "^1.2",
|
||||
"phive/twig-extensions-deferred": "^1.0"
|
||||
"phive/twig-extensions-deferred": "^1.0",
|
||||
"willdurand/negotiation": "^2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"codeception/codeception": "^2.4",
|
||||
|
||||
54
composer.lock
generated
54
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "a6592549298919c71cbcd8007b976e85",
|
||||
"content-hash": "0d5507fb2bcbb3cf1cb9c51f8df81397",
|
||||
"packages": [
|
||||
{
|
||||
"name": "antoligy/dom-string-iterators",
|
||||
@@ -2388,6 +2388,58 @@
|
||||
"templating"
|
||||
],
|
||||
"time": "2018-07-13T07:12:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "willdurand/negotiation",
|
||||
"version": "v2.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/willdurand/Negotiation.git",
|
||||
"reference": "03436ededa67c6e83b9b12defac15384cb399dc9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/willdurand/Negotiation/zipball/03436ededa67c6e83b9b12defac15384cb399dc9",
|
||||
"reference": "03436ededa67c6e83b9b12defac15384cb399dc9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Negotiation\\": "src/Negotiation"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "William Durand",
|
||||
"email": "will+git@drnd.me"
|
||||
}
|
||||
],
|
||||
"description": "Content Negotiation tools for PHP provided as a standalone library.",
|
||||
"homepage": "http://williamdurand.fr/Negotiation/",
|
||||
"keywords": [
|
||||
"accept",
|
||||
"content",
|
||||
"format",
|
||||
"header",
|
||||
"negotiation"
|
||||
],
|
||||
"time": "2017-05-14T17:21:12+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
@@ -53,7 +53,7 @@ pages:
|
||||
special_chars: # List of special characters to automatically convert to entities
|
||||
'>': 'gt'
|
||||
'<': 'lt'
|
||||
types: [txt,xml,html,htm,json,rss,atom] # list of valid page types
|
||||
types: [html,htm,json,xml,txt,rss,atom] # list of valid page types
|
||||
append_url_extension: '' # Append page's extension in Page urls (e.g. '.html' results in /path/page.html)
|
||||
expires: 604800 # Page expires time in seconds (604800 seconds = 7 days)
|
||||
cache_control: # Can be blank for no setting, or a valid `cache-control` text value
|
||||
|
||||
@@ -23,6 +23,7 @@ use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Yaml;
|
||||
use Negotiation\Negotiator;
|
||||
use RocketTheme\Toolbox\Event\Event;
|
||||
use RocketTheme\Toolbox\File\MarkdownFile;
|
||||
|
||||
@@ -1287,12 +1288,31 @@ class Page implements PageInterface
|
||||
$this->template_format = $var;
|
||||
}
|
||||
|
||||
// Set from URL extension set on page
|
||||
if (empty($this->template_format)) {
|
||||
$this->template_format = $this->url_extension;
|
||||
}
|
||||
|
||||
// Set from uri extension
|
||||
if (empty($this->template_format)) {
|
||||
$this->template_format = Grav::instance()['uri']->extension('html');
|
||||
$this->template_format = Grav::instance()['uri']->extension();
|
||||
}
|
||||
|
||||
// Use content negotitation via the `accept:` header
|
||||
if (empty($this->template_format) && $accept = $_SERVER['HTTP_ACCEPT'] ?? false) {
|
||||
$negotiator = new Negotiator();
|
||||
|
||||
$supported_types = Grav::instance()['config']->get('system.pages.types', ['html', 'json']);
|
||||
$priorities = Utils::getMimeTypes($supported_types);
|
||||
|
||||
$media_type = $negotiator->getBest($accept, $priorities);
|
||||
$mimetype = $media_type->getValue();
|
||||
$this->template_format = Utils::getExtensionByMime($mimetype);
|
||||
}
|
||||
|
||||
// Last chance set a default type
|
||||
if (empty($this->template_format)) {
|
||||
$this->template_format = 'html';
|
||||
}
|
||||
|
||||
return $this->template_format;
|
||||
|
||||
@@ -478,6 +478,85 @@ abstract class Utils
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the mimetypes for an array of extensions
|
||||
*
|
||||
* @param array $extensions
|
||||
* @return array
|
||||
*/
|
||||
public static function getMimeTypes(array $extensions)
|
||||
{
|
||||
$mimetypes = [];
|
||||
foreach ($extensions as $extension) {
|
||||
$mimetype = static::getMimeByExtension($extension, false);
|
||||
if ($mimetype && !in_array($mimetype, $mimetypes)) {
|
||||
$mimetypes[] = $mimetype;
|
||||
}
|
||||
}
|
||||
return $mimetypes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the mimetype based on filename extension
|
||||
*
|
||||
* @param string $mime mime type (eg "text/html")
|
||||
* @param string $default default value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getExtensionByMime($mime, $default = 'html')
|
||||
{
|
||||
$mime = strtolower($mime);
|
||||
|
||||
// look for some standard mime types
|
||||
switch ($mime) {
|
||||
case '*/*':
|
||||
case 'text/*':
|
||||
case 'text/html':
|
||||
return 'html';
|
||||
case 'application/json':
|
||||
return 'json';
|
||||
case 'application/atom+xml':
|
||||
return 'atom';
|
||||
case 'application/rss+xml':
|
||||
return 'rss';
|
||||
case 'application/xml':
|
||||
return 'xml';
|
||||
}
|
||||
|
||||
$media_types = (array)Grav::instance()['config']->get('media.types');
|
||||
|
||||
foreach ($media_types as $extension => $type) {
|
||||
if ($extension === 'defaults') {
|
||||
continue;
|
||||
}
|
||||
if (isset($type['mime']) && $type['mime'] === $mime) {
|
||||
return $extension;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the extensions for an array of mimetypes
|
||||
*
|
||||
* @param array $mimetypes
|
||||
* @return array
|
||||
*/
|
||||
public static function getExtensions(array $mimetypes)
|
||||
{
|
||||
$extensions = [];
|
||||
foreach ($mimetypes as $mimetype) {
|
||||
$extension = static::getExtensionByMime($mimetype, false);
|
||||
if ($extension && !in_array($extension, $extensions)) {
|
||||
$extensions[] = $extension;
|
||||
}
|
||||
}
|
||||
return $extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype based on filename
|
||||
*
|
||||
@@ -523,47 +602,6 @@ abstract class Utils
|
||||
return $type ?: static::getMimeByFilename($filename, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mimetype based on filename extension
|
||||
*
|
||||
* @param string $mime mime type (eg "text/html")
|
||||
* @param string $default default value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getExtensionByMime($mime, $default = 'html')
|
||||
{
|
||||
$mime = strtolower($mime);
|
||||
|
||||
// look for some standard mime types
|
||||
switch ($mime) {
|
||||
case '*/*':
|
||||
case 'text/*':
|
||||
case 'text/html':
|
||||
return 'html';
|
||||
case 'application/json':
|
||||
return 'json';
|
||||
case 'application/atom+xml':
|
||||
return 'atom';
|
||||
case 'application/rss+xml':
|
||||
return 'rss';
|
||||
case 'application/xml':
|
||||
return 'xml';
|
||||
}
|
||||
|
||||
$media_types = (array)Grav::instance()['config']->get('media.types');
|
||||
|
||||
foreach ($media_types as $extension => $type) {
|
||||
if ($extension === 'defaults') {
|
||||
continue;
|
||||
}
|
||||
if (isset($type['mime']) && $type['mime'] === $mime) {
|
||||
return $extension;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if filename is considered safe.
|
||||
|
||||
Reference in New Issue
Block a user