diff --git a/.idea/blade.xml b/.idea/blade.xml index ef260f9..a30d69b 100644 --- a/.idea/blade.xml +++ b/.idea/blade.xml @@ -53,6 +53,7 @@ + @@ -89,14 +90,18 @@ + + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index d834035..8015452 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ format. This project adheres to [Semantic Versioning](https://semver.org/spec/v2 ## [Unreleased] +### Added + +- Added support for view hooks as closures that return a view +- Added support for explicitly setting the view name in `` + ## [0.1.0] - 2024-01-24 ### Changed diff --git a/README.md b/README.md index a2743ed..8e4e0ff 100644 --- a/README.md +++ b/README.md @@ -241,11 +241,11 @@ Now you have two spots that you can hook into… // Somewhere in a `PromotionsServiceProvider` class, perhaps… if ($this->isInCyberMondayPromotionalPeriod()) { - View::hook('emails.receipt', 'intro', view('emails.promotions._cyber_monday_intro')); + View::hook('emails.receipt', 'intro', fn() => view('emails.promotions._cyber_monday_intro')); } if (Auth::user()->isNewRegistrant()) { - View::hook('emails.receipt', 'footer', view('emails.promotions._thank_you_for_first_purchase')); + View::hook('emails.receipt', 'footer', fn() => view('emails.promotions._thank_you_for_first_purchase')); } ``` @@ -256,6 +256,18 @@ anything that Blade can render. Finally, the fourth argument is a `priority` val the priority, the earlier it will be rendered (if there are multiple things hooking into the same spot). If you do not provide a priority, it will be set the `1000` by default. +### Explicitly Setting View Name + +The `` Blade component can usually infer what view it's being rendered inside. +Depending on how your views are rendered, though, you may need to explicitly pass the view +name to the component. You can do that by passing an additional `view` prop: + +```blade + +``` + +This is a requirement that we hope to improve in a future release! + ### View Hook Attributes It's possible to pass component attributes to your hooks, using regular Blade syntax: diff --git a/src/Support/HooksServiceProvider.php b/src/Support/HooksServiceProvider.php index 787fe3f..18fe884 100755 --- a/src/Support/HooksServiceProvider.php +++ b/src/Support/HooksServiceProvider.php @@ -40,22 +40,29 @@ public function packageBooted() Closure|Htmlable|Hook $hook, int $priority = Hook::DEFAULT_PRIORITY ) use ($observer) { - if ($hook instanceof Htmlable) { - $html = $hook; - $hook = function(Context $context) use ($observer, $html) { - return $observer->withoutObserving(function() use ($html, $context) { - if ($html instanceof ViewContract) { - $html->with($context->data); + $wrapper = function(Context $context) use ($observer, $hook) { + // Unwrap the hook + while ($hook instanceof Closure) { + $hook = $hook($context); + } + + // If it's a view, render it + if ($hook instanceof Htmlable) { + $hook = $observer->withoutObserving(function() use ($hook, $context) { + if ($hook instanceof ViewContract) { + $hook->with($context->data); } - return new HtmlString($html->toHtml()); + return new HtmlString($hook->toHtml()); }); - }; - } + } + + return $hook; + }; app(HookRegistry::class) ->get($view) - ->on($name, $hook, $priority); + ->on($name, $wrapper, $priority); }); } } diff --git a/src/View/Components/Hook.php b/src/View/Components/Hook.php index b83ebd1..10dab59 100644 --- a/src/View/Components/Hook.php +++ b/src/View/Components/Hook.php @@ -12,13 +12,14 @@ public function __construct( public HookRegistry $registry, public Observer $observer, public string $name, + public ?string $view = null, ) { } public function render() { return function(array $data) { - $view = $this->observer->active_view->getName(); + $view = $this->view ?? $this->observer->active_view->getName(); $attributes = $data['attributes']->getAttributes(); return $this->registry diff --git a/tests/HookableTest.php b/tests/HookableTest.php index 0662671..00256ea 100644 --- a/tests/HookableTest.php +++ b/tests/HookableTest.php @@ -137,8 +137,10 @@ public function test_view_hooks_can_be_registered(): void // know that registration order doesn't matter View::hook('demo', 'header', fn() => 'Hello Skyler!', Hook::LOW_PRIORITY); View::hook('demo', 'header', view('hello', ['name' => 'Bogdan'])); + View::hook('demo', 'header', fn() => view('hello', ['name' => 'Chris'])); View::hook('demo', 'footer', new HtmlString('Hello Chris!')); View::hook('demo', 'footer', view('hello', ['name' => 'Caleb'])); + View::hook('demo', 'footer', fn() => view('hello', ['name' => 'Daniel'])); View::hook('demo', 'footer', function($context) { $this->assertEquals('bar', $context->foo); @@ -148,10 +150,12 @@ public function test_view_hooks_can_be_registered(): void $view->assertSeeTextInOrder([ 'Hello Bogdan!', + 'Hello Chris!', 'Hello Skyler!', 'This is a demo', 'Hello Chris!', 'Hello Caleb!', + 'Hello Daniel!', ]); } }