1
0

Improved rendering with no caching and with validation

This commit is contained in:
Richard Dern 2024-05-09 21:54:06 +02:00
parent f1a7dadc9b
commit d02f03ddd5
5 changed files with 120 additions and 22 deletions

View File

@ -164,11 +164,13 @@ public function exists(): bool
/**
* Load everything
*/
public function load(): void
public function load(): self
{
$this->loadAttachments();
$this->loadMetadata();
$this->loadMarkdown();
return $this;
}
/**
@ -208,14 +210,11 @@ public function repair(): bool
public function touch()
{
$this->metadata()->set('lastModified', now()->toIso8601String());
$this->saveMetadata();
// $parent = $this->getParent();
$parent = $this->getParent();
if (!empty($parent)) {
$parent->touch();
}
// if (!empty($parent)) {
// $parent->touch();
// }
}
public function render()
@ -223,9 +222,6 @@ public function render()
$renderer = BundleRenderer::getBundleRendererFor($this);
$result = $renderer->render();
$this->metadata()->set('lastRendered', now()->toIso8601String());
$this->metadata()->save();
return $result;
}
@ -275,6 +271,33 @@ public static function findBundles(FilesystemAdapter $disk, ?string $path = '/',
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()
{
$cover = $this->metadata()->get('cover');

View File

@ -36,6 +36,7 @@ public function __construct()
{ --r|recursive : Also render sub-bundles }
{ --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> }
{ --validate : Perform validations before rendering }
{ path? : Path to a specific bundle to render - Default to <info>/</info> }
';
@ -51,6 +52,8 @@ public function handle()
->selectDisk()
->renderAssets()
->clearCache()
->validate()
->renderFeed()
->render()
->deploy();
}
@ -137,6 +140,23 @@ private function clearCache(): self
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
*/
@ -153,7 +173,7 @@ private function getBundles()
$this->output->write('Collecting bundles... ');
if ($this->option('recursive')) {
$bundles = Bundle::findBundles($this->sourceDisk, $path, true);
$bundles = Bundle::findBundles($this->sourceDisk, $path, true, false);
} else {
$bundles = [new Bundle($path, $this->sourceDisk)];
}
@ -163,6 +183,19 @@ private function getBundles()
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
*/
@ -185,7 +218,6 @@ private function render(): self
private function handleBundle(Bundle $bundle, $progress)
{
$progress->label(sprintf('Rendering %s ...', $bundle->getPath()));
$progress->hint('Rendering the bundle');
if ($this->option('dry-run')) {
return;
@ -198,8 +230,6 @@ private function handleBundle(Bundle $bundle, $progress)
$path = Str::finish($path, '/') . 'index.html';
}
$progress->hint(sprintf('Storing %s', $path));
$this->targetDisk->put($path, $content);
}
}

View File

@ -7,7 +7,11 @@
use App\Classes\Link;
use App\Services\BundleRenderers\Contracts\RendersBundle;
use Carbon\Carbon;
use DOMXPath;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Masterminds\HTML5;
abstract class BaseRenderer implements RendersBundle
{
@ -44,17 +48,17 @@ public function render()
$this->prepareRender($currentPage);
if ($currentPage === 1) {
$result[$this->bundle->getPath()] = $this->renderView();
$result[$this->bundle->getPath()] = $this->renderPage();
}
$page = sprintf('%spage/%s/', $this->bundle->getPath(), $currentPage);
$result[$page] = $this->renderView();
$result[$page] = $this->renderPage();
}
} else {
$this->prepareRender(1);
$result[$this->bundle->getPath()] = $this->renderView();
$result[$this->bundle->getPath()] = $this->renderPage();
}
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, '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);
}
@ -215,10 +231,39 @@ protected function collectSubBundles()
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;
}
/**
* Render specific view
*/
protected function renderView(string $view)
{
return (string) view($view, $this->viewData);
}
}

View File

@ -20,7 +20,7 @@ public function render()
data_set($this->viewData, 'showToc', true);
data_set($this->viewData, 'dossier', $dossier);
return [$this->bundle->getPath() => $this->renderView()];
return [$this->bundle->getPath() => $this->renderPage()];
}
/**

View File

@ -27,7 +27,7 @@ public function render()
data_set($this->viewData, 'relations', $relations);
return [$this->bundle->getPath() => $this->renderView('term')];
return [$this->bundle->getPath() => $this->renderPage()];
}
/**