Improved rendering with no caching and with validation
This commit is contained in:
parent
f1a7dadc9b
commit
d02f03ddd5
|
@ -164,11 +164,13 @@ public function exists(): bool
|
||||||
/**
|
/**
|
||||||
* Load everything
|
* Load everything
|
||||||
*/
|
*/
|
||||||
public function load(): void
|
public function load(): self
|
||||||
{
|
{
|
||||||
$this->loadAttachments();
|
$this->loadAttachments();
|
||||||
$this->loadMetadata();
|
$this->loadMetadata();
|
||||||
$this->loadMarkdown();
|
$this->loadMarkdown();
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -208,14 +210,11 @@ public function repair(): bool
|
||||||
|
|
||||||
public function touch()
|
public function touch()
|
||||||
{
|
{
|
||||||
$this->metadata()->set('lastModified', now()->toIso8601String());
|
// $parent = $this->getParent();
|
||||||
$this->saveMetadata();
|
|
||||||
|
|
||||||
$parent = $this->getParent();
|
// if (!empty($parent)) {
|
||||||
|
// $parent->touch();
|
||||||
if (!empty($parent)) {
|
// }
|
||||||
$parent->touch();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function render()
|
public function render()
|
||||||
|
@ -223,9 +222,6 @@ public function render()
|
||||||
$renderer = BundleRenderer::getBundleRendererFor($this);
|
$renderer = BundleRenderer::getBundleRendererFor($this);
|
||||||
$result = $renderer->render();
|
$result = $renderer->render();
|
||||||
|
|
||||||
$this->metadata()->set('lastRendered', now()->toIso8601String());
|
|
||||||
$this->metadata()->save();
|
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,6 +271,33 @@ public static function findBundles(FilesystemAdapter $disk, ?string $path = '/',
|
||||||
return $bundles;
|
return $bundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getFeedItems(FilesystemAdapter $disk)
|
||||||
|
{
|
||||||
|
$subBundles = Bundle::findBundles($disk, '/', true);
|
||||||
|
|
||||||
|
$subBundles = collect($subBundles)
|
||||||
|
->filter(fn (Bundle $bundle) => !empty($bundle->metadata()->get('date')))
|
||||||
|
->sort(function (Bundle $bundleA, Bundle $bundleB) {
|
||||||
|
return Carbon::parse($bundleA->metadata()->get('date'))->lt(Carbon::parse($bundleB->metadata()->get('date')));
|
||||||
|
})
|
||||||
|
->map(fn (Bundle $bundle) => $bundle->load())
|
||||||
|
->take(10);
|
||||||
|
|
||||||
|
return $subBundles;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function renderFeed(FilesystemAdapter $disk)
|
||||||
|
{
|
||||||
|
$lastBundles = static::getFeedItems($disk);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'/index.xml' => (string) view('feed', [
|
||||||
|
'bundles' => $lastBundles,
|
||||||
|
'lastBuildDate' => now()->toRssString(),
|
||||||
|
]),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
private function repairCover()
|
private function repairCover()
|
||||||
{
|
{
|
||||||
$cover = $this->metadata()->get('cover');
|
$cover = $this->metadata()->get('cover');
|
||||||
|
|
|
@ -36,6 +36,7 @@ public function __construct()
|
||||||
{ --r|recursive : Also render sub-bundles }
|
{ --r|recursive : Also render sub-bundles }
|
||||||
{ --source-disk= : Use specified content disk - Defaults to <info>' . env('CONTENT_DISK') . '</info> }
|
{ --source-disk= : Use specified content disk - Defaults to <info>' . env('CONTENT_DISK') . '</info> }
|
||||||
{ --target-disk= : Use specified rendering disk - Defaults to <info>' . env('DIST_DISK') . '</info> }
|
{ --target-disk= : Use specified rendering disk - Defaults to <info>' . env('DIST_DISK') . '</info> }
|
||||||
|
{ --validate : Perform validations before rendering }
|
||||||
{ path? : Path to a specific bundle to render - Default to <info>/</info> }
|
{ path? : Path to a specific bundle to render - Default to <info>/</info> }
|
||||||
';
|
';
|
||||||
|
|
||||||
|
@ -51,6 +52,8 @@ public function handle()
|
||||||
->selectDisk()
|
->selectDisk()
|
||||||
->renderAssets()
|
->renderAssets()
|
||||||
->clearCache()
|
->clearCache()
|
||||||
|
->validate()
|
||||||
|
->renderFeed()
|
||||||
->render()
|
->render()
|
||||||
->deploy();
|
->deploy();
|
||||||
}
|
}
|
||||||
|
@ -137,6 +140,23 @@ private function clearCache(): self
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function validate(): self
|
||||||
|
{
|
||||||
|
if (!$this->option('validate')) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->call('bundle:validate', ['--recursive' => true]);
|
||||||
|
|
||||||
|
if (!empty($result)) {
|
||||||
|
if (confirm('Validation errors have occurred. Cancel process?')) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect a list of bundles to render
|
* Collect a list of bundles to render
|
||||||
*/
|
*/
|
||||||
|
@ -153,7 +173,7 @@ private function getBundles()
|
||||||
$this->output->write('Collecting bundles... ');
|
$this->output->write('Collecting bundles... ');
|
||||||
|
|
||||||
if ($this->option('recursive')) {
|
if ($this->option('recursive')) {
|
||||||
$bundles = Bundle::findBundles($this->sourceDisk, $path, true);
|
$bundles = Bundle::findBundles($this->sourceDisk, $path, true, false);
|
||||||
} else {
|
} else {
|
||||||
$bundles = [new Bundle($path, $this->sourceDisk)];
|
$bundles = [new Bundle($path, $this->sourceDisk)];
|
||||||
}
|
}
|
||||||
|
@ -163,6 +183,19 @@ private function getBundles()
|
||||||
return $bundles;
|
return $bundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function renderFeed(): self
|
||||||
|
{
|
||||||
|
$result = Bundle::renderFeed($this->sourceDisk);
|
||||||
|
|
||||||
|
foreach ($result as $path => $content) {
|
||||||
|
$this->output->write(sprintf('Rendering <info>%s</info> as feed... ', $path));
|
||||||
|
$this->targetDisk->put($path, $content);
|
||||||
|
$this->info('OK');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform rendering
|
* Perform rendering
|
||||||
*/
|
*/
|
||||||
|
@ -185,7 +218,6 @@ private function render(): self
|
||||||
private function handleBundle(Bundle $bundle, $progress)
|
private function handleBundle(Bundle $bundle, $progress)
|
||||||
{
|
{
|
||||||
$progress->label(sprintf('Rendering %s ...', $bundle->getPath()));
|
$progress->label(sprintf('Rendering %s ...', $bundle->getPath()));
|
||||||
$progress->hint('Rendering the bundle');
|
|
||||||
|
|
||||||
if ($this->option('dry-run')) {
|
if ($this->option('dry-run')) {
|
||||||
return;
|
return;
|
||||||
|
@ -198,8 +230,6 @@ private function handleBundle(Bundle $bundle, $progress)
|
||||||
$path = Str::finish($path, '/') . 'index.html';
|
$path = Str::finish($path, '/') . 'index.html';
|
||||||
}
|
}
|
||||||
|
|
||||||
$progress->hint(sprintf('Storing %s', $path));
|
|
||||||
|
|
||||||
$this->targetDisk->put($path, $content);
|
$this->targetDisk->put($path, $content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,11 @@
|
||||||
use App\Classes\Link;
|
use App\Classes\Link;
|
||||||
use App\Services\BundleRenderers\Contracts\RendersBundle;
|
use App\Services\BundleRenderers\Contracts\RendersBundle;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use DOMXPath;
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use Masterminds\HTML5;
|
||||||
|
|
||||||
abstract class BaseRenderer implements RendersBundle
|
abstract class BaseRenderer implements RendersBundle
|
||||||
{
|
{
|
||||||
|
@ -44,17 +48,17 @@ public function render()
|
||||||
$this->prepareRender($currentPage);
|
$this->prepareRender($currentPage);
|
||||||
|
|
||||||
if ($currentPage === 1) {
|
if ($currentPage === 1) {
|
||||||
$result[$this->bundle->getPath()] = $this->renderView();
|
$result[$this->bundle->getPath()] = $this->renderPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = sprintf('%spage/%s/', $this->bundle->getPath(), $currentPage);
|
$page = sprintf('%spage/%s/', $this->bundle->getPath(), $currentPage);
|
||||||
|
|
||||||
$result[$page] = $this->renderView();
|
$result[$page] = $this->renderPage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$this->prepareRender(1);
|
$this->prepareRender(1);
|
||||||
|
|
||||||
$result[$this->bundle->getPath()] = $this->renderView();
|
$result[$this->bundle->getPath()] = $this->renderPage();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
|
@ -100,6 +104,18 @@ protected function prepareRender(int $currentPage = 1)
|
||||||
|
|
||||||
data_set($this->viewData, 'cover', $cover ? $cover->render() : null);
|
data_set($this->viewData, 'cover', $cover ? $cover->render() : null);
|
||||||
data_set($this->viewData, 'body', $this->bundle->markdown()->render());
|
data_set($this->viewData, 'body', $this->bundle->markdown()->render());
|
||||||
|
data_set($this->viewData, 'feedIsValid', Cache::get('feed_is_valid', false));
|
||||||
|
data_set($this->viewData, 'cssIsValid', Cache::get('css_is_valid', false));
|
||||||
|
|
||||||
|
if ($currentPage === 1) {
|
||||||
|
$path = $this->bundle->getPath();
|
||||||
|
} else {
|
||||||
|
$path = sprintf('%spage/%s/', $this->bundle->getPath(), $currentPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
$cacheKey = sprintf('html_is_valid_%s', Str::slug($path));
|
||||||
|
|
||||||
|
data_set($this->viewData, 'htmlIsValid', Cache::get($cacheKey, false));
|
||||||
|
|
||||||
$this->handlePagination($currentPage);
|
$this->handlePagination($currentPage);
|
||||||
}
|
}
|
||||||
|
@ -215,10 +231,39 @@ protected function collectSubBundles()
|
||||||
return $subBundles;
|
return $subBundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function renderView(?string $view = 'article')
|
/**
|
||||||
|
* Renders a full-page. Validates HTML
|
||||||
|
*/
|
||||||
|
protected function renderPage(?string $view = 'article')
|
||||||
{
|
{
|
||||||
$html = (string) view($view, $this->viewData);
|
$html = $this->renderView($view);
|
||||||
|
|
||||||
|
$html5 = new HTML5([
|
||||||
|
// Required tu use xpath, see
|
||||||
|
// https://github.com/Masterminds/html5-php/issues/123
|
||||||
|
'disable_html_ns' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$dom = $html5->loadHTML($html);
|
||||||
|
$xpath = new DOMXPath($dom);
|
||||||
|
$spans = $xpath->query('//pre/code/span[@class="line" and normalize-space(.) = ""]');
|
||||||
|
|
||||||
|
foreach ($spans as $span) {
|
||||||
|
if ($span->isSameNode($span->parentNode->lastChild)) {
|
||||||
|
$span->parentNode->removeChild($span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = $html5->saveHTML($dom);
|
||||||
|
|
||||||
return $html;
|
return $html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render specific view
|
||||||
|
*/
|
||||||
|
protected function renderView(string $view)
|
||||||
|
{
|
||||||
|
return (string) view($view, $this->viewData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ public function render()
|
||||||
data_set($this->viewData, 'showToc', true);
|
data_set($this->viewData, 'showToc', true);
|
||||||
data_set($this->viewData, 'dossier', $dossier);
|
data_set($this->viewData, 'dossier', $dossier);
|
||||||
|
|
||||||
return [$this->bundle->getPath() => $this->renderView()];
|
return [$this->bundle->getPath() => $this->renderPage()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,7 @@ public function render()
|
||||||
|
|
||||||
data_set($this->viewData, 'relations', $relations);
|
data_set($this->viewData, 'relations', $relations);
|
||||||
|
|
||||||
return [$this->bundle->getPath() => $this->renderView('term')];
|
return [$this->bundle->getPath() => $this->renderPage()];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user