Skip to content

Commit

Permalink
fixes Pages without meta block are rendered empty PhileCMS#351
Browse files Browse the repository at this point in the history
The raw-content has to be split into meta and content.

This was done in two places before (Page and Parser) essentially
duplicating the same functionality. Now this responsibility is delegated to the
Parser, it is the party with the knowledge on how to detect and extract the
meta from the content.

The evaluation of meta and content is still done twice as before, so there's
still room for performance improvement. But at least the implementations are
merged into one code place.
  • Loading branch information
Schlaefer committed Jul 29, 2022
1 parent de57daf commit e1ae62e
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 32 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
- Adds support for PHP 8 and removes support for PHP 7.
- Updated internal cache engine Phpfastcache from 6 to 9.

### Fixed
- Pages without meta block are rendered empty #351

## Release 1.11.1

Please see the [release notes](https://github.com/PhileCMS/Phile/releases/tag/1.11.1) or the [complete change-log](https://github.com/PhileCMS/Phile/compare/1.11.0...1.11.1) for more information
Expand Down
19 changes: 5 additions & 14 deletions lib/Phile/Model/Page.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Phile\Core\Router;
use Phile\Core\ServiceLocator;
use Phile\Repository\Page as Repository;
use Phile\ServiceLocator\MetaInterface;

/**
* the Model class for a page
Expand Down Expand Up @@ -173,25 +174,15 @@ public function getMeta()
/**
* parse the raw content
*/
protected function parseRawData()
protected function parseRawData(): void
{
$this->meta = new Meta($this->rawData);

$content = '';
if ($this->rawData !== null) {
$rawData = trim($this->rawData);
$fences = [
'c' => ['open' => '/*', 'close' => '*/'],
'html' => ['open' => '<!--', 'close' => '-->'],
'yaml' => ['open' => '---', 'close' => '---']
];
foreach ($fences as $fence) {
if (strncmp($fence['open'], $rawData, strlen($fence['open'])) === 0) {
$sub = substr($rawData, strlen($fence['open']));
list(, $content) = explode($fence['close'], $sub, 2);
break;
}
}
/** @var MetaInterface */
$metaParser = ServiceLocator::getService('Phile_Parser_Meta');
$content = $metaParser->extractContent($this->rawData);
}

$this->content = $content;
Expand Down
8 changes: 8 additions & 0 deletions lib/Phile/ServiceLocator/MetaInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ interface MetaInterface
* @return array with key/value store
*/
public function parse($rawData);

/**
* Parses text and extracts the content-part (meta-data is removed)
*
* @param string $rawData Text to inspect
* @return string Text without meta-data
*/
public function extractContent(?string $rawData): string;
}
64 changes: 46 additions & 18 deletions plugins/phile/parserMeta/Classes/Parser/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,31 +35,18 @@ public function __construct(array $config = null)
}

/**
* parse the content and extract meta information
* Implements MetaInterface::parse
*
* @param string $rawData raw page data
* @return array with key/value store
* {@inheritdoc}
*/
public function parse($rawData)
{
$rawData = trim($rawData);
$fences = $this->config['fences'];

$start = $stop = null;
foreach ($fences as $fence) {
$start = $fence['open'];
$length = strlen($start);
if (substr($rawData, 0, $length) === $start) {
$stop = $fence['close'];
break;
}
}

if ($stop === null) {
list($meta) = $this->findFenceStop($rawData);

if ($meta === null) {
return [];
}

$meta = trim(substr($rawData, strlen($start), strpos($rawData, $stop, strlen($start)) - (strlen($stop) + 1)));
if (strtolower($this->config['format']) === 'yaml') {
$meta = Yaml::parse($meta);
} else {
Expand All @@ -69,6 +56,47 @@ public function parse($rawData)
return $meta;
}

/**
* Implements MetaInterface::extractContent
*
* {@inheritdoc}
*/
public function extractContent(?string $rawData): string
{
list(, $content) = $this->findFenceStop($rawData);

return $content;
}

/**
* Inspects the text and splits meta-data and content
*
* @param string $rawData Text to inspect
* @return array array with [meta-data, content]
*/
protected function findFenceStop(string $rawData): array
{
$rawData = trim($rawData);
$fences = $this->config['fences'];

$meta = null;
$content = $rawData;

if ($rawData !== null) {
$rawData = trim($rawData);
$fences = $this->config['fences'];
foreach ($fences as $fence) {
if (strncmp($fence['open'], $rawData, strlen($fence['open'])) === 0) {
$sub = substr($rawData, strlen($fence['open']));
list($meta, $content) = explode($fence['close'], $sub, 2);
break;
}
}
}

return [$meta, $content];
}

/**
* convert meta data keys
*
Expand Down
14 changes: 14 additions & 0 deletions plugins/phile/parserMeta/tests/MetaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,18 @@ public function testYamlWithYamlFrontMatter()
$this->assertSame('foo', $meta['title']);
$this->assertSame(['bar', 'baz'], $meta['tags']);
}

public function testDataWithoutMetaDataBlock()
{
$raw = "# Hello World\n## Hello you too";
$parser = new Meta([
'fences' => ['yaml' => ['open' => '---', 'close' => '---']],
]);

$content = $parser->extractContent($raw);
$this->assertSame($raw, $content);

$meta = $parser->parse($raw);
$this->assertSame([], $meta);
}
}

0 comments on commit e1ae62e

Please sign in to comment.