1
0
mirror of https://github.com/typemill/typemill.git synced 2025-10-17 23:56:09 +02:00

TOC-feature and improved character encoding for file names

This commit is contained in:
Sebastian
2017-11-29 22:56:54 +01:00
parent 17767b754a
commit cd240bfaed
23 changed files with 458 additions and 249 deletions

View File

@@ -9,12 +9,12 @@ use Typemill\Models\WriteYaml;
use \Symfony\Component\Yaml\Yaml;
use Typemill\Models\VersionCheck;
use Typemill\Models\Helpers;
use Typemill\Extensions\ParsedownExtension;
class PageController extends Controller
{
public function index($request, $response, $args)
{
/* Initiate Variables */
$structure = false;
$contentHTML = false;
@@ -75,12 +75,18 @@ class PageController extends Controller
/* find the url in the content-item-tree and return the item-object for the file */
$item = Folder::getItemForUrl($structure, $urlRel);
/*
if(!$item && $cached)
{
$structure = $this->getFreshStructure($pathToContent, $cache, $uri);
$item = Folder::getItemForUrl($structure, $urlRel);
}
if(!$item){ return $this->render404($response, array( 'navigation' => $structure, 'settings' => $settings, 'base_url' => $base_url )); }
*/
if(!$item)
{
return $this->render404($response, array( 'navigation' => $structure, 'settings' => $settings, 'base_url' => $base_url ));
}
/* get breadcrumb for page */
$breadcrumb = Folder::getBreadcrumb($structure, $item->keyPathArray);
@@ -103,7 +109,7 @@ class PageController extends Controller
}
/* initialize parsedown */
$Parsedown = new \ParsedownExtra();
$Parsedown = new ParsedownExtension();
/* parse markdown-file to html-string */
$contentHTML = $Parsedown->text($contentMD);

View File

@@ -0,0 +1,149 @@
<?php
namespace Typemill\Extensions;
class ParsedownExtension extends \ParsedownExtra
{
function __construct()
{
parent::__construct();
array_unshift($this->BlockTypes['['], 'TableOfContents');
}
function text($text)
{
# make sure no definitions are set
$this->DefinitionData = array();
# standardize line breaks
$text = str_replace(array("\r\n", "\r"), "\n", $text);
# remove surrounding line breaks
$text = trim($text, "\n");
# split text into lines
$lines = explode("\n", $text);
# iterate through lines to identify blocks
$markup = $this->lines($lines);
# trim line breaks
$markup = trim($markup, "\n");
if (isset($this->DefinitionData['TableOfContents']))
{
$TOC = $this->buildTOC($this->headlines);
$markup = preg_replace('%(<p[^>]*>\[TOC\]</p>)%i', $TOC, $markup);
}
# merge consecutive dl elements
$markup = preg_replace('/<\/dl>\s+<dl>\s+/', '', $markup);
# add footnotes
if (isset($this->DefinitionData['Footnote']))
{
$Element = $this->buildFootnoteElement();
$markup .= "\n" . $this->element($Element);
}
return $markup;
}
# TableOfContents
protected function blockTableOfContents($line, $block)
{
if ($line['text'] == '[TOC]')
{
$this->DefinitionData['TableOfContents'] = true;
}
}
#
# Header
private $headlines = array();
private $headlinesCount = 0;
protected function blockHeader($Line)
{
if (isset($Line['text'][1]))
{
$level = 1;
while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
{
$level ++;
}
if ($level > 6)
{
return;
}
$text = trim($Line['text'], '# ');
$this->headlinesCount++;
$Block = array(
'element' => array(
'name' => 'h' . min(6, $level),
'text' => $text,
'handler' => 'line',
'attributes' => array(
'id' => "headline-$this->headlinesCount"
)
)
);
$this->headlines[] = array('level' => $level, 'name' => $Block['element']['name'], 'attribute' => $Block['element']['attributes']['id'], 'text' => $text);
return $Block;
}
}
# build the markup for table of contents
protected function buildTOC($headlines)
{
$markup = '<ul class="TOC">';
foreach($headlines as $key => $headline)
{
$thisLevel = $headline['level'];
$prevLevel = $key > 0 ? $headlines[$key-1]['level'] : 1;
$nextLevel = isset($headlines[$key+1]) ? $headlines[$key+1]['level'] : 0;
if($thisLevel > $prevLevel)
{
$markup .= '<ul>';
}
$markup .= '<li class="' . $headline['name'] . '"><a href="#' . $headline['attribute'] . '">' . $headline['text'] . '</a>';
if($thisLevel == $nextLevel)
{
$markup .= '</li>';
}
elseif($thisLevel > $nextLevel)
{
while($thisLevel > $nextLevel)
{
$markup .= '</li></ul>';
$thisLevel--;
}
}
}
$markup .= '</ul>';
return $markup;
}
}

View File

@@ -59,9 +59,9 @@ class Folder
$item->index = array_search('index.md', $name) === false ? false : true;
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
$item->name = implode(" ",$nameParts);
$item->name = iconv('ISO-8859-15', 'UTF-8', $item->name);
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
$item->slug = implode("-",$nameParts);
$item->slug = URLify::filter(iconv('ISO-8859-15', 'UTF-8', $item->slug));
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
$item->path = $fullPath . DIRECTORY_SEPARATOR . $key;
$item->urlRelWoF = $fullSlugWithoutFolder . '/' . $item->slug;
$item->urlRel = $fullSlugWithFolder . '/' . $item->slug;
@@ -85,9 +85,9 @@ class Folder
$item->fileType = $fileType;
$item->order = count($nameParts) > 1 ? array_shift($nameParts) : NULL;
$item->name = implode(" ",$nameParts);
$item->name = iconv('ISO-8859-15', 'UTF-8', $item->name);
$item->name = iconv(mb_detect_encoding($item->name, mb_detect_order(), true), "UTF-8", $item->name);
$item->slug = implode("-",$nameParts);
$item->slug = URLify::filter(iconv('ISO-8859-15', 'UTF-8', $item->slug));
$item->slug = URLify::filter(iconv(mb_detect_encoding($item->slug, mb_detect_order(), true), "UTF-8", $item->slug));
$item->path = $fullPath . DIRECTORY_SEPARATOR . $name;
$item->key = $iteration;
$item->keyPath = $keyPath . '.' . $iteration;

View File

@@ -232,79 +232,6 @@
"dependency injection"
]
},
{
"name": "slim/slim",
"version": "3.9.0",
"version_normalized": "3.9.0.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "575a8b53a0a489447915029c69680156cd355304"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/575a8b53a0a489447915029c69680156cd355304",
"reference": "575a8b53a0a489447915029c69680156cd355304",
"shasum": ""
},
"require": {
"container-interop/container-interop": "^1.2",
"nikic/fast-route": "^1.0",
"php": ">=5.5.0",
"pimple/pimple": "^3.0",
"psr/container": "^1.0",
"psr/http-message": "^1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"squizlabs/php_codesniffer": "^2.5"
},
"time": "2017-11-04T08:46:46+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Slim\\": "Slim"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Allen",
"email": "rob@akrabat.com",
"homepage": "http://akrabat.com"
},
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "https://joshlockhart.com"
},
{
"name": "Gabriel Manricks",
"email": "gmanricks@me.com",
"homepage": "http://gabrielmanricks.com"
},
{
"name": "Andrew Smith",
"email": "a.smith@silentworks.co.uk",
"homepage": "http://silentworks.co.uk"
}
],
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
"homepage": "https://slimframework.com",
"keywords": [
"api",
"framework",
"micro",
"router"
]
},
{
"name": "twig/twig",
"version": "v1.35.0",
@@ -372,101 +299,6 @@
"templating"
]
},
{
"name": "symfony/yaml",
"version": "v2.8.30",
"version_normalized": "2.8.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "d819bf267e901727141fe828ae888486fd21236e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d819bf267e901727141fe828ae888486fd21236e",
"reference": "d819bf267e901727141fe828ae888486fd21236e",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"time": "2017-11-05T15:25:56+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com"
},
{
"name": "erusev/parsedown",
"version": "1.6.3",
"version_normalized": "1.6.3.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "728952b90a333b5c6f77f06ea9422b94b585878d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/728952b90a333b5c6f77f06ea9422b94b585878d",
"reference": "728952b90a333b5c6f77f06ea9422b94b585878d",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2017-05-14T14:47:48+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
]
},
{
"name": "slim/twig-view",
"version": "2.3.0",
@@ -670,5 +502,176 @@
"parsedown",
"parser"
]
},
{
"name": "slim/slim",
"version": "3.9.2",
"version_normalized": "3.9.2.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "4086d0106cf5a7135c69fce4161fe355a8feb118"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/4086d0106cf5a7135c69fce4161fe355a8feb118",
"reference": "4086d0106cf5a7135c69fce4161fe355a8feb118",
"shasum": ""
},
"require": {
"container-interop/container-interop": "^1.2",
"nikic/fast-route": "^1.0",
"php": ">=5.5.0",
"pimple/pimple": "^3.0",
"psr/container": "^1.0",
"psr/http-message": "^1.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"squizlabs/php_codesniffer": "^2.5"
},
"time": "2017-11-26T19:13:09+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Slim\\": "Slim"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rob Allen",
"email": "rob@akrabat.com",
"homepage": "http://akrabat.com"
},
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "https://joshlockhart.com"
},
{
"name": "Gabriel Manricks",
"email": "gmanricks@me.com",
"homepage": "http://gabrielmanricks.com"
},
{
"name": "Andrew Smith",
"email": "a.smith@silentworks.co.uk",
"homepage": "http://silentworks.co.uk"
}
],
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
"homepage": "https://slimframework.com",
"keywords": [
"api",
"framework",
"micro",
"router"
]
},
{
"name": "symfony/yaml",
"version": "v2.8.31",
"version_normalized": "2.8.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "d819bf267e901727141fe828ae888486fd21236e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/d819bf267e901727141fe828ae888486fd21236e",
"reference": "d819bf267e901727141fe828ae888486fd21236e",
"shasum": ""
},
"require": {
"php": ">=5.3.9"
},
"time": "2017-11-05T15:25:56+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com"
},
{
"name": "erusev/parsedown",
"version": "1.6.4",
"version_normalized": "1.6.4.0",
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown.git",
"reference": "fbe3fe878f4fe69048bb8a52783a09802004f548"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/fbe3fe878f4fe69048bb8a52783a09802004f548",
"reference": "fbe3fe878f4fe69048bb8a52783a09802004f548",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35"
},
"time": "2017-11-14T20:44:03+00:00",
"type": "library",
"installation-source": "source",
"autoload": {
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"markdown",
"parser"
]
}
]

