Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render Hooks #151

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions resources/views/components/about.blade.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_ABOUT_BEFORE) }}

@if ($about !== '')
<div>
<h1 class="text-3xl font-semibold">{{ $title }}</h1>
Expand All @@ -6,3 +8,5 @@
</div>
</div>
@endif

{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_ABOUT_AFTER) }}
3 changes: 3 additions & 0 deletions resources/views/components/cachet.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@
</style>
</head>
<body class="flex min-h-screen flex-col items-stretch antialiased">
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_BODY_BEFORE) }}
{{ $slot }}

<!-- Custom Cachet Footer -->
{!! $cachet_footer !!}

{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_BODY_AFTER) }}
</body>
</html>
2 changes: 2 additions & 0 deletions resources/views/components/component-group.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@props(['componentGroup' => null])

{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_COMPONENT_GROUPS_BEFORE) }}
<div x-data x-disclosure {{ $attributes
->merge(array_filter([
'default-open' => $componentGroup->isExpanded(),
Expand Down Expand Up @@ -29,3 +30,4 @@
</ul>
</div>
</div>
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_COMPONENT_GROUPS_AFTER) }}
2 changes: 2 additions & 0 deletions resources/views/components/component.blade.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_COMPONENTS_BEFORE) }}
<li class="px-4 py-3">
<div class="flex items-center justify-between">
<div class="flex flex-col grow gap-y-1">
Expand Down Expand Up @@ -37,3 +38,4 @@
</div>
</div>
</li>
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_BODY_AFTER) }}
4 changes: 3 additions & 1 deletion resources/views/components/header.blade.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_NAVIGATION_BEFORE) }}
<div class="flex items-center justify-between border-b border-zinc-200 px-4 sm:px-6 lg:px-8 py-4 dark:border-zinc-700">
<div>
<a href="{{ route('cachet.status-page') }}" class="transition hover:opacity-80">
Expand All @@ -22,4 +23,5 @@
@endauth
</div>
@endif
</div>
</div>
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_NAVIGATION_AFTER) }}
2 changes: 2 additions & 0 deletions resources/views/components/incident.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
'incidents',
])

{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_INCIDENTS_BEFORE) }}
<div class="relative flex flex-col gap-5" x-data="{ forDate: new Date(@js($date)) }">
<h3 class="text-xl font-semibold"><time datetime="{{ $date }}" x-text="forDate.toLocaleDateString()"></time></h3>
@forelse($incidents as $incident)
Expand Down Expand Up @@ -78,3 +79,4 @@
</div>
@endforelse
</div>
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_INCIDENTS_AFTER) }}
2 changes: 2 additions & 0 deletions resources/views/components/schedule.blade.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_SCHEDULES_BEFORE) }}
<li class="p-4" x-data="{ timestamp: new Date(@js($schedule->scheduled_at)) }">
<div class="flex flex-col-reverse items-start justify-between gap-4 md:flex-row md:items-center">
<div class="flex items-start gap-2.5 w-full">
Expand Down Expand Up @@ -37,3 +38,4 @@
</div>
</div>
</li>
{{ \Cachet\Facades\CachetView::renderHook(\Cachet\View\RenderHook::STATUS_PAGE_SCHEDULES_AFTER) }}
2 changes: 2 additions & 0 deletions src/CachetCoreServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Cachet\Models\Incident;
use Cachet\Models\Schedule;
use Cachet\Settings\AppSettings;
use Cachet\View\ViewManager;
use Filament\Support\Colors\Color;
use Filament\Support\Facades\FilamentColor;
use Illuminate\Cache\RateLimiting\Limit;
Expand All @@ -31,6 +32,7 @@ public function register(): void
}

$this->app->singleton(Cachet::class);
$this->app->singleton(ViewManager::class);
}

