Concentrate to one bundle renderer - for now
This commit is contained in:
parent
f839975252
commit
a0877d3bd0
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
class BundleRendererServiceProvider extends ServiceProvider
|
class BundleRendererServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
protected array $bundleRenderers = [
|
protected array $bundleRenderers = [];
|
||||||
\App\Services\BundleRenderers\Renderers\BlogRenderer::class,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register services.
|
* Register services.
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Services\BundleRenderers;
|
namespace App\Services\BundleRenderers;
|
||||||
|
|
||||||
use App\Classes\Bundle;
|
use App\Classes\Bundle;
|
||||||
use App\Exceptions\BundleRendererCannotBeFound;
|
use App\Services\BundleRenderers\Renderers\ListRenderer;
|
||||||
|
|
||||||
class BundleRendererFactory
|
class BundleRendererFactory
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ public function getBundleRendererFor(Bundle $bundle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new BundleRendererCannotBeFound();
|
return new ListRenderer($bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,14 +2,32 @@
|
||||||
|
|
||||||
namespace App\Services\BundleRenderers\Renderers;
|
namespace App\Services\BundleRenderers\Renderers;
|
||||||
|
|
||||||
|
use App\Classes\AttachmentsManager;
|
||||||
use App\Classes\Bundle;
|
use App\Classes\Bundle;
|
||||||
use App\Services\BundleRenderers\Contracts\RendersBundle;
|
use App\Services\BundleRenderers\Contracts\RendersBundle;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
abstract class BaseRenderer implements RendersBundle
|
abstract class BaseRenderer implements RendersBundle
|
||||||
{
|
{
|
||||||
|
protected array $viewData = [];
|
||||||
|
|
||||||
public function __construct(protected Bundle $bundle)
|
public function __construct(protected Bundle $bundle)
|
||||||
{
|
{
|
||||||
$bundle->load();
|
$bundle->load();
|
||||||
|
|
||||||
|
$this->shareCommonDataWithView();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a card HTML view of the bundle, suitable to display in lists
|
||||||
|
*/
|
||||||
|
public function renderCard()
|
||||||
|
{
|
||||||
|
return view('article-card', [
|
||||||
|
'bundle' => $this->bundle,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,4 +37,122 @@ public static function make(Bundle $bundle): RendersBundle
|
||||||
{
|
{
|
||||||
return new static($bundle);
|
return new static($bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a complete HTML view of the bundle
|
||||||
|
*/
|
||||||
|
protected function prepareRender()
|
||||||
|
{
|
||||||
|
$this->bundle->markdown()->lint();
|
||||||
|
|
||||||
|
$coverRef = $this->bundle->metadata()->get('cover');
|
||||||
|
$cover = null;
|
||||||
|
|
||||||
|
if (!empty($coverRef)) {
|
||||||
|
$cover = $this->bundle->attachments(AttachmentsManager::Images)->getComponentByRef($coverRef, 'article');
|
||||||
|
}
|
||||||
|
|
||||||
|
$date = $this->bundle->metadata()->get('date');
|
||||||
|
|
||||||
|
if (!empty($date)) {
|
||||||
|
data_set($this->viewData, 'date', Carbon::parse($date));
|
||||||
|
}
|
||||||
|
|
||||||
|
data_set($this->viewData, 'cover', $cover ? $cover->render() : null);
|
||||||
|
data_set($this->viewData, 'body', $this->bundle->markdown()->render());
|
||||||
|
|
||||||
|
$this->handlePagination();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-fill view with data used by all renderers
|
||||||
|
*/
|
||||||
|
protected function shareCommonDataWithView(): void
|
||||||
|
{
|
||||||
|
data_set($this->viewData, 'siteTitle', $this->bundle->getSiteTitle());
|
||||||
|
data_set($this->viewData, 'articleTitle', $this->bundle->getArticleTitle());
|
||||||
|
data_set($this->viewData, 'bundle', $this->bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handlePagination()
|
||||||
|
{
|
||||||
|
$itemsPerPage = config('pagination.itemsPerPage');
|
||||||
|
$currentPage = $this->bundle->getCurrentPage();
|
||||||
|
$lastModified = $this->bundle->lastModified();
|
||||||
|
|
||||||
|
$cacheKey = sprintf('subBundles_%s', base64_encode($this->bundle->getPath()));
|
||||||
|
$cacheKeyLm = sprintf('subBundles_%s_lastModified', base64_encode($this->bundle->getPath()));
|
||||||
|
|
||||||
|
if (
|
||||||
|
Cache::has($cacheKeyLm)
|
||||||
|
&& Cache::has($cacheKey)
|
||||||
|
&& $lastModified
|
||||||
|
&& Cache::get($cacheKeyLm)->gte($lastModified)
|
||||||
|
) {
|
||||||
|
$subBundles = Cache::get($cacheKey);
|
||||||
|
} else {
|
||||||
|
$subBundles = $this->collectSubBundles();
|
||||||
|
|
||||||
|
Cache::put($cacheKey, $subBundles, now()->addWeek());
|
||||||
|
Cache::put($cacheKeyLm, $lastModified, now()->addWeek());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$this->bundle->exists() && empty($subBundles)) {
|
||||||
|
throw new Exception(sprintf(
|
||||||
|
'Page %s does not exist in bundle %s',
|
||||||
|
$this->bundle->getCurrentPage(),
|
||||||
|
$this->bundle->getPath()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$totalPages = 1;
|
||||||
|
|
||||||
|
if (!empty($subBundles)) {
|
||||||
|
$chunks = array_chunk($subBundles, $itemsPerPage);
|
||||||
|
|
||||||
|
if (!array_key_exists($currentPage - 1, $chunks) && $currentPage > 1) {
|
||||||
|
throw new Exception(sprintf(
|
||||||
|
'Page %s does not exist in bundle %s',
|
||||||
|
$currentPage - 1,
|
||||||
|
$this->bundle->getPath()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$currentChunk = $chunks[$currentPage - 1];
|
||||||
|
$totalPages = count($chunks);
|
||||||
|
} else {
|
||||||
|
$currentChunk = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$bundles = [];
|
||||||
|
|
||||||
|
if (!empty($currentChunk)) {
|
||||||
|
$bundles = array_map(fn (string $path) => new Bundle($path, $this->bundle->getDisk()), $currentChunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'root' => $this->bundle->getPath(),
|
||||||
|
'itemsPerPage' => $itemsPerPage,
|
||||||
|
'currentPage' => $currentPage,
|
||||||
|
'totalPages' => $totalPages,
|
||||||
|
'items' => $bundles,
|
||||||
|
];
|
||||||
|
|
||||||
|
data_set($this->viewData, 'pagination', $data);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function collectSubBundles()
|
||||||
|
{
|
||||||
|
$subBundles = Bundle::findBundles($this->bundle->getDisk(), $this->bundle->getPath(), true);
|
||||||
|
|
||||||
|
$subBundles = collect($subBundles)
|
||||||
|
->filter(fn (Bundle $bundle) => !empty($bundle->metadata()->get('date')) && $bundle->getPath() !== $this->bundle->getPath())
|
||||||
|
->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->getPath())
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
return $subBundles;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Services\BundleRenderers\Renderers;
|
|
||||||
|
|
||||||
use App\Classes\Bundle;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
|
|
||||||
class BlogRenderer extends BaseRenderer
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Renders a complete HTML view of the bundle
|
|
||||||
*/
|
|
||||||
public function render()
|
|
||||||
{
|
|
||||||
return view('article', [
|
|
||||||
'articleTitle' => $this->bundle->metadata()->get('title'),
|
|
||||||
'date' => Carbon::parse($this->bundle->metadata()->get('date'))->format('d/m/Y'),
|
|
||||||
'body' => $this->bundle->markdown()->render(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a boolean value indicating if this creator in particular can
|
|
||||||
* create bundles for specified section
|
|
||||||
*/
|
|
||||||
public static function handles(Bundle $bundle): bool
|
|
||||||
{
|
|
||||||
$parts = preg_split('#/#', $bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY);
|
|
||||||
|
|
||||||
return $parts && $parts[0] === 'blog' && count($parts) === 5;
|
|
||||||
}
|
|
||||||
}
|
|
29
app/Services/BundleRenderers/Renderers/ListRenderer.php
Normal file
29
app/Services/BundleRenderers/Renderers/ListRenderer.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\BundleRenderers\Renderers;
|
||||||
|
|
||||||
|
use App\Classes\Bundle;
|
||||||
|
|
||||||
|
class ListRenderer extends BaseRenderer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Renders a complete HTML view of the bundle
|
||||||
|
*/
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$this->prepareRender();
|
||||||
|
|
||||||
|
return view('article', $this->viewData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a boolean value indicating if this creator in particular can
|
||||||
|
* create bundles for specified section
|
||||||
|
*/
|
||||||
|
public static function handles(Bundle $bundle): bool
|
||||||
|
{
|
||||||
|
// This renderer is used by default when no other renderer claimed it
|
||||||
|
// can handle the path
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user