View File

@@ -52,7 +52,7 @@ class App
*
* @var string
*/
const VERSION = '3.9.0';
const VERSION = '3.9.2';
/**
* Container
@@ -292,11 +292,29 @@ class App
$response = $this->container->get('response');
try {
ob_start();
$response = $this->process($this->container->get('request'), $response);
} catch (InvalidMethodException $e) {
$response = $this->processInvalidMethod($e->getRequest(), $response);
} finally {
$output = ob_get_clean();
}
if (!empty($output) && $response->getBody()->isWritable()) {
$outputBuffering = $this->container->get('settings')['outputBuffering'];
if ($outputBuffering === 'prepend') {
// prepend output buffer content
$body = new Http\Body(fopen('php://temp', 'r+'));
$body->write($output . $response->getBody());
$response = $response->withBody($body);
} elseif ($outputBuffering === 'append') {
// append output buffer content
$response->getBody()->write($output);
}
}
$response = $this->finalize($response);
if (!$silent) {
$this->respond($response);
}
@@ -374,13 +392,11 @@ class App
$response = $this->handlePhpError($e, $request, $response);
}
$response = $this->finalize($response);
return $response;
}
/**
* Send the response the client
* Send the response to the client
*
* @param ResponseInterface $response
*/

View File

@@ -153,8 +153,7 @@ class DefaultServicesProvider
*/
$container['errorHandler'] = function ($container) {
return new Error(
$container->get('settings')['displayErrorDetails'],
$container->get('settings')['outputBuffering']
$container->get('settings')['displayErrorDetails']
);
};
}

