diff --git a/src/Components/Lazy.php b/src/Components/Lazy.php index 6b0b5f73..48b37c24 100644 --- a/src/Components/Lazy.php +++ b/src/Components/Lazy.php @@ -2,6 +2,7 @@ namespace ProtoneMedia\Splade\Components; +use Illuminate\Support\Str; use Illuminate\View\Component; use ProtoneMedia\Splade\SpladeCore; @@ -25,9 +26,14 @@ public function __construct( */ public function render() { + $key = Str::random(); + return $this->splade->isLazyRequest() - ? '{{ $slot }}' - : view('splade::functional.lazy', [ + ? implode([ + '', + '{{ $slot }}', + '', + ]) : view('splade::functional.lazy', [ 'name' => $this->splade->newLazyComponentKey(), ]); } diff --git a/src/Components/Rehydrate.php b/src/Components/Rehydrate.php index 1eacd0bf..d84e552f 100644 --- a/src/Components/Rehydrate.php +++ b/src/Components/Rehydrate.php @@ -2,6 +2,7 @@ namespace ProtoneMedia\Splade\Components; +use Illuminate\Support\Str; use Illuminate\View\Component; use ProtoneMedia\Splade\SpladeCore; @@ -28,9 +29,14 @@ public function __construct( */ public function render() { + $key = Str::random(); + return $this->splade->isRehydrateRequest() - ? '{{ $slot }}' - : view('splade::functional.rehydrate', [ + ? implode([ + '', + '{{ $slot }}', + '', + ]) : view('splade::functional.rehydrate', [ 'name' => $this->splade->newRehydrateComponentKey(), 'on' => $this->on, ]); diff --git a/src/Facades/Splade.php b/src/Facades/Splade.php index 8335d024..655a9d29 100644 --- a/src/Facades/Splade.php +++ b/src/Facades/Splade.php @@ -23,6 +23,7 @@ * @method static EventRedirectFactory redirectOnEvent() * @method static EventRefresh refreshOnEvent() * @method static int getLazyComponentKey() + * @method static int getRehydrateComponentKey() * @method static mixed onInit($value) * @method static mixed onLazy($value) * @method static self defaultToast(callable $toastFactory): diff --git a/src/Http/PrepareViewWithLazyComponents.php b/src/Http/PrepareViewWithLazyComponents.php index bb645008..d05765c1 100644 --- a/src/Http/PrepareViewWithLazyComponents.php +++ b/src/Http/PrepareViewWithLazyComponents.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Event; +use Illuminate\Support\Str; use Illuminate\View\View; use ProtoneMedia\Splade\Components\SpladeComponent; use ProtoneMedia\Splade\Facades\Splade; @@ -28,18 +29,8 @@ public function registerMacro(): self // Find the lazy components within the view preg_match_all(PrepareViewWithLazyComponents::regexForTag(SpladeComponent::tag('lazy')), $view, $matches); - $lazyComponents = collect($matches[0] ?? []); - - // If this is a lazy request, get the right component and render it. - if (Splade::isLazyRequest()) { - return Blade::render( - $lazyComponents->get(Splade::getLazyComponentKey()), - $this->getData() - ); - } - - // Otherwise, replace all lazy components with just the placeholder - $lazyComponents->each(function (string $lazyComponent, $key) use ($matches, &$view) { + // Replace all lazy components with just the placeholder + collect($matches[0] ?? [])->each(function (string $lazyComponent, $key) use ($matches, &$view) { preg_match_all(PrepareViewWithLazyComponents::regexForTag('x-slot:placeholder'), $lazyComponent, $placeholderMatches); $view = str_replace($lazyComponent, implode('', [ @@ -55,6 +46,30 @@ public function registerMacro(): self return $this; } + /** + * Grabs the lazy-component from the rendered content and returns it. + * + * @param string $content + * @param int $componentKey + * @return string + */ + public static function extractComponent(string $content, int $componentKey): string + { + preg_match_all('/START-SPLADE-LAZY-(\w+)-->/', $content, $matches); + + return (string) collect($matches[1] ?? []) + ->mapWithKeys(function (string $name, $key) use ($content) { + $rehydrate = Str::between( + $content, + "", + "" + ); + + return [$key => trim($rehydrate)]; + }) + ->get($componentKey); + } + /** * Registers an event handler for the 'creating:' event, which is fired before * rendering a Blade template. This way we can, based on the request, replace @@ -64,6 +79,11 @@ public function registerMacro(): self */ public function registerEventListener(): self { + if (Splade::isLazyRequest()) { + // Render normally + return $this; + } + $listener = $this->interceptCreatingViews(SpladeComponent::tag('lazy'), function (View $view) { return $view->renderWithPreparedLazyComponents(); }); diff --git a/src/Http/PrepareViewWithRehydrateComponents.php b/src/Http/PrepareViewWithRehydrateComponents.php index 33f9d7bb..8c48d955 100644 --- a/src/Http/PrepareViewWithRehydrateComponents.php +++ b/src/Http/PrepareViewWithRehydrateComponents.php @@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Blade; use Illuminate\Support\Facades\Event; +use Illuminate\Support\Str; use Illuminate\View\View; use ProtoneMedia\Splade\Components\SpladeComponent; use ProtoneMedia\Splade\Facades\Splade; @@ -28,18 +29,8 @@ public function registerMacro(): self // Find the rehydrate components within the view preg_match_all(PrepareViewWithRehydrateComponents::regexForTag(SpladeComponent::tag('rehydrate')), $view, $matches); - $rehydrateComponents = collect($matches[0] ?? []); - - // If this is a rehydrate request, get the right component and render it. - if (Splade::isRehydrateRequest()) { - return Blade::render( - $rehydrateComponents->get(Splade::getRehydrateComponentKey()), - $this->getData() - ); - } - - // Otherwise, extract the (optional) placeholder - $rehydrateComponents->each(function (string $rehydrateComponent) use (&$view) { + // Extract the (optional) placeholder + collect($matches[0] ?? [])->each(function (string $rehydrateComponent) use (&$view) { preg_match_all(PrepareViewWithRehydrateComponents::regexForTag('x-slot:placeholder'), $rehydrateComponent, $placeholderMatches); $placeholder = $placeholderMatches[0][0] ?? ''; @@ -60,6 +51,30 @@ public function registerMacro(): self return $this; } + /** + * Grabs the rehydrate-component from the rendered content and returns it. + * + * @param string $content + * @param int $componentKey + * @return string + */ + public static function extractComponent(string $content, int $componentKey): string + { + preg_match_all('/START-SPLADE-REHYDRATE-(\w+)-->/', $content, $matches); + + return (string) collect($matches[1] ?? []) + ->mapWithKeys(function (string $name, $key) use ($content) { + $rehydrate = Str::between( + $content, + "", + "" + ); + + return [$key => trim($rehydrate)]; + }) + ->get($componentKey); + } + /** * Registers an event handler for the 'creating:' event, which is fired before * rendering a Blade template. This way we can, based on the request, replace @@ -69,6 +84,11 @@ public function registerMacro(): self */ public function registerEventListener(): self { + if (Splade::isRehydrateRequest()) { + // Render normally + return $this; + } + $listener = $this->interceptCreatingViews(SpladeComponent::tag('rehydrate'), function (View $view) { return $view->renderWithPreparedRehydrateComponents(); }); diff --git a/src/Http/SpladeMiddleware.php b/src/Http/SpladeMiddleware.php index 7521171c..f5bb2a9c 100644 --- a/src/Http/SpladeMiddleware.php +++ b/src/Http/SpladeMiddleware.php @@ -139,6 +139,12 @@ private function handleSpladeRequest(Request $request, Response $response, objec // Extract the Dynamic Content, we'll return that separately so Vue can handle it. [$content, $dynamics] = static::extractDynamicsFromContent($content); + if ($this->splade->isLazyRequest()) { + $content = PrepareViewWithLazyComponents::extractComponent($content, $this->splade->getLazyComponentKey()) ?: $content; + } elseif ($this->splade->isRehydrateRequest()) { + $content = PrepareViewWithRehydrateComponents::extractComponent($content, $this->splade->getRehydrateComponentKey()); + } + return $response->setContent(json_encode([ // If this is Modal request, extract the content... 'html' => $this->splade->isModalRequest() ? $this->parseModalContent($content) : $content,