Skip to content

Commit

Permalink
Banner options, Native lazy loading
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
tg666 committed Dec 1, 2023
1 parent c98d219 commit 99e15e2
Show file tree
Hide file tree
Showing 47 changed files with 616 additions and 165 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

## 1.0.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' => <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

Expand Down
10 changes: 9 additions & 1 deletion docs/integration-with-nette-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -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']}
```

Expand Down
58 changes: 55 additions & 3 deletions docs/integration-without-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand Down Expand Up @@ -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
])
```

Expand Down Expand Up @@ -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']}
```

Expand Down
7 changes: 5 additions & 2 deletions src/Bridge/Latte/RendererProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
42 changes: 42 additions & 0 deletions src/Renderer/Latte/Helpers.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace SixtyEightPublishers\AmpClient\Renderer\Latte;

use SixtyEightPublishers\AmpClient\Request\ValueObject\Position as RequestPosition;

final class Helpers
{
private function __construct() {}

/**
* @return array<string, string>
*/
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<string, scalar> $options
*
* @return array<string, scalar>
*/
public static function createOptionAttributes(array $options): array
{
$attributes = [];

foreach ($options as $name => $value) {
$attributes['data-amp-option-' . $name] = $value;
}

return $attributes;
}
}
27 changes: 10 additions & 17 deletions src/Renderer/Latte/LatteRendererBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -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),
);
}

Expand Down
14 changes: 7 additions & 7 deletions src/Renderer/Latte/Templates/ClientSideTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ final class ClientSideTemplate
{
public Position $position;

/** @var array<string, string> */
public array $resourceAttributes;

/** @var array<string, scalar|null> */
public array $elementAttributes;

/** @var array<string, scalar> */
public array $options;

/**
* @param array<string, string> $resourceAttributes
* @param array<string, scalar|null> $elementAttributes
* @param array<string, scalar> $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;
}
}
8 changes: 7 additions & 1 deletion src/Renderer/Latte/Templates/MultipleTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,23 @@ final class MultipleTemplate
/** @var array<string, scalar|null> */
public array $elementAttributes;

/** @var array<string, scalar> */
public array $options;

/**
* @param array<int, Banner> $banners
* @param array<string, scalar|null> $elementAttributes
* @param array<string, scalar> $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;
}
}
8 changes: 7 additions & 1 deletion src/Renderer/Latte/Templates/NotFoundTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ final class NotFoundTemplate
/** @var array<string, scalar|null> */
public array $elementAttributes;

/** @var array<string, scalar> */
public array $options;

/**
* @param array<string, scalar|null> $elementAttributes
* @param array<string, scalar> $options
*/
public function __construct(
Position $position,
array $elementAttributes
array $elementAttributes,
array $options
) {
$this->position = $position;
$this->elementAttributes = $elementAttributes;
$this->options = $options;
}
}
8 changes: 7 additions & 1 deletion src/Renderer/Latte/Templates/RandomTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,22 @@ final class RandomTemplate
/** @var array<string, scalar|null> */
public array $elementAttributes;

/** @var array<string, scalar> */
public array $options;

/**
* @param array<string, scalar|null> $elementAttributes
* @param array<string, scalar> $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;
}
}
8 changes: 7 additions & 1 deletion src/Renderer/Latte/Templates/SingleTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,22 @@ final class SingleTemplate
/** @var array<string, scalar|null> */
public array $elementAttributes;

/** @var array<string, scalar> */
public array $options;

/**
* @param array<string, scalar|null> $elementAttributes
* @param array<string, scalar> $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;
}
}
Loading

0 comments on commit 99e15e2

Please sign in to comment.