From ddbf62635626399f8fe035d714bd3663ddf8dd23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Glawaty?= Date: Fri, 1 Dec 2023 06:17:12 +0100 Subject: [PATCH] Banner options, Native lazy loading - added ability to provide custom options for each banner through Renderer or Latte macro - added support for native lazy loading - updated default templates due to implementation of custom banner options and native lazy loading - added and fixed tests - updated docs - updated CHANGELOG --- CHANGELOG.md | 9 ++ docs/integration-with-nette-framework.md | 10 +- docs/integration-without-framework.md | 58 +++++++- src/Bridge/Latte/RendererProvider.php | 7 +- src/Renderer/Latte/Helpers.php | 42 ++++++ src/Renderer/Latte/LatteRendererBridge.php | 27 ++-- .../Latte/Templates/ClientSideTemplate.php | 14 +- .../Latte/Templates/MultipleTemplate.php | 8 +- .../Latte/Templates/NotFoundTemplate.php | 8 +- .../Latte/Templates/RandomTemplate.php | 8 +- .../Latte/Templates/SingleTemplate.php | 8 +- src/Renderer/Latte/Templates/clientSide.latte | 4 +- .../Latte/Templates/contents.fragment.latte | 5 +- src/Renderer/Latte/Templates/multiple.latte | 15 ++- src/Renderer/Latte/Templates/notFound.latte | 4 +- src/Renderer/Latte/Templates/random.latte | 6 +- src/Renderer/Latte/Templates/single.latte | 6 +- src/Renderer/Phtml/Helpers.php | 18 +++ src/Renderer/Phtml/PhtmlRendererBridge.php | 20 +-- src/Renderer/Phtml/Templates/clientSide.phtml | 3 +- .../Phtml/Templates/contents.fragment.phtml | 6 +- src/Renderer/Phtml/Templates/multiple.phtml | 8 +- src/Renderer/Phtml/Templates/notFound.phtml | 3 +- src/Renderer/Phtml/Templates/random.phtml | 3 +- src/Renderer/Phtml/Templates/single.phtml | 3 +- src/Renderer/Renderer.php | 19 ++- src/Renderer/RendererBridgeInterface.php | 15 ++- src/Renderer/RendererInterface.php | 6 +- tests/Bridge/Latte/RendererProviderTest.php | 63 +++++++-- .../Latte/LatteRendererBridgeTest.php | 15 ++- .../Phtml/PhtmlRendererBridgeTest.php | 15 ++- tests/Renderer/RendererTest.php | 18 +-- .../renderer/client-side/data-provider.php | 19 ++- .../renderer/client-side/fullFeatured.html | 1 + .../renderer/client-side/withLazyLoading.html | 1 + .../withResourcesAndAttributes.html | 1 - .../renderer/multiple/data-provider.php | 124 +++++++++++------- ...leBannersFullFeatured.withLazyLoading.html | 33 +++++ ...llFeatured.withLazyLoadingFromOffset1.html | 33 +++++ .../renderer/not-found/data-provider.php | 10 ++ .../not-found/notFound.withLazyLoading.html | 1 + ...faultImageContentOnly.withLazyLoading.html | 11 ++ .../random/bannerWithMultipleContents.html | 6 +- .../renderer/random/data-provider.php | 35 +++++ ...faultImageContentOnly.withLazyLoading.html | 11 ++ .../single/bannerWithMultipleContents.html | 6 +- .../renderer/single/data-provider.php | 35 +++++ 47 files changed, 616 insertions(+), 165 deletions(-) create mode 100644 src/Renderer/Latte/Helpers.php create mode 100644 tests/resources/renderer/client-side/fullFeatured.html create mode 100644 tests/resources/renderer/client-side/withLazyLoading.html delete mode 100644 tests/resources/renderer/client-side/withResourcesAndAttributes.html create mode 100644 tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoading.html create mode 100644 tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoadingFromOffset1.html create mode 100644 tests/resources/renderer/not-found/notFound.withLazyLoading.html create mode 100644 tests/resources/renderer/random/bannerWithDefaultImageContentOnly.withLazyLoading.html create mode 100644 tests/resources/renderer/single/bannerWithDefaultImageContentOnly.withLazyLoading.html diff --git a/CHANGELOG.md b/CHANGELOG.md index eb8b4ab..de01026 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +## 1.1.0 - 2023-12-01 +### Added +- Added ability to provide custom options for each banner through Renderer or Latte macro. +- Added support for native lazy loading. Feature can be enabled through banner options `'loading' => 'lazy'` and `'loading-offset' => ` (for multiple positions only). + +### Changed +- Updated default templates due to implementation of custom banner options and native lazy loading. +- Updated docs. + ## 1.0.0 - 2023-11-30 ### Added diff --git a/docs/integration-with-nette-framework.md b/docs/integration-with-nette-framework.md index eb86834..63be7ce 100644 --- a/docs/integration-with-nette-framework.md +++ b/docs/integration-with-nette-framework.md @@ -116,8 +116,16 @@ extensions: Now the macro `{banner}` is available in the application and can be used in templates: ```latte +{* + Available arguments are: + * `resources` - An array of banner resources, + * `options` - An array of custom options. Can be also used for enabling native lazy loading. + * `attributes` - An array of HTML attributes + * `mode` - Allows to switch a rendering mode. See the "Using multiple rendering modes" section below +*} + {banner homepage.top} -{banner homepage.promo, resources: ['role' => 'guest']} +{banner homepage.promo, resources: ['role' => 'guest'], options: ['loading' => 'lazy']} {banner homepage.bottom, attributes: ['class' => 'my-awesome-class']} ``` diff --git a/docs/integration-without-framework.md b/docs/integration-without-framework.md index 26d7915..b22e703 100644 --- a/docs/integration-without-framework.md +++ b/docs/integration-without-framework.md @@ -10,6 +10,7 @@ * [Fetching banners](#fetching-banners) * [Rendering banners](#rendering-banners) * [Rendering banners on the client side](#rendering-banners-on-the-client-side) + * [Lazy loading of image banners](#lazy-loading-of-image-banners) * [Templates overwriting](#templates-overwriting) * [Rendering banners using Latte](#rendering-banners-using-latte) * [Latte templating system integration](#latte-templating-system-integration) @@ -165,7 +166,14 @@ echo $renderer->render($response->getPosition('homepage.top')); The second argument can be used to pass an array of attributes to be contained in the banner's HTML wrapper element. ```php -echo $renderer->render($response->getPosition('homepage.top', ['class' => 'my-awesome-class'])); +echo $renderer->render($response->getPosition('homepage.top'), ['class' => 'my-awesome-class']); +``` + +The third argument can be used to provide custom options. +These options are available in the banner templates and will also be available to the JavaScript client, so they can be accessed in event handlers. + +```php +echo $renderer->render($response->getPosition('homepage.top'), [], ['customOption' => 'customValue']); ``` ### Rendering banners on the client side @@ -184,6 +192,42 @@ echo $renderer->renderClientSide(new Position('homepage.promo'), ['class' => 'my Banners rendered in this way will be loaded by the JavaScript client when its `attachBanners()` function is called. +### Lazy loading of image banners + +The default client templates support [native lazy loading](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading#images_and_iframes) of images. +To activate lazy loading the option `'loading' => 'lazy'` must be passed to the renderer. + +```php +# server-side rendering: +echo $renderer->render($response->getPosition('homepage.top'), [], [ + 'loading' => 'lazy', +]); + +# client-side rendering: +echo $renderer->renderClientSide(new Position('homepage.top'), [], [ + 'loading' => 'lazy', +]); +``` + +A special case is a position of type `multiple`, where it may be desirable to lazily load all banners except the first. +This can be achieved by adding the option `loading-offset`, whose value specifies from which banner the attribute `loading` should be rendered. + +```php +# server-side rendering: +echo $renderer->render($response->getPosition('homepage.top'), [], [ + 'loading' => 'lazy', + 'loading-offset' => 1, +]); + +# client-side rendering: +echo $renderer->renderClientSide(new Position('homepage.top'), [], [ + 'loading' => 'lazy', + 'loading-offset' => 1, +]); +``` + +If you prefer a different implementation of lazy loading, it is possible to use own templates instead of the default ones and integrate a different solution in these templates. + ### Templates overwriting The default templates are written as `.phtml` templates and can be found [here](../src/Renderer/Phtml/Templates). Templates can be also overwritten: @@ -211,7 +255,7 @@ new Templates([ Templates::Multiple => '/multiple.phtml', # for positions with the display type "multiple" Templates::Random => '/random.phtml', # for positions with the display type "random" Templates::NotFound => '/notFound.phtml', # for positions that were not found - Templates::ClientSide => '/clientSide.phtml', + Templates::ClientSide => '/clientSide.phtml', # for positions that should be rendered by JS client ]) ``` @@ -276,8 +320,16 @@ $engine->render(__DIR__ . '/template.latte'); ```latte {* ./template.latte *} +{* + Available arguments are: + * `resources` - An array of banner resources, + * `options` - An array of custom options. Can be also used for enabling native lazy loading. + * `attributes` - An array of HTML attributes + * `mode` - Allows to switch a rendering mode. See the "Using multiple rendering modes" section below +*} + {banner homepage.top} -{banner homepage.promo, resources: ['role' => 'guest']} +{banner homepage.promo, resources: ['role' => 'guest'], options: ['loading' => 'lazy']} {banner homepage.bottom, attributes: ['class' => 'my-awesome-class']} ``` diff --git a/src/Bridge/Latte/RendererProvider.php b/src/Bridge/Latte/RendererProvider.php index 901b638..2120040 100644 --- a/src/Bridge/Latte/RendererProvider.php +++ b/src/Bridge/Latte/RendererProvider.php @@ -37,6 +37,7 @@ final class RendererProvider private const OptionResources = 'resources'; private const OptionAttributes = 'attributes'; private const OptionMode = 'mode'; + private const OptionOptions = 'options'; private AmpClientInterface $client; @@ -279,8 +280,9 @@ private function renderPosition(ResponsePosition $position, array $options): str { try { $elementAttributes = (array) ($options[self::OptionAttributes] ?? []); + $bannerOptions = (array) ($options[self::OptionOptions] ?? []); - return $this->renderer->render($position, $elementAttributes); + return $this->renderer->render($position, $elementAttributes, $bannerOptions); } catch (RendererException $e) { if ($this->debugMode) { throw $e; @@ -303,8 +305,9 @@ private function renderClientSidePosition(RequestPosition $position, array $opti { try { $elementAttributes = (array) ($options[self::OptionAttributes] ?? []); + $bannerOptions = (array) ($options[self::OptionOptions] ?? []); - return $this->renderer->renderClientSide($position, $elementAttributes); + return $this->renderer->renderClientSide($position, $elementAttributes, $bannerOptions); } catch (RendererException $e) { if ($this->debugMode) { throw $e; diff --git a/src/Renderer/Latte/Helpers.php b/src/Renderer/Latte/Helpers.php new file mode 100644 index 0000000..a46379b --- /dev/null +++ b/src/Renderer/Latte/Helpers.php @@ -0,0 +1,42 @@ + + */ + public static function createResourceAttributes(RequestPosition $position): array + { + $attributes = []; + + foreach ($position->getResources() as $resource) { + $attributes['data-amp-resource-' . $resource->getCode()] = implode(',', $resource->getValues()); + } + + return $attributes; + } + + /** + * @param array $options + * + * @return array + */ + public static function createOptionAttributes(array $options): array + { + $attributes = []; + + foreach ($options as $name => $value) { + $attributes['data-amp-option-' . $name] = $value; + } + + return $attributes; + } +} diff --git a/src/Renderer/Latte/LatteRendererBridge.php b/src/Renderer/Latte/LatteRendererBridge.php index e0a5250..7fce64a 100644 --- a/src/Renderer/Latte/LatteRendererBridge.php +++ b/src/Renderer/Latte/LatteRendererBridge.php @@ -15,7 +15,6 @@ use SixtyEightPublishers\AmpClient\Request\ValueObject\Position as RequestPosition; use SixtyEightPublishers\AmpClient\Response\ValueObject\Banner; use SixtyEightPublishers\AmpClient\Response\ValueObject\Position as ResponsePosition; -use function implode; final class LatteRendererBridge implements RendererBridgeInterface { @@ -52,49 +51,43 @@ public function overrideTemplates(Templates $templates): self return $renderer; } - public function renderNotFound(ResponsePosition $position, array $elementAttributes = []): string + public function renderNotFound(ResponsePosition $position, array $elementAttributes = [], array $options = []): string { return $this->getLatte()->renderToString( $this->templates->getTemplateFile(Templates::NotFound), - new NotFoundTemplate($position, $elementAttributes), + new NotFoundTemplate($position, $elementAttributes, $options), ); } - public function renderSingle(ResponsePosition $position, ?Banner $banner, array $elementAttributes = []): string + public function renderSingle(ResponsePosition $position, ?Banner $banner, array $elementAttributes = [], array $options = []): string { return $this->getLatte()->renderToString( $this->templates->getTemplateFile(Templates::Single), - new SingleTemplate($position, $banner, $elementAttributes), + new SingleTemplate($position, $banner, $elementAttributes, $options), ); } - public function renderRandom(ResponsePosition $position, ?Banner $banner, array $elementAttributes = []): string + public function renderRandom(ResponsePosition $position, ?Banner $banner, array $elementAttributes = [], array $options = []): string { return $this->getLatte()->renderToString( $this->templates->getTemplateFile(Templates::Random), - new RandomTemplate($position, $banner, $elementAttributes), + new RandomTemplate($position, $banner, $elementAttributes, $options), ); } - public function renderMultiple(ResponsePosition $position, array $banners, array $elementAttributes = []): string + public function renderMultiple(ResponsePosition $position, array $banners, array $elementAttributes = [], array $options = []): string { return $this->getLatte()->renderToString( $this->templates->getTemplateFile(Templates::Multiple), - new MultipleTemplate($position, $banners, $elementAttributes), + new MultipleTemplate($position, $banners, $elementAttributes, $options), ); } - public function renderClientSide(RequestPosition $position, array $elementAttributes = []): string + public function renderClientSide(RequestPosition $position, array $elementAttributes = [], array $options = []): string { - $resourceAttributes = []; - - foreach ($position->getResources() as $resource) { - $resourceAttributes['data-amp-resource-' . $resource->getCode()] = implode(',', $resource->getValues()); - } - return $this->getLatte()->renderToString( $this->templates->getTemplateFile(Templates::ClientSide), - new ClientSideTemplate($position, $resourceAttributes, $elementAttributes), + new ClientSideTemplate($position, $elementAttributes, $options), ); } diff --git a/src/Renderer/Latte/Templates/ClientSideTemplate.php b/src/Renderer/Latte/Templates/ClientSideTemplate.php index 2c273dc..3609592 100644 --- a/src/Renderer/Latte/Templates/ClientSideTemplate.php +++ b/src/Renderer/Latte/Templates/ClientSideTemplate.php @@ -10,23 +10,23 @@ final class ClientSideTemplate { public Position $position; - /** @var array */ - public array $resourceAttributes; - /** @var array */ public array $elementAttributes; + /** @var array */ + public array $options; + /** - * @param array $resourceAttributes * @param array $elementAttributes + * @param array $options */ public function __construct( Position $position, - array $resourceAttributes, - array $elementAttributes + array $elementAttributes, + array $options ) { $this->position = $position; - $this->resourceAttributes = $resourceAttributes; $this->elementAttributes = $elementAttributes; + $this->options = $options; } } diff --git a/src/Renderer/Latte/Templates/MultipleTemplate.php b/src/Renderer/Latte/Templates/MultipleTemplate.php index 6eb4ebc..58184d3 100644 --- a/src/Renderer/Latte/Templates/MultipleTemplate.php +++ b/src/Renderer/Latte/Templates/MultipleTemplate.php @@ -17,17 +17,23 @@ final class MultipleTemplate /** @var array */ public array $elementAttributes; + /** @var array */ + public array $options; + /** * @param array $banners * @param array $elementAttributes + * @param array $options */ public function __construct( Position $position, array $banners, - array $elementAttributes + array $elementAttributes, + array $options ) { $this->position = $position; $this->banners = $banners; $this->elementAttributes = $elementAttributes; + $this->options = $options; } } diff --git a/src/Renderer/Latte/Templates/NotFoundTemplate.php b/src/Renderer/Latte/Templates/NotFoundTemplate.php index 43fa773..55bf4a7 100644 --- a/src/Renderer/Latte/Templates/NotFoundTemplate.php +++ b/src/Renderer/Latte/Templates/NotFoundTemplate.php @@ -13,14 +13,20 @@ final class NotFoundTemplate /** @var array */ public array $elementAttributes; + /** @var array */ + public array $options; + /** * @param array $elementAttributes + * @param array $options */ public function __construct( Position $position, - array $elementAttributes + array $elementAttributes, + array $options ) { $this->position = $position; $this->elementAttributes = $elementAttributes; + $this->options = $options; } } diff --git a/src/Renderer/Latte/Templates/RandomTemplate.php b/src/Renderer/Latte/Templates/RandomTemplate.php index 4105aa3..4e1d5ca 100644 --- a/src/Renderer/Latte/Templates/RandomTemplate.php +++ b/src/Renderer/Latte/Templates/RandomTemplate.php @@ -16,16 +16,22 @@ final class RandomTemplate /** @var array */ public array $elementAttributes; + /** @var array */ + public array $options; + /** * @param array $elementAttributes + * @param array $options */ public function __construct( Position $position, ?Banner $banner, - array $elementAttributes + array $elementAttributes, + array $options ) { $this->position = $position; $this->banner = $banner; $this->elementAttributes = $elementAttributes; + $this->options = $options; } } diff --git a/src/Renderer/Latte/Templates/SingleTemplate.php b/src/Renderer/Latte/Templates/SingleTemplate.php index 1b11331..3dc91e0 100644 --- a/src/Renderer/Latte/Templates/SingleTemplate.php +++ b/src/Renderer/Latte/Templates/SingleTemplate.php @@ -16,16 +16,22 @@ final class SingleTemplate /** @var array */ public array $elementAttributes; + /** @var array */ + public array $options; + /** * @param array $elementAttributes + * @param array $options */ public function __construct( Position $position, ?Banner $banner, - array $elementAttributes + array $elementAttributes, + array $options ) { $this->position = $position; $this->banner = $banner; $this->elementAttributes = $elementAttributes; + $this->options = $options; } } diff --git a/src/Renderer/Latte/Templates/clientSide.latte b/src/Renderer/Latte/Templates/clientSide.latte index feeef15..c9a91d9 100644 --- a/src/Renderer/Latte/Templates/clientSide.latte +++ b/src/Renderer/Latte/Templates/clientSide.latte @@ -1,5 +1,7 @@ {templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\ClientSideTemplate} +{var $helpers = SixtyEightPublishers\AmpClient\Renderer\Latte\Helpers::class} +
+ n:attr="array_merge($helpers::createResourceAttributes($position), $helpers::createOptionAttributes($options), $elementAttributes)">
diff --git a/src/Renderer/Latte/Templates/contents.fragment.latte b/src/Renderer/Latte/Templates/contents.fragment.latte index 05bd344..7122925 100644 --- a/src/Renderer/Latte/Templates/contents.fragment.latte +++ b/src/Renderer/Latte/Templates/contents.fragment.latte @@ -1,5 +1,6 @@ -{varType SixtyEightPublishers\AmpClient\Request\ValueObject\Position $position} +{varType SixtyEightPublishers\AmpClient\Response\ValueObject\Position $position} {varType SixtyEightPublishers\AmpClient\Response\ValueObject\Banner|null $banner} +{varType array $options} {foreach $banner->getContents() as $content} {if $content instanceof SixtyEightPublishers\AmpClient\Response\ValueObject\ImageContent} @@ -19,7 +20,7 @@ src="{$content->getSrc()}" sizes="{$content->getSizes()}" alt="{$content->getAlt()}" - n:attr="title => '' !== $content->getTitle() ? $content->getTitle() : null"> + n:attr="title => '' !== $content->getTitle() ? $content->getTitle() : null, loading => $options['loading'] ?? null"> {elseif $content instanceof SixtyEightPublishers\AmpClient\Response\ValueObject\HtmlContent} diff --git a/src/Renderer/Latte/Templates/multiple.latte b/src/Renderer/Latte/Templates/multiple.latte index 1a5d25b..0fe9961 100644 --- a/src/Renderer/Latte/Templates/multiple.latte +++ b/src/Renderer/Latte/Templates/multiple.latte @@ -1,16 +1,25 @@ {templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\MultipleTemplate} +{var $helpers = SixtyEightPublishers\AmpClient\Renderer\Latte\Helpers::class} +
+ n:attr="array_merge($helpers::createOptionAttributes($options), $elementAttributes)"> {do $banners = array_filter($banners, fn(SixtyEightPublishers\AmpClient\Response\ValueObject\Banner $banner) => 0 < count($banner->getContents()))}
-
- {include 'contents.fragment.latte', position: $position, banner: $banner} + + {var $optionsCopy = $options} + + {if isset($optionsCopy['loading']) && $index < ((int) ($optionsCopy['loading-offset'] ?? 0))} + {do $optionsCopy['loading'] = null} + {/if} + + {include 'contents.fragment.latte', position: $position, banner: $banner, options: $optionsCopy}
diff --git a/src/Renderer/Latte/Templates/notFound.latte b/src/Renderer/Latte/Templates/notFound.latte index a7b9b2c..8e54b40 100644 --- a/src/Renderer/Latte/Templates/notFound.latte +++ b/src/Renderer/Latte/Templates/notFound.latte @@ -1,6 +1,8 @@ {templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\NotFoundTemplate} +{var $helpers = SixtyEightPublishers\AmpClient\Renderer\Latte\Helpers::class} +
+ n:attr="array_merge($helpers::createOptionAttributes($options), $elementAttributes)">
diff --git a/src/Renderer/Latte/Templates/random.latte b/src/Renderer/Latte/Templates/random.latte index a8ba859..514dd9d 100644 --- a/src/Renderer/Latte/Templates/random.latte +++ b/src/Renderer/Latte/Templates/random.latte @@ -1,12 +1,14 @@ {templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\RandomTemplate} +{var $helpers = SixtyEightPublishers\AmpClient\Renderer\Latte\Helpers::class} +
+ n:attr="array_merge($helpers::createOptionAttributes($options), $elementAttributes)">
- {include 'contents.fragment.latte', position: $position, banner: $banner} + {include 'contents.fragment.latte', position: $position, banner: $banner, options: $options}
diff --git a/src/Renderer/Latte/Templates/single.latte b/src/Renderer/Latte/Templates/single.latte index 522cb0b..7591821 100644 --- a/src/Renderer/Latte/Templates/single.latte +++ b/src/Renderer/Latte/Templates/single.latte @@ -1,12 +1,14 @@ {templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\SingleTemplate} +{var $helpers = SixtyEightPublishers\AmpClient\Renderer\Latte\Helpers::class} +
+ n:attr="array_merge($helpers::createOptionAttributes($options), $elementAttributes)">
- {include 'contents.fragment.latte', position: $position, banner: $banner} + {include 'contents.fragment.latte', position: $position, banner: $banner, options: $options}
diff --git a/src/Renderer/Phtml/Helpers.php b/src/Renderer/Phtml/Helpers.php index dba40c3..49aa33b 100644 --- a/src/Renderer/Phtml/Helpers.php +++ b/src/Renderer/Phtml/Helpers.php @@ -11,6 +11,8 @@ final class Helpers { + private function __construct() {} + /** * @param mixed $string */ @@ -60,4 +62,20 @@ public static function printAttributes(array $attributes): string return '' !== $attrs ? (' ' . $attrs) : ''; } + + /** + * @param array $array + * + * @return array + */ + public static function prefixKeys(array $array, string $prefix): array + { + $attributes = []; + + foreach ($array as $key => $value) { + $attributes[$prefix . $key] = $value; + } + + return $attributes; + } } diff --git a/src/Renderer/Phtml/PhtmlRendererBridge.php b/src/Renderer/Phtml/PhtmlRendererBridge.php index 9031b48..4b60b47 100644 --- a/src/Renderer/Phtml/PhtmlRendererBridge.php +++ b/src/Renderer/Phtml/PhtmlRendererBridge.php @@ -38,11 +38,11 @@ public function overrideTemplates(Templates $templates): self /** * @throws Throwable */ - public function renderNotFound(ResponsePosition $position, array $elementAttributes = []): string + public function renderNotFound(ResponsePosition $position, array $elementAttributes = [], array $options = []): string { $filename = $this->templates->getTemplateFile(Templates::NotFound); - return OutputBuffer::capture(function () use ($filename, $position, $elementAttributes) { + return OutputBuffer::capture(function () use ($filename, $position, $elementAttributes, $options) { require $filename; }); } @@ -50,11 +50,11 @@ public function renderNotFound(ResponsePosition $position, array $elementAttribu /** * @throws Throwable */ - public function renderSingle(ResponsePosition $position, ?Banner $banner, array $elementAttributes = []): string + public function renderSingle(ResponsePosition $position, ?Banner $banner, array $elementAttributes = [], array $options = []): string { $filename = $this->templates->getTemplateFile(Templates::Single); - return OutputBuffer::capture(function () use ($filename, $position, $banner, $elementAttributes) { + return OutputBuffer::capture(function () use ($filename, $position, $banner, $elementAttributes, $options) { require $filename; }); } @@ -62,11 +62,11 @@ public function renderSingle(ResponsePosition $position, ?Banner $banner, array /** * @throws Throwable */ - public function renderRandom(ResponsePosition $position, ?Banner $banner, array $elementAttributes = []): string + public function renderRandom(ResponsePosition $position, ?Banner $banner, array $elementAttributes = [], array $options = []): string { $filename = $this->templates->getTemplateFile(Templates::Random); - return OutputBuffer::capture(function () use ($filename, $position, $banner, $elementAttributes) { + return OutputBuffer::capture(function () use ($filename, $position, $banner, $elementAttributes, $options) { require $filename; }); } @@ -74,11 +74,11 @@ public function renderRandom(ResponsePosition $position, ?Banner $banner, array /** * @throws Throwable */ - public function renderMultiple(ResponsePosition $position, array $banners, array $elementAttributes = []): string + public function renderMultiple(ResponsePosition $position, array $banners, array $elementAttributes = [], array $options = []): string { $filename = $this->templates->getTemplateFile(Templates::Multiple); - return OutputBuffer::capture(function () use ($filename, $position, $banners, $elementAttributes) { + return OutputBuffer::capture(function () use ($filename, $position, $banners, $elementAttributes, $options) { require $filename; }); } @@ -86,11 +86,11 @@ public function renderMultiple(ResponsePosition $position, array $banners, array /** * @throws Throwable */ - public function renderClientSide(RequestPosition $position, array $elementAttributes = []): string + public function renderClientSide(RequestPosition $position, array $elementAttributes = [], array $options = []): string { $filename = $this->templates->getTemplateFile(Templates::ClientSide); - return OutputBuffer::capture(function () use ($filename, $position, $elementAttributes) { + return OutputBuffer::capture(function () use ($filename, $position, $elementAttributes, $options) { require $filename; }); } diff --git a/src/Renderer/Phtml/Templates/clientSide.phtml b/src/Renderer/Phtml/Templates/clientSide.phtml index 84c2ea8..9ad1016 100644 --- a/src/Renderer/Phtml/Templates/clientSide.phtml +++ b/src/Renderer/Phtml/Templates/clientSide.phtml @@ -8,8 +8,9 @@ use SixtyEightPublishers\AmpClient\Request\ValueObject\Position; /** @var Position $position */ /** @var array $elementAttributes */ +/** @var array $options */ ?>
getResources() as $resource) : ?>getCode() . '="' . implode(',', $resource->getValues()) . '"' ?> - > + >
diff --git a/src/Renderer/Phtml/Templates/contents.fragment.phtml b/src/Renderer/Phtml/Templates/contents.fragment.phtml index d4e4232..98168c7 100644 --- a/src/Renderer/Phtml/Templates/contents.fragment.phtml +++ b/src/Renderer/Phtml/Templates/contents.fragment.phtml @@ -12,8 +12,9 @@ use SixtyEightPublishers\AmpClient\Renderer\BreakpointStyle\BreakpointStyle; /** @var Position $position */ /** @var ?Banner $banner */ +/** @var array $options */ ?> -getContents() as $content) : ?> +getContents() as $index => $content) : ?> getTitle()) : ?>title="getTitle()) ?>"> + getTitle()) : ?>title="getTitle()) ?>" + loading=""> diff --git a/src/Renderer/Phtml/Templates/multiple.phtml b/src/Renderer/Phtml/Templates/multiple.phtml index 583d717..09d1bb5 100644 --- a/src/Renderer/Phtml/Templates/multiple.phtml +++ b/src/Renderer/Phtml/Templates/multiple.phtml @@ -12,18 +12,22 @@ use SixtyEightPublishers\AmpClient\Renderer\AmpBannerExternalAttribute; /** @var Position $position */ /** @var array $banners */ /** @var array $elementAttributes */ +/** @var array $options */ ?>
> + > 0 < count($banner->getContents())) ?>
- + + + $banner) : ?>
+
diff --git a/src/Renderer/Phtml/Templates/notFound.phtml b/src/Renderer/Phtml/Templates/notFound.phtml index faaf824..56d8cb3 100644 --- a/src/Renderer/Phtml/Templates/notFound.phtml +++ b/src/Renderer/Phtml/Templates/notFound.phtml @@ -9,8 +9,9 @@ use SixtyEightPublishers\AmpClient\Renderer\AmpBannerExternalAttribute; /** @var Position $position */ /** @var array $elementAttributes */ +/** @var array $options */ ?>
> + >
diff --git a/src/Renderer/Phtml/Templates/random.phtml b/src/Renderer/Phtml/Templates/random.phtml index 293ef63..559f792 100644 --- a/src/Renderer/Phtml/Templates/random.phtml +++ b/src/Renderer/Phtml/Templates/random.phtml @@ -12,10 +12,11 @@ use SixtyEightPublishers\AmpClient\Renderer\AmpBannerExternalAttribute; /** @var Position $position */ /** @var ?Banner $banner */ /** @var array $elementAttributes */ +/** @var array $options */ ?>
> + > getContents())): ?>
$elementAttributes */ +/** @var array $options */ ?>
> + > getContents())): ?>
getDisplayType()) { case null: - return $this->rendererBridge->renderNotFound($position, $elementAttributes); + return $this->rendererBridge->renderNotFound( + $position, + $elementAttributes, + $options, + ); case ResponsePosition::DisplayTypeMultiple: return $this->rendererBridge->renderMultiple( $position, $this->bannersResolver->resolveMultiple($position), $elementAttributes, + $options, ); case ResponsePosition::DisplayTypeRandom: return $this->rendererBridge->renderRandom( $position, $this->bannersResolver->resolveRandom($position), $elementAttributes, + $options, ); case ResponsePosition::DisplayTypeSingle: default: @@ -57,6 +63,7 @@ public function render(ResponsePosition $position, array $elementAttributes = [] $position, $this->bannersResolver->resolveSingle($position), $elementAttributes, + $options, ); } } catch (Throwable $e) { @@ -72,10 +79,14 @@ public function render(ResponsePosition $position, array $elementAttributes = [] } } - public function renderClientSide(RequestPosition $position, array $elementAttributes = []): string + public function renderClientSide(RequestPosition $position, array $elementAttributes = [], array $options = []): string { try { - return $this->rendererBridge->renderClientSide($position, $elementAttributes); + return $this->rendererBridge->renderClientSide( + $position, + $elementAttributes, + $options, + ); } catch (Throwable $e) { if ($e instanceof RendererException) { throw $e; diff --git a/src/Renderer/RendererBridgeInterface.php b/src/Renderer/RendererBridgeInterface.php index 5c6288f..9e5233a 100644 --- a/src/Renderer/RendererBridgeInterface.php +++ b/src/Renderer/RendererBridgeInterface.php @@ -14,27 +14,32 @@ public function overrideTemplates(Templates $templates): self; /** * @param array $elementAttributes + * @param array $options */ - public function renderNotFound(ResponsePosition $position, array $elementAttributes = []): string; + public function renderNotFound(ResponsePosition $position, array $elementAttributes = [], array $options = []): string; /** * @param array $elementAttributes + * @param array $options */ - public function renderSingle(ResponsePosition $position, ?Banner $banner, array $elementAttributes = []): string; + public function renderSingle(ResponsePosition $position, ?Banner $banner, array $elementAttributes = [], array $options = []): string; /** * @param array $elementAttributes + * @param array $options */ - public function renderRandom(ResponsePosition $position, ?Banner $banner, array $elementAttributes = []): string; + public function renderRandom(ResponsePosition $position, ?Banner $banner, array $elementAttributes = [], array $options = []): string; /** * @param array $banners * @param array $elementAttributes + * @param array $options */ - public function renderMultiple(ResponsePosition $position, array $banners, array $elementAttributes = []): string; + public function renderMultiple(ResponsePosition $position, array $banners, array $elementAttributes = [], array $options = []): string; /** * @param array $elementAttributes + * @param array $options */ - public function renderClientSide(RequestPosition $position, array $elementAttributes = []): string; + public function renderClientSide(RequestPosition $position, array $elementAttributes = [], array $options = []): string; } diff --git a/src/Renderer/RendererInterface.php b/src/Renderer/RendererInterface.php index d977788..ba51951 100644 --- a/src/Renderer/RendererInterface.php +++ b/src/Renderer/RendererInterface.php @@ -12,15 +12,17 @@ interface RendererInterface { /** * @param array $elementAttributes + * @param array $options * * @throws RendererException */ - public function render(ResponsePosition $position, array $elementAttributes = []): string; + public function render(ResponsePosition $position, array $elementAttributes = [], array $options = []): string; /** * @param array $elementAttributes + * @param array $options * * @throws RendererException */ - public function renderClientSide(RequestPosition $position, array $elementAttributes = []): string; + public function renderClientSide(RequestPosition $position, array $elementAttributes = [], array $options = []): string; } diff --git a/tests/Bridge/Latte/RendererProviderTest.php b/tests/Bridge/Latte/RendererProviderTest.php index dcfb660..fd1a935 100644 --- a/tests/Bridge/Latte/RendererProviderTest.php +++ b/tests/Bridge/Latte/RendererProviderTest.php @@ -57,7 +57,7 @@ public function testInvokingDefaultInstanceWithoutResources(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andReturn(''); Assert::same('', $provider(new stdClass(), 'homepage.top')); @@ -92,7 +92,7 @@ public function testInvokingDefaultInstanceWithSameModeAsDefault(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andReturn(''); Assert::same('', $provider(new stdClass(), 'homepage.top', ['mode' => 'direct'])); @@ -127,12 +127,47 @@ public function testInvokingDefaultInstanceWithAttributes(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, ['class' => 'my-custom-class']) + ->with($responsePosition, ['class' => 'my-custom-class'], []) ->andReturn(''); Assert::same('', $provider(new stdClass(), 'homepage.top', ['attributes' => ['class' => 'my-custom-class']])); } + public function testInvokingDefaultInstanceWithOptions(): void + { + $client = Mockery::mock(AmpClientInterface::class); + $renderer = Mockery::mock(RendererInterface::class); + $provider = new RendererProvider($client, $renderer); + + $responsePosition = new ResponsePosition('1234', 'homepage.top', 'Homepage top', 0, ResponsePosition::DisplayTypeSingle, ResponsePosition::BreakpointTypeMin, []); + $response = new BannersResponse([ + 'homepage.top' => $responsePosition, + ]); + + $client + ->shouldReceive('fetchBanners') + ->once() + ->with(Mockery::type(BannersRequest::class)) + ->andReturnUsing(static function (BannersRequest $request) use ($response): BannersResponse { + Assert::equal( + new BannersRequest([ + new RequestPosition('homepage.top'), + ]), + $request, + ); + + return $response; + }); + + $renderer + ->shouldReceive('render') + ->once() + ->with($responsePosition, [], ['loading' => 'lazy', 'custom' => 'value']) + ->andReturn(''); + + Assert::same('', $provider(new stdClass(), 'homepage.top', ['options' => ['loading' => 'lazy', 'custom' => 'value']])); + } + public function testInvokingDefaultInstanceWithResources(): void { $client = Mockery::mock(AmpClientInterface::class); @@ -165,7 +200,7 @@ public function testInvokingDefaultInstanceWithResources(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andReturn(''); Assert::same( @@ -211,7 +246,7 @@ public function testClientConfigurationEventsShouldBeInvokedBeforeFirstFetch(): $renderer ->shouldReceive('render') ->twice() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andReturn(''); Assert::same('', $provider(new stdClass(), 'homepage.top')); @@ -313,7 +348,7 @@ public function testExceptionShouldBeThrownWhenRendererThrowsExceptionInDebugMod $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andThrow(new RendererException('Test renderer exception')); Assert::exception( @@ -342,7 +377,7 @@ public function testEmptyStringShouldBeReturnedWhenRendererThrowsExceptionInNonD $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andThrow(new RendererException('Test renderer exception')); Assert::same('', $provider(new stdClass(), 'homepage.top')); @@ -369,7 +404,7 @@ public function testExceptionShouldBeLoggedWhenRendererThrowsExceptionInNonDebug $renderer ->shouldReceive('render') ->once() - ->with($responsePosition, []) + ->with($responsePosition, [], []) ->andThrow($exception); $logger @@ -459,11 +494,11 @@ public function testPositionsShouldBeQueuedAndReplacedInStringOutput(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition1, ['class' => 'my-custom-class']) + ->with($responsePosition1, ['class' => 'my-custom-class'], []) ->andReturn('') ->shouldReceive('render') ->once() - ->with($responsePosition2, []) + ->with($responsePosition2, [], []) ->andReturn(''); Assert::same( @@ -551,11 +586,11 @@ public function testPositionsShouldBeQueuedAndReplacedInArrayOutput(): void $renderer ->shouldReceive('render') ->once() - ->with($responsePosition1, ['class' => 'my-custom-class']) + ->with($responsePosition1, ['class' => 'my-custom-class'], []) ->andReturn('') ->shouldReceive('render') ->once() - ->with($responsePosition2, []) + ->with($responsePosition2, [], []) ->andReturn(''); Assert::same( @@ -596,7 +631,7 @@ public function testPositionShouldBeRenderedClientSide(): void $renderer ->shouldReceive('renderClientSide') ->once() - ->with(Mockery::type(RequestPosition::class), []) + ->with(Mockery::type(RequestPosition::class), [], []) ->andReturnUsing(static function (RequestPosition $position) use ($requestPosition): string { Assert::equal($requestPosition, $position); @@ -634,7 +669,7 @@ public function testPositionShouldBeRenderedClientSideWithAlternativeMode(): voi $renderer ->shouldReceive('renderClientSide') ->once() - ->with(Mockery::type(RequestPosition::class), []) + ->with(Mockery::type(RequestPosition::class), [], []) ->andReturnUsing(static function (RequestPosition $position) use ($requestPosition): string { Assert::equal($requestPosition, $position); diff --git a/tests/Renderer/Latte/LatteRendererBridgeTest.php b/tests/Renderer/Latte/LatteRendererBridgeTest.php index 8a81229..ccd9082 100644 --- a/tests/Renderer/Latte/LatteRendererBridgeTest.php +++ b/tests/Renderer/Latte/LatteRendererBridgeTest.php @@ -40,11 +40,12 @@ public function testTemplatesShouldBeOverridden(): void public function testNotFoundTemplateRendering( ResponsePosition $position, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = $this->createRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderNotFound($position, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderNotFound($position, $elementAttributes, $options)); } /** @@ -54,11 +55,12 @@ public function testSingleTemplateRendering( ResponsePosition $position, ?Banner $banner, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = $this->createRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderSingle($position, $banner, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderSingle($position, $banner, $elementAttributes, $options)); } /** @@ -68,11 +70,12 @@ public function testRandomTemplateRendering( ResponsePosition $position, ?Banner $banner, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = $this->createRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderRandom($position, $banner, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderRandom($position, $banner, $elementAttributes, $options)); } /** @@ -82,11 +85,12 @@ public function testMultipleTemplateRendering( ResponsePosition $position, array $banners, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = $this->createRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderMultiple($position, $banners, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderMultiple($position, $banners, $elementAttributes, $options)); } /** @@ -95,11 +99,12 @@ public function testMultipleTemplateRendering( public function testClientSideTemplateRendering( RequestPosition $position, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = $this->createRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderClientSide($position, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderClientSide($position, $elementAttributes, $options)); } public function notFoundTemplateDataProvider(): array diff --git a/tests/Renderer/Phtml/PhtmlRendererBridgeTest.php b/tests/Renderer/Phtml/PhtmlRendererBridgeTest.php index 2c70a31..cd5e0a9 100644 --- a/tests/Renderer/Phtml/PhtmlRendererBridgeTest.php +++ b/tests/Renderer/Phtml/PhtmlRendererBridgeTest.php @@ -39,11 +39,12 @@ public function testTemplatesShouldBeOverridden(): void public function testNotFoundTemplateRendering( ResponsePosition $position, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = new PhtmlRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderNotFound($position, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderNotFound($position, $elementAttributes, $options)); } /** @@ -53,11 +54,12 @@ public function testSingleTemplateRendering( ResponsePosition $position, ?Banner $banner, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = new PhtmlRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderSingle($position, $banner, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderSingle($position, $banner, $elementAttributes, $options)); } /** @@ -67,11 +69,12 @@ public function testRandomTemplateRendering( ResponsePosition $position, ?Banner $banner, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = new PhtmlRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderRandom($position, $banner, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderRandom($position, $banner, $elementAttributes, $options)); } /** @@ -81,11 +84,12 @@ public function testMultipleTemplateRendering( ResponsePosition $position, array $banners, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = new PhtmlRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderMultiple($position, $banners, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderMultiple($position, $banners, $elementAttributes, $options)); } /** @@ -94,11 +98,12 @@ public function testMultipleTemplateRendering( public function testClientSideTemplateRendering( RequestPosition $position, array $elementAttributes, + array $options, string $expectationFile ): void { $renderer = new PhtmlRendererBridge(); - AssertHtml::assert($expectationFile, $renderer->renderClientSide($position, $elementAttributes)); + AssertHtml::assert($expectationFile, $renderer->renderClientSide($position, $elementAttributes, $options)); } public function notFoundTemplateDataProvider(): array diff --git a/tests/Renderer/RendererTest.php b/tests/Renderer/RendererTest.php index 6bf4e3a..a3bbe9a 100644 --- a/tests/Renderer/RendererTest.php +++ b/tests/Renderer/RendererTest.php @@ -51,7 +51,7 @@ public function testNotFoundTemplateShouldBeRendered(): void $rendererBridge ->shouldReceive('renderNotFound') ->once() - ->with($position, []) + ->with($position, [], []) ->andReturn('not found'); Assert::same('not found', $renderer->render($position)); @@ -75,7 +75,7 @@ public function testSingleTemplateShouldBeRendered(): void $rendererBridge ->shouldReceive('renderSingle') ->once() - ->with($position, $banner, []) + ->with($position, $banner, [], []) ->andReturn('single'); Assert::same('single', $renderer->render($position)); @@ -99,7 +99,7 @@ public function testRandomTemplateShouldBeRendered(): void $rendererBridge ->shouldReceive('renderRandom') ->once() - ->with($position, $banner, []) + ->with($position, $banner, [], []) ->andReturn('random'); Assert::same('random', $renderer->render($position)); @@ -126,7 +126,7 @@ public function testMultipleTemplateShouldBeRendered(): void $rendererBridge ->shouldReceive('renderMultiple') ->once() - ->with($position, $banners, []) + ->with($position, $banners, [], []) ->andReturn('multiple'); Assert::same('multiple', $renderer->render($position)); @@ -145,7 +145,7 @@ public function testClientSideTemplateShouldBeRendered(): void $rendererBridge ->shouldReceive('renderClientSide') ->once() - ->with($position, []) + ->with($position, [], []) ->andReturn('client-side'); Assert::same('client-side', $renderer->renderClientSide($position)); @@ -162,7 +162,7 @@ public function testRendererExceptionShouldBeThrownOnRenderingWhenBridgeThrowsTh $rendererBridge ->shouldReceive('renderNotFound') ->once() - ->with($position, []) + ->with($position, [], []) ->andThrow(new RendererException('Test exception')); Assert::exception( @@ -183,7 +183,7 @@ public function testRendererExceptionShouldBeThrownOnClientSideRenderingWhenBrid $rendererBridge ->shouldReceive('renderClientSide') ->once() - ->with($position, []) + ->with($position, [], []) ->andThrow(new RendererException('Test exception')); Assert::exception( @@ -204,7 +204,7 @@ public function testRendererExceptionShouldBeThrownOnRenderingWhenBridgeThrowsAn $rendererBridge ->shouldReceive('renderNotFound') ->once() - ->with($position, []) + ->with($position, [], []) ->andThrow(new Exception('Test exception')); Assert::exception( @@ -225,7 +225,7 @@ public function testRendererExceptionShouldBeThrownOnClientSideRenderingWhenBrid $rendererBridge ->shouldReceive('renderClientSide') ->once() - ->with($position, []) + ->with($position, [], []) ->andThrow(new Exception('Test exception')); Assert::exception( diff --git a/tests/resources/renderer/client-side/data-provider.php b/tests/resources/renderer/client-side/data-provider.php index 4f792d3..0f5736c 100644 --- a/tests/resources/renderer/client-side/data-provider.php +++ b/tests/resources/renderer/client-side/data-provider.php @@ -9,6 +9,7 @@ 'Position only' => [ new Position('homepage.top'), [], + [], __DIR__ . '/positionOnly.html', ], 'With resources' => [ @@ -17,6 +18,7 @@ new BannerResource('category', [123, 456]), ]), [], + [], __DIR__ . '/withResources.html', ], 'With attributes' => [ @@ -27,9 +29,18 @@ 'data-custom2' => false, 'data-custom3' => null, ], + [], __DIR__ . '/withAttributes.html', ], - 'With resources and attributes' => [ + 'With lazy loading' => [ + new Position('homepage.top'), + [], + [ + 'loading' => 'lazy', + ], + __DIR__ . '/withLazyLoading.html', + ], + 'Full featured' => [ new Position('homepage.top', [ new BannerResource('role', 'vip'), new BannerResource('category', [123, 456]), @@ -40,6 +51,10 @@ 'data-custom2' => false, 'data-custom3' => null, ], - __DIR__ . '/withResourcesAndAttributes.html', + [ + 'loading' => 'lazy', + 'custom' => 'value', + ], + __DIR__ . '/fullFeatured.html', ], ]; diff --git a/tests/resources/renderer/client-side/fullFeatured.html b/tests/resources/renderer/client-side/fullFeatured.html new file mode 100644 index 0000000..8cbc2b0 --- /dev/null +++ b/tests/resources/renderer/client-side/fullFeatured.html @@ -0,0 +1 @@ +
diff --git a/tests/resources/renderer/client-side/withLazyLoading.html b/tests/resources/renderer/client-side/withLazyLoading.html new file mode 100644 index 0000000..14c2b44 --- /dev/null +++ b/tests/resources/renderer/client-side/withLazyLoading.html @@ -0,0 +1 @@ +
diff --git a/tests/resources/renderer/client-side/withResourcesAndAttributes.html b/tests/resources/renderer/client-side/withResourcesAndAttributes.html deleted file mode 100644 index dfb9490..0000000 --- a/tests/resources/renderer/client-side/withResourcesAndAttributes.html +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/tests/resources/renderer/multiple/data-provider.php b/tests/resources/renderer/multiple/data-provider.php index 699e86c..0696d9f 100644 --- a/tests/resources/renderer/multiple/data-provider.php +++ b/tests/resources/renderer/multiple/data-provider.php @@ -10,11 +10,63 @@ $position = new Position('1234', 'homepage.top', 'Homepage top', 0, Position::DisplayTypeMultiple, Position::BreakpointTypeMin, []); +$fullFeaturedBanners = [ + new Banner('1234', 'Main', 0, null, null, null, [ + new HtmlContent( + null, + '

Small content

', + ), + new ImageContent( + 600, + 'https://www.example.com/main1', + '_blank', + 'Main 1', + 'Main 1', + 'https://img.example.com/1000/main1.png', + 'https://img.example.com/800/main1.png 800w, https://img.example.com/1000/main1.png 1000w', + '(min-width: 1000px) 1000px, 100vw', + [ + new Source('image/avif', 'https://img.example.com/800/main1.avif 800w, https://img.example.com/1000/main1.avif 1000w'), + new Source('image/webp', 'https://img.example.com/800/main1.webp 800w, https://img.example.com/1000/main1.webp 1000w'), + ], + ), + new ImageContent( + 400, + 'https://www.example.com/main2', + '_blank', + 'Main 2', + 'Main 2', + 'https://img.example.com/600/main2.png', + 'https://img.example.com/600/main2.png 600w', + '100vw', + [ + new Source('image/avif', 'https://img.example.com/600/main2.avif 600w'), + new Source('image/webp', 'https://img.example.com/600/main2.webp 600w'), + ], + ), + ]), + new Banner('1235', 'Secondary', 0, null, null, null, [ + new ImageContent( + null, + 'https://www.example.com/secondary1', + null, + 'Secondary 1', + 'Secondary 1', + 'https://img.example.com/1000/secondary1.png', + 'https://img.example.com/800/secondary1.png 800w, https://img.example.com/1000/secondary1.png 1000w', + '(min-width: 1000px) 1000px, 100vw', + [], + ), + ]), + new Banner('1236', 'No contents', 0, null, null, null, []), +]; + return [ 'No banner' => [ $position, [], [], + [], __DIR__ . '/noBanner.html', ], 'No banner with attributes' => [ @@ -26,6 +78,7 @@ 'data-custom2' => false, 'data-custom3' => null, ], + [], __DIR__ . '/noBanner.withAttributes.html', ], 'Single banner without contents' => [ @@ -34,6 +87,7 @@ new Banner('1234', 'Main', 0, null, null, null, []), ], [], + [], __DIR__ . '/singleBannerWithoutContents.html', ], 'Multiple banners without contents' => [ @@ -43,61 +97,33 @@ new Banner('1235', 'Main 2', 0, null, null, null, []), ], [], + [], __DIR__ . '/multipleBannersWithoutContents.html', ], 'Multiple banners - full featured' => [ $position, + $fullFeaturedBanners, + [], + [], + __DIR__ . '/multipleBannersFullFeatured.html', + ], + 'Multiple banners - full featured with lazy loading (all)' => [ + $position, + $fullFeaturedBanners, + [], [ - new Banner('1234', 'Main', 0, null, null, null, [ - new HtmlContent( - null, - '

Small content

', - ), - new ImageContent( - 600, - 'https://www.example.com/main1', - '_blank', - 'Main 1', - 'Main 1', - 'https://img.example.com/1000/main1.png', - 'https://img.example.com/800/main1.png 800w, https://img.example.com/1000/main1.png 1000w', - '(min-width: 1000px) 1000px, 100vw', - [ - new Source('image/avif', 'https://img.example.com/800/main1.avif 800w, https://img.example.com/1000/main1.avif 1000w'), - new Source('image/webp', 'https://img.example.com/800/main1.webp 800w, https://img.example.com/1000/main1.webp 1000w'), - ], - ), - new ImageContent( - 400, - 'https://www.example.com/main2', - '_blank', - 'Main 2', - 'Main 2', - 'https://img.example.com/600/main2.png', - 'https://img.example.com/600/main2.png 600w', - '100vw', - [ - new Source('image/avif', 'https://img.example.com/600/main2.avif 600w'), - new Source('image/webp', 'https://img.example.com/600/main2.webp 600w'), - ], - ), - ]), - new Banner('1235', 'Secondary', 0, null, null, null, [ - new ImageContent( - null, - 'https://www.example.com/secondary1', - null, - 'Secondary 1', - 'Secondary 1', - 'https://img.example.com/1000/secondary1.png', - 'https://img.example.com/800/secondary1.png 800w, https://img.example.com/1000/secondary1.png 1000w', - '(min-width: 1000px) 1000px, 100vw', - [], - ), - ]), - new Banner('1236', 'No contents', 0, null, null, null, []), + 'loading' => 'lazy', ], + __DIR__ . '/multipleBannersFullFeatured.withLazyLoading.html', + ], + 'Multiple banners - full featured with lazy loading (offset 1)' => [ + $position, + $fullFeaturedBanners, [], - __DIR__ . '/multipleBannersFullFeatured.html', + [ + 'loading' => 'lazy', + 'loading-offset' => 1, + ], + __DIR__ . '/multipleBannersFullFeatured.withLazyLoadingFromOffset1.html', ], ]; diff --git a/tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoading.html b/tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoading.html new file mode 100644 index 0000000..0fb847f --- /dev/null +++ b/tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoading.html @@ -0,0 +1,33 @@ +
+
+
+
+
+

Small content

+
+ + + + + Main 1 + + + + + + + Main 2 + + + +
+ +
+
+
diff --git a/tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoadingFromOffset1.html b/tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoadingFromOffset1.html new file mode 100644 index 0000000..2ae6200 --- /dev/null +++ b/tests/resources/renderer/multiple/multipleBannersFullFeatured.withLazyLoadingFromOffset1.html @@ -0,0 +1,33 @@ +
+
+
+
+
+

Small content

+
+ + + + + Main 1 + + + + + + + Main 2 + + + +
+ +
+
+
diff --git a/tests/resources/renderer/not-found/data-provider.php b/tests/resources/renderer/not-found/data-provider.php index 16af3f9..1ba1905 100644 --- a/tests/resources/renderer/not-found/data-provider.php +++ b/tests/resources/renderer/not-found/data-provider.php @@ -10,6 +10,7 @@ 'Not found' => [ $position, [], + [], __DIR__ . '/notFound.html', ], 'Not found with attributes' => [ @@ -20,6 +21,15 @@ 'data-custom2' => false, 'data-custom3' => null, ], + [], __DIR__ . '/notFound.withAttributes.html', ], + 'Not found with lazy loading' => [ + $position, + [], + [ + 'loading' => 'lazy', + ], + __DIR__ . '/notFound.withLazyLoading.html', + ], ]; diff --git a/tests/resources/renderer/not-found/notFound.withLazyLoading.html b/tests/resources/renderer/not-found/notFound.withLazyLoading.html new file mode 100644 index 0000000..983f275 --- /dev/null +++ b/tests/resources/renderer/not-found/notFound.withLazyLoading.html @@ -0,0 +1 @@ +
diff --git a/tests/resources/renderer/random/bannerWithDefaultImageContentOnly.withLazyLoading.html b/tests/resources/renderer/random/bannerWithDefaultImageContentOnly.withLazyLoading.html new file mode 100644 index 0000000..55a4c52 --- /dev/null +++ b/tests/resources/renderer/random/bannerWithDefaultImageContentOnly.withLazyLoading.html @@ -0,0 +1,11 @@ + diff --git a/tests/resources/renderer/random/bannerWithMultipleContents.html b/tests/resources/renderer/random/bannerWithMultipleContents.html index 8bb7be7..4286bff 100644 --- a/tests/resources/renderer/random/bannerWithMultipleContents.html +++ b/tests/resources/renderer/random/bannerWithMultipleContents.html @@ -1,4 +1,4 @@ -
+

Small content

@@ -7,14 +7,14 @@ - Main 1 + Main 1 - Main 2 + Main 2 diff --git a/tests/resources/renderer/random/data-provider.php b/tests/resources/renderer/random/data-provider.php index 0263c2a..119c060 100644 --- a/tests/resources/renderer/random/data-provider.php +++ b/tests/resources/renderer/random/data-provider.php @@ -15,6 +15,7 @@ $position, null, [], + [], __DIR__ . '/noBanner.html', ], 'No banner with attributes' => [ @@ -26,12 +27,14 @@ 'data-custom2' => false, 'data-custom3' => null, ], + [], __DIR__ . '/noBanner.withAttributes.html', ], 'Banner without contents' => [ $position, new Banner('1234', 'Main', 0, null, null, null, []), [], + [], __DIR__ . '/bannerWithoutContent.html', ], 'Banner with default content only: image without optional values' => [ @@ -50,6 +53,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithDefaultImageContentOnly.withoutOptionalValues.html', ], 'Banner with default content only: image with optional value' => [ @@ -71,8 +75,33 @@ ), ]), [], + [], __DIR__ . '/bannerWithDefaultImageContentOnly.withOptionalValues.html', ], + 'Banner with default content only: image with lazy loading' => [ + $position, + new Banner('1234', 'Main', 0, null, null, null, [ + new ImageContent( + null, + 'https://www.example.com/main1', + '_blank', + 'Main 1', + 'Main 1', + 'https://img.example.com/1000/main1.png', + 'https://img.example.com/500/main1.png 500w, https://img.example.com/1000/main1.png 1000w', + '(min-width: 1000px) calc(1000px - 2 * 16px), (min-width: 600px) calc(100vw - 2 * 16px), 100vw', + [ + new Source('image/avif', 'https://img.example.com/500/main1.avif 500w, https://img.example.com/1000/main1.avif 1000w'), + new Source('image/webp', 'https://img.example.com/500/main1.webp 500w, https://img.example.com/1000/main1.webp 1000w'), + ], + ), + ]), + [], + [ + 'loading' => 'lazy', + ], + __DIR__ . '/bannerWithDefaultImageContentOnly.withLazyLoading.html', + ], 'Banner with breakpoint content only: image' => [ $position, new Banner('1234', 'Main', 0, null, null, null, [ @@ -89,6 +118,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithBreakpointImageContentOnly.html', ], 'Banner with default content only: html' => [ @@ -100,6 +130,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithDefaultHtmlContentOnly.html', ], 'Banner with breakpoint content only: html' => [ @@ -111,6 +142,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithBreakpointHtmlContentOnly.html', ], 'Banner with multiple contents' => [ @@ -150,6 +182,9 @@ ), ]), [], + [ + 'loading' => 'lazy', + ], __DIR__ . '/bannerWithMultipleContents.html', ], ]; diff --git a/tests/resources/renderer/single/bannerWithDefaultImageContentOnly.withLazyLoading.html b/tests/resources/renderer/single/bannerWithDefaultImageContentOnly.withLazyLoading.html new file mode 100644 index 0000000..8773cfb --- /dev/null +++ b/tests/resources/renderer/single/bannerWithDefaultImageContentOnly.withLazyLoading.html @@ -0,0 +1,11 @@ + diff --git a/tests/resources/renderer/single/bannerWithMultipleContents.html b/tests/resources/renderer/single/bannerWithMultipleContents.html index f5ad774..1684757 100644 --- a/tests/resources/renderer/single/bannerWithMultipleContents.html +++ b/tests/resources/renderer/single/bannerWithMultipleContents.html @@ -1,4 +1,4 @@ -
+

Small content

@@ -7,14 +7,14 @@ - Main 1 + Main 1 - Main 2 + Main 2 diff --git a/tests/resources/renderer/single/data-provider.php b/tests/resources/renderer/single/data-provider.php index d39c6ab..7a0c622 100644 --- a/tests/resources/renderer/single/data-provider.php +++ b/tests/resources/renderer/single/data-provider.php @@ -15,6 +15,7 @@ $position, null, [], + [], __DIR__ . '/noBanner.html', ], 'No banner with attributes' => [ @@ -26,12 +27,14 @@ 'data-custom2' => false, 'data-custom3' => null, ], + [], __DIR__ . '/noBanner.withAttributes.html', ], 'Banner without contents' => [ $position, new Banner('1234', 'Main', 0, null, null, null, []), [], + [], __DIR__ . '/bannerWithoutContent.html', ], 'Banner with default content only: image without optional values' => [ @@ -50,6 +53,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithDefaultImageContentOnly.withoutOptionalValues.html', ], 'Banner with default content only: image with optional value' => [ @@ -71,8 +75,33 @@ ), ]), [], + [], __DIR__ . '/bannerWithDefaultImageContentOnly.withOptionalValues.html', ], + 'Banner with default content only: image with lazy loading' => [ + $position, + new Banner('1234', 'Main', 0, null, null, null, [ + new ImageContent( + null, + 'https://www.example.com/main1', + '_blank', + 'Main 1', + 'Main 1', + 'https://img.example.com/1000/main1.png', + 'https://img.example.com/500/main1.png 500w, https://img.example.com/1000/main1.png 1000w', + '(min-width: 1000px) calc(1000px - 2 * 16px), (min-width: 600px) calc(100vw - 2 * 16px), 100vw', + [ + new Source('image/avif', 'https://img.example.com/500/main1.avif 500w, https://img.example.com/1000/main1.avif 1000w'), + new Source('image/webp', 'https://img.example.com/500/main1.webp 500w, https://img.example.com/1000/main1.webp 1000w'), + ], + ), + ]), + [], + [ + 'loading' => 'lazy', + ], + __DIR__ . '/bannerWithDefaultImageContentOnly.withLazyLoading.html', + ], 'Banner with breakpoint content only: image' => [ $position, new Banner('1234', 'Main', 0, null, null, null, [ @@ -89,6 +118,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithBreakpointImageContentOnly.html', ], 'Banner with default content only: html' => [ @@ -100,6 +130,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithDefaultHtmlContentOnly.html', ], 'Banner with breakpoint content only: html' => [ @@ -111,6 +142,7 @@ ), ]), [], + [], __DIR__ . '/bannerWithBreakpointHtmlContentOnly.html', ], 'Banner with multiple contents' => [ @@ -150,6 +182,9 @@ ), ]), [], + [ + 'loading' => 'lazy', + ], __DIR__ . '/bannerWithMultipleContents.html', ], ];