/**
Expand Down
28 changes: 28 additions & 0 deletions src/Facades/CachetView.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

namespace Cachet\Facades;

use Cachet\View\ViewManager;
use Closure;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Facades\Facade;

/**
* @method static Htmlable renderHook(string $name, string | array | null $scopes = null)
*
* @see ViewManager
*/
class CachetView extends Facade
{
protected static function getFacadeAccessor()
{
return ViewManager::class;
}

public static function registerRenderHook(string $name, Closure $hook, string | array | null $scopes = null): void
{
static::resolved(function (ViewManager $viewManager) use ($name, $hook, $scopes) {
$viewManager->registerRenderHook($name, $hook, $scopes);
});
}
}
42 changes: 42 additions & 0 deletions src/View/RenderHook.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace Cachet\View;

class RenderHook
{
const STATUS_PAGE_BODY_AFTER = 'cachet::status-page.body.after';

const STATUS_PAGE_BODY_BEFORE = 'cachet::status-page.body.before';

const STATUS_PAGE_NAVIGATION_AFTER = 'cachet::status-page.navigation.after';

const STATUS_PAGE_NAVIGATION_BEFORE = 'cachet::status-page.navigation.before';

const STATUS_PAGE_ABOUT_AFTER = 'cachet::status-page.about.after';

const STATUS_PAGE_ABOUT_BEFORE = 'cachet::status-page.about.before';

const STATUS_PAGE_COMPONENTS_AFTER = 'cachet::status-page.components.after';

const STATUS_PAGE_COMPONENTS_BEFORE = 'cachet::status-page.components.before';

const STATUS_PAGE_COMPONENT_GROUPS_AFTER = 'cachet::status-page.component-groups.after';

const STATUS_PAGE_COMPONENT_GROUPS_BEFORE = 'cachet::status-page.component-groups.before';

const STATUS_PAGE_INCIDENTS_AFTER = 'cachet::status-page.incidents.after';

const STATUS_PAGE_INCIDENTS_BEFORE = 'cachet::status-page.incidents.before';

const STATUS_PAGE_SCHEDULES_AFTER = 'cachet::status-page.schedules.after';

const STATUS_PAGE_SCHEDULES_BEFORE = 'cachet::status-page.schedules.before';

const STATUS_PAGE_BANNER = 'cachet::status-page.banner';

const STATUS_PAGE_METRICS_AFTER = 'cachet::status-page.metrics.after';

const STATUS_PAGE_METRICS_BEFORE = 'cachet::status-page.metrics.before';

const FOOTER = 'cachet::footer';
}
69 changes: 69 additions & 0 deletions src/View/ViewManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

namespace Cachet\View;

use Closure;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Arr;
use Illuminate\Support\HtmlString;

class ViewManager
{
/**
* @var array<string, array<string, array<Closure>>>
*/
protected array $renderHooks = [];

/**
* @param string | array<string> | null $scopes
*/
public function registerRenderHook(string $name, Closure $hook, string | array | null $scopes = null): void
{
if (! is_array($scopes)) {
$scopes = [$scopes];
}

foreach ($scopes as $scopeName) {
$this->renderHooks[$name][$scopeName][] = $hook;
}
}

/**
* @param string | array<string> | null $scopes
*/
public function renderHook(string $name, string | array | null $scopes = null): Htmlable
{
$renderedHooks = [];

$scopes = Arr::wrap($scopes);

$renderHook = function (callable $hook) use (&$renderedHooks, $scopes): ?string {
$hookId = spl_object_id($hook);

if (in_array($hookId, $renderedHooks)) {
return null;
}

$renderedHooks[] = $hookId;

return (string) app()->call($hook, ['scopes' => $scopes]);
};

$hooks = array_map(
$renderHook,
$this->renderHooks[$name][null] ?? [],
);

foreach ($scopes as $scopeName) {
$hooks = [
...$hooks,
...array_map(
$renderHook,
$this->renderHooks[$name][$scopeName] ?? [],
),
];
}

return new HtmlString(implode('', $hooks));
}
}
2 changes: 1 addition & 1 deletion tests/Architecture/ViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
use Illuminate\View\Component;

test('view test')
->expect('Cachet\View')
->expect('Cachet\View\Components')
->toBeClasses()
->toExtend(Component::class);
Loading