Displaying of dossiers
This commit is contained in:
parent
4a4727f92d
commit
c7010c7e74
|
@ -7,6 +7,7 @@
|
||||||
use App\Classes\Traits\ManagesMetadata;
|
use App\Classes\Traits\ManagesMetadata;
|
||||||
use App\Contracts\Bundles;
|
use App\Contracts\Bundles;
|
||||||
use App\Services\BundleRenderers\Facades\BundleRenderer;
|
use App\Services\BundleRenderers\Facades\BundleRenderer;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Illuminate\Filesystem\FilesystemAdapter;
|
use Illuminate\Filesystem\FilesystemAdapter;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
@ -26,6 +27,8 @@ class Bundle implements Bundles
|
||||||
|
|
||||||
protected ?Bundle $parent;
|
protected ?Bundle $parent;
|
||||||
|
|
||||||
|
protected ?array $directChildren;
|
||||||
|
|
||||||
public function __construct(protected string $path, protected FilesystemAdapter $disk)
|
public function __construct(protected string $path, protected FilesystemAdapter $disk)
|
||||||
{
|
{
|
||||||
$this->path = $this->normalizeBundlePath($path);
|
$this->path = $this->normalizeBundlePath($path);
|
||||||
|
@ -102,6 +105,18 @@ public function getParent(): ?Bundle
|
||||||
return $this->parent;
|
return $this->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array containing direct children of this bundle
|
||||||
|
*/
|
||||||
|
public function getDirectChildren(): array
|
||||||
|
{
|
||||||
|
if (!isset($this->directChildren)) {
|
||||||
|
$this->directChildren = static::findBundles($this->getDisk(), $this->getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->directChildren;
|
||||||
|
}
|
||||||
|
|
||||||
public function getArticleTitle(): string
|
public function getArticleTitle(): string
|
||||||
{
|
{
|
||||||
return $this->metadata()->get('title') ?? Str::title(basename($this->path));
|
return $this->metadata()->get('title') ?? Str::title(basename($this->path));
|
||||||
|
@ -199,6 +214,15 @@ public static function findBundles(FilesystemAdapter $disk, ?string $path = '/',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$bundles = collect($bundles)
|
||||||
|
->sortBy([
|
||||||
|
fn (Bundle $a, Bundle $b) => Carbon::parse($a->metadata()->get('date'))
|
||||||
|
->gt(Carbon::parse($b->metadata()->get('date'))),
|
||||||
|
fn (Bundle $a, Bundle $b) => Carbon::parse($b->metadata()->get('date'))
|
||||||
|
->gt(Carbon::parse($a->metadata()->get('date'))),
|
||||||
|
])
|
||||||
|
->toArray();
|
||||||
|
|
||||||
return $bundles;
|
return $bundles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
|
|
||||||
class BundleRendererServiceProvider extends ServiceProvider
|
class BundleRendererServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
protected array $bundleRenderers = [];
|
protected array $bundleRenderers = [
|
||||||
|
\App\Services\BundleRenderers\Renderers\DossiersListRenderer::class,
|
||||||
|
\App\Services\BundleRenderers\Renderers\DossierRenderer::class,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register services.
|
* Register services.
|
||||||
|
|
48
app/Services/BundleRenderers/Renderers/DossierRenderer.php
Normal file
48
app/Services/BundleRenderers/Renderers/DossierRenderer.php
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\BundleRenderers\Renderers;
|
||||||
|
|
||||||
|
use App\Classes\Bundle;
|
||||||
|
|
||||||
|
class DossierRenderer extends BaseRenderer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Renders a complete HTML view of the bundle
|
||||||
|
*/
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
$this->prepareRender();
|
||||||
|
|
||||||
|
$parts = preg_split('#/#', $this->bundle->getPath(), -1, PREG_SPLIT_NO_EMPTY);
|
||||||
|
$dossierPath = implode('/', [$parts[0], $parts[1]]);
|
||||||
|
$dossier = new Bundle($dossierPath, $this->bundle->getDisk());
|
||||||
|
|
||||||
|
data_set($this->viewData, 'showToc', true);
|
||||||
|
data_set($this->viewData, 'dossier', $dossier);
|
||||||
|
|
||||||
|
return view('article', $this->viewData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders a card HTML view of the bundle, suitable to display in lists
|
||||||
|
*/
|
||||||
|
public function renderCard()
|
||||||
|
{
|
||||||
|
$this->prepareRenderCard();
|
||||||
|
|
||||||
|
return view('dossier-card', $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
|
||||||
|
{
|
||||||
|
return $bundle->getSection() && $bundle->getSection()->getPath() === '/dossiers/';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handlePagination()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\BundleRenderers\Renderers;
|
||||||
|
|
||||||
|
use App\Classes\Bundle;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
|
||||||
|
class DossiersListRenderer 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
|
||||||
|
{
|
||||||
|
return $bundle->getPath() === '/dossiers/';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function collectSubBundles()
|
||||||
|
{
|
||||||
|
$subBundles = Bundle::findBundles($this->bundle->getDisk(), $this->bundle->getPath());
|
||||||
|
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,55 @@ #article-main {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1.5rem;
|
gap: 1.5rem;
|
||||||
|
|
||||||
|
.drop {
|
||||||
|
font-size: 1rem;
|
||||||
|
width: var(--design-width);
|
||||||
|
margin: 0 auto;
|
||||||
|
color: #6c7a89;
|
||||||
|
background: #01010c radial-gradient(at bottom center, #00101f, #000614, #01010c) no-repeat;
|
||||||
|
box-shadow: 0 1px 1rem #000;
|
||||||
|
border-radius: .5rem;
|
||||||
|
border: solid 2px #00101f;
|
||||||
|
padding: 0 1rem;
|
||||||
|
|
||||||
|
summary ~ * {
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.down {
|
||||||
|
summary ~ * {
|
||||||
|
top: 3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.up {
|
||||||
|
summary ~ * {
|
||||||
|
bottom: 3em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
padding: .5rem;
|
||||||
|
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
padding-left: 2rem;
|
||||||
|
line-height: 150%;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
padding: .2rem 0;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li + li {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.table-of-contents {
|
.table-of-contents {
|
||||||
margin: 2rem auto;
|
margin: 2rem auto;
|
||||||
line-height: 150%;
|
line-height: 150%;
|
||||||
|
|
|
@ -24,9 +24,27 @@ class="{!! $mainLink['classes'] !!}"
|
||||||
@endif
|
@endif
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
@if (!empty($body))
|
@if (!empty($body) || $showToc)
|
||||||
<section id="article-body">
|
<section id="article-body">
|
||||||
|
@if($showToc)
|
||||||
|
<details class="drop down">
|
||||||
|
<summary>Sommaire</summary>
|
||||||
|
<nav>
|
||||||
|
@include('components.table-of-contents', ['toc' => $dossier->getDirectChildren()])
|
||||||
|
</nav>
|
||||||
|
</details>
|
||||||
|
@endif
|
||||||
|
|
||||||
{!! $body !!}
|
{!! $body !!}
|
||||||
|
|
||||||
|
@if($showToc)
|
||||||
|
<details class="drop up">
|
||||||
|
<summary>Sommaire</summary>
|
||||||
|
<nav>
|
||||||
|
@include('components.table-of-contents', ['toc' => $dossier->getDirectChildren()])
|
||||||
|
</nav>
|
||||||
|
</details>
|
||||||
|
@endif
|
||||||
</section>
|
</section>
|
||||||
@endif
|
@endif
|
||||||
</article>
|
</article>
|
||||||
|
|
14
resources/views/components/table-of-contents.blade.php
Normal file
14
resources/views/components/table-of-contents.blade.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<ul>
|
||||||
|
@foreach ($toc as $item)
|
||||||
|
<li>
|
||||||
|
@if ('/' . urldecode(request()->path()) . '/' === $item->getPath())
|
||||||
|
<strong>{{ $item->getArticleTitle() }}</strong>
|
||||||
|
@else
|
||||||
|
<a href="{{ $item->getPath() }}">{{ $item->getArticleTitle() }}</a>
|
||||||
|
@endif
|
||||||
|
@if (!empty($item->getDirectChildren()))
|
||||||
|
@include('components.table-of-contents', ['toc' => $item->getDirectChildren()])
|
||||||
|
@endif
|
||||||
|
</li>
|
||||||
|
@endforeach
|
||||||
|
</ul>
|
13
resources/views/dossier-card.blade.php
Normal file
13
resources/views/dossier-card.blade.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<a class="article-card-link" href="{{ $bundle->getPath() }}">
|
||||||
|
<article class="article-card">
|
||||||
|
<h2>{!! $bundle->getArticleTitle() !!}</h2>
|
||||||
|
<section class="article-card-body">
|
||||||
|
@if (!empty($date))
|
||||||
|
<p><time datetime="{{ $date->toIso8601String() }}">{{ $date->isoFormat('LL') }}</time></p>
|
||||||
|
@endif
|
||||||
|
@if (!empty($section))
|
||||||
|
<p>{!! $section->getArticleTitle() !!}</p>
|
||||||
|
@endif
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
</a>
|
Loading…
Reference in New Issue
Block a user