View File

@@ -4,7 +4,7 @@
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE (MIT License)
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Exception;

View File

@@ -4,7 +4,7 @@
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE (MIT License)
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Exception;

View File

@@ -1,5 +1,11 @@
<?php
/**
* Slim Framework (https://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Exception;
use Psr\Http\Message\ServerRequestInterface;

View File

@@ -4,7 +4,7 @@
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE (MIT License)
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Exception;

View File

@@ -4,7 +4,7 @@
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2017 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE (MIT License)
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Exception;

View File

@@ -18,20 +18,14 @@ abstract class AbstractError extends AbstractHandler
*/
protected $displayErrorDetails;
/**
* @var bool|string
*/
protected $outputBuffering;
/**
* Constructor
*
* @param bool $displayErrorDetails Set to true to display full details
*/
public function __construct($displayErrorDetails = false, $outputBuffering = false)
public function __construct($displayErrorDetails = false)
{
$this->displayErrorDetails = (bool) $displayErrorDetails;
$this->outputBuffering = $outputBuffering;
}
/**

View File

@@ -55,19 +55,7 @@ class Error extends AbstractError
$this->writeToErrorLog($exception);
$body = new Body(fopen('php://temp', 'r+'));
if ($this->outputBuffering === 'prepend') {
// prepend output buffer content
$body->write(ob_get_clean() . $output);
} elseif ($this->outputBuffering === 'append') {
// append output buffer content
$body->write($output . ob_get_clean());
} else {
// outputBuffering is false or some other unknown setting
// delete anything in the output buffer.
ob_get_clean();
$body->write($output);
}
$body->write($output);
return $response
->withStatus(500)

View File

@@ -249,6 +249,34 @@ class Response extends Message implements ResponseInterface
return '';
}
/*******************************************************************************
* Headers
******************************************************************************/
/**
* Return an instance with the provided value replacing the specified header.
*
* If a Location header is set and the status code is 200, then set the status
* code to 302 to mimic what PHP does. See https://github.com/slimphp/Slim/issues/1730
*
* @param string $name Case-insensitive header field name.
* @param string|string[] $value Header value(s).
* @return static
* @throws \InvalidArgumentException for invalid header names or values.
*/
public function withHeader($name, $value)
{
$clone = clone $this;
$clone->headers->set($name, $value);
if ($clone->getStatusCode() === 200 && strtolower($name) === 'location') {
$clone = $clone->withStatus(302);
}
return $clone;
}
/*******************************************************************************
* Body
******************************************************************************/

View File

@@ -381,6 +381,8 @@ class Uri implements UriInterface
$clone->user = $this->filterUserInfo($user);
if ($clone->user) {
$clone->password = $password ? $this->filterUserInfo($password) : '';
} else {
$clone->password = '';
}
return $clone;

View File

@@ -8,12 +8,9 @@
*/
namespace Slim;
use Exception;
use Throwable;
use InvalidArgumentException;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Exception\SlimException;
use Slim\Handlers\Strategies\RequestResponse;
use Slim\Interfaces\InvocationStrategyInterface;
use Slim\Interfaces\RouteInterface;
@@ -335,22 +332,7 @@ class Route extends Routable implements RouteInterface
/** @var InvocationStrategyInterface $handler */
$handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse();
// invoke route callable
if ($this->outputBuffering === false) {
$newResponse = $handler($this->callable, $request, $response, $this->arguments);
} else {
try {
ob_start();
$newResponse = $handler($this->callable, $request, $response, $this->arguments);
$output = ob_get_clean();
// @codeCoverageIgnoreStart
} catch (Throwable $e) {
throw $e;
// @codeCoverageIgnoreEnd
} catch (Exception $e) {
throw $e;
}
}
$newResponse = $handler($this->callable, $request, $response, $this->arguments);
if ($newResponse instanceof ResponseInterface) {
// if route callback returns a ResponseInterface, then use it
@@ -362,18 +344,6 @@ class Route extends Routable implements RouteInterface
}
}
if (!empty($output) && $response->getBody()->isWritable()) {
if ($this->outputBuffering === 'prepend') {
// prepend output buffer content
$body = new Http\Body(fopen('php://temp', 'r+'));
$body->write($output . $response->getBody());
$response = $response->withBody($body);
} elseif ($this->outputBuffering === 'append') {
// append output buffer content
$response->getBody()->write($output);
}
}
return $response;
}
}