Skip to content

Commit

Permalink
Integration with JS client
Browse files Browse the repository at this point in the history
- added possibility to render custom attributes on a banner tag
- added rendering of data attribute `data-amp-banner-external`
- fixed fingerprint resolving (now compatible with JS client)
- added and fixed tests
  • Loading branch information
tg666 committed Nov 29, 2023
1 parent 0fe5551 commit d12decd
Show file tree
Hide file tree
Showing 60 changed files with 382 additions and 112 deletions.
2 changes: 1 addition & 1 deletion docs/integration-with-nette-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Now we have the macro `{banner}` available in the application, and we can use it

```latte
{banner homepage.top}
{banner homepage.promo, ['role' => 'guest']}
{banner homepage.promo, resources: ['role' => 'guest']}
```

Banners are now requested via API and rendered to the template automatically.
Expand Down
2 changes: 1 addition & 1 deletion docs/integration-without-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ $engine->render(__DIR__ . '/template.latte');
{* ./template.latte *}
{banner homepage.top}
{banner homepage.promo, ['role' => 'guest']}
{banner homepage.promo, resources: ['role' => 'guest']}
```

Banners are now requested via API and rendered to the template automatically.
Expand Down
2 changes: 1 addition & 1 deletion src/Bridge/Latte/AmpClientLatte2Extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ public function macroBanner(MacroNode $node, PhpWriter $writer): string

return $writer
->using($node)
->write('echo ($this->global->ampClientRenderer)($this->global, %node.word, %node.args?);');
->write('echo ($this->global->ampClientRenderer)($this->global, %node.word, %node.array?);');
}
}
13 changes: 7 additions & 6 deletions src/Bridge/Latte/Node/BannerNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Generator;
use Latte\CompileException;
use Latte\Compiler\Nodes\Php\Expression\ArrayNode;
use Latte\Compiler\Nodes\Php\ExpressionNode;
use Latte\Compiler\Nodes\StatementNode;
use Latte\Compiler\PrintContext;
Expand All @@ -18,7 +19,7 @@ final class BannerNode extends StatementNode
{
public ExpressionNode $positionCode;

public ?ExpressionNode $resources = null;
public ?ArrayNode $options = null;

/**
* @throws CompileException
Expand All @@ -30,19 +31,19 @@ public static function create(Tag $tag): self
$node->positionCode = $tag->parser->parseUnquotedStringOrExpression();

if ($tag->parser->stream->tryConsume(',')) {
$node->resources = $tag->parser->parseExpression();
$node->options = $tag->parser->parseArguments();
}

return $node;
}

public function print(PrintContext $context): string
{
if (null !== $this->resources) {
if (null !== $this->options) {
return $context->format(
'echo ($this->global->ampClientRenderer)($this->global, %node, %node?);',
$this->positionCode,
$this->resources,
$this->options,
);
}

Expand All @@ -56,8 +57,8 @@ public function &getIterator(): Generator
{
yield $this->positionCode;

if (null !== $this->resources) {
yield $this->resources;
if (null !== $this->options) {
yield $this->options;
}
}
}
15 changes: 9 additions & 6 deletions src/Bridge/Latte/RendererProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

final class RendererProvider
{
private const OptionResources = 'resources';

private AmpClientInterface $client;

private RendererInterface $renderer;
Expand Down Expand Up @@ -62,13 +64,13 @@ public function __construct(
}

/**
* @param array<string, string|array<int, string>> $resources
* @param array<string, mixed> $options
*
* @throws AmpExceptionInterface
*/
public function __invoke(object $globals, string $positionCode, array $resources = []): string
public function __invoke(object $globals, string $positionCode, array $options = []): string
{
$position = $this->createPosition($positionCode, $resources);
$position = $this->createPosition($positionCode, $options);

if ($this->renderingMode->shouldBePositionQueued($position, $globals)) {
return $this->addToQueue($position);
Expand Down Expand Up @@ -250,14 +252,15 @@ private function renderPosition(ResponsePosition $position): string
}

/**
* @param array<string, string|array<int, string>> $resources
* @param array<string, mixed> $options
*/
private function createPosition(string $positionCode, array $resources): RequestPosition
private function createPosition(string $positionCode, array $options): RequestPosition
{
$resources = (array) ($options[self::OptionResources] ?? []);
$bannerResources = [];

foreach ($resources as $resourceCode => $resourceValues) {
$bannerResources[] = new BannerResource($resourceCode, $resourceValues);
$bannerResources[] = $resourceValues instanceof BannerResource ? $resourceValues : new BannerResource($resourceCode, $resourceValues);
}

return new RequestPosition($positionCode, $bannerResources);
Expand Down
13 changes: 13 additions & 0 deletions src/Exception/RendererException.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ public static function unableToCreateFingerprint(string $positionCode, string $b
);
}

public static function unableToRenderAmpBannerExternalAttribute(string $positionCode, ?Throwable $previous = null): self
{
return new self(
sprintf(
'Unable to render amp-banner-external for the position %s. %s',
$positionCode,
null !== $previous ? $previous->getMessage() : '',
),
0,
$previous,
);
}

/**
* @param class-string $rendererBridgeClassname
*/
Expand Down
63 changes: 63 additions & 0 deletions src/Renderer/AmpBannerExternalAttribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

declare(strict_types=1);

namespace SixtyEightPublishers\AmpClient\Renderer;

use JsonException;
use SixtyEightPublishers\AmpClient\Exception\RendererException;
use SixtyEightPublishers\AmpClient\Response\ValueObject\Position;

final class AmpBannerExternalAttribute
{
private Position $position;

private string $state;

private string $stateInfo;

private function __construct(Position $position, string $state, string $stateInfo)
{
$this->position = $position;
$this->state = $state;
$this->stateInfo = $stateInfo;
}

public static function rendered(Position $position): self
{
return new self($position, 'RENDERED', 'Banner was successfully rendered server-side.');
}

public static function notFound(Position $position): self
{
return new self($position, 'NOT_FOUND', 'Banner not found in fetched response on the server.');
}

public function __toString(): string
{
$components = [
'positionData' => [
'id' => $this->position->getId(),
'code' => $this->position->getCode(),
'name' => $this->position->getName(),
'rotationSeconds' => $this->position->getRotationSeconds(),
'displayType' => $this->position->getDisplayType(),
'breakpointType' => $this->position->getBreakpointType(),
],
'state' => [
'value' => $this->state,
'info' => $this->stateInfo,
],
];

try {
$json = json_encode($components, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
} catch (JsonException $e) {
throw RendererException::unableToRenderAmpBannerExternalAttribute($this->position->getCode(), $e);
}

return base64_encode(
rawurlencode($json),
);
}
}
10 changes: 3 additions & 7 deletions src/Renderer/Fingerprint.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use function base64_encode;
use function json_encode;
use function rawurlencode;
use function rtrim;

final class Fingerprint
{
Expand Down Expand Up @@ -39,17 +38,14 @@ public static function create(Position $position, Banner $banner): self
];

try {
$json = json_encode($components, JSON_THROW_ON_ERROR);
$json = json_encode($components, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
} catch (JsonException $e) {
throw RendererException::unableToCreateFingerprint($position->getCode(), $banner->getId(), $e);
}

return new self(
rtrim(
base64_encode(
rawurlencode($json),
),
'=',
base64_encode(
rawurlencode($json),
),
);
}
Expand Down
16 changes: 8 additions & 8 deletions src/Renderer/Latte/LatteRendererBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,35 @@ public function overrideTemplates(Templates $templates): self
return $renderer;
}

public function renderNotFound(Position $position): string
public function renderNotFound(Position $position, array $elementAttributes = []): string
{
return $this->getLatte()->renderToString(
$this->templates->getTemplateFile(Templates::TemplateNotFound),
new NotFoundTemplate($position),
new NotFoundTemplate($position, $elementAttributes),
);
}

public function renderSingle(Position $position, ?Banner $banner): string
public function renderSingle(Position $position, ?Banner $banner, array $elementAttributes = []): string
{
return $this->getLatte()->renderToString(
$this->templates->getTemplateFile(Templates::TemplateSingle),
new SingleTemplate($position, $banner),
new SingleTemplate($position, $banner, $elementAttributes),
);
}

public function renderRandom(Position $position, ?Banner $banner): string
public function renderRandom(Position $position, ?Banner $banner, array $elementAttributes = []): string
{
return $this->getLatte()->renderToString(
$this->templates->getTemplateFile(Templates::TemplateRandom),
new RandomTemplate($position, $banner),
new RandomTemplate($position, $banner, $elementAttributes),
);
}

public function renderMultiple(Position $position, array $banners): string
public function renderMultiple(Position $position, array $banners, array $elementAttributes = []): string
{
return $this->getLatte()->renderToString(
$this->templates->getTemplateFile(Templates::TemplateMultiple),
new MultipleTemplate($position, $banners),
new MultipleTemplate($position, $banners, $elementAttributes),
);
}

Expand Down
10 changes: 8 additions & 2 deletions src/Renderer/Latte/Templates/MultipleTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@ final class MultipleTemplate
/** @var array<int, Banner> */
public array $banners;

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

/**
* @param array<int, Banner> $banners
* @param array<int, Banner> $banners
* @param array<string, scalar|null> $elementAttributes
*/
public function __construct(
Position $position,
array $banners
array $banners,
array $elementAttributes
) {
$this->position = $position;
$this->banners = $banners;
$this->elementAttributes = $elementAttributes;
}
}
10 changes: 9 additions & 1 deletion src/Renderer/Latte/Templates/NotFoundTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@ final class NotFoundTemplate
{
public Position $position;

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

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

public ?Banner $banner;

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

/**
* @param array<string, scalar|null> $elementAttributes
*/
public function __construct(
Position $position,
?Banner $banner
?Banner $banner,
array $elementAttributes
) {
$this->position = $position;
$this->banner = $banner;
$this->elementAttributes = $elementAttributes;
}
}
10 changes: 9 additions & 1 deletion src/Renderer/Latte/Templates/SingleTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@ final class SingleTemplate

public ?Banner $banner;

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

/**
* @param array<string, scalar|null> $elementAttributes
*/
public function __construct(
Position $position,
?Banner $banner
?Banner $banner,
array $elementAttributes
) {
$this->position = $position;
$this->banner = $banner;
$this->elementAttributes = $elementAttributes;
}
}
4 changes: 3 additions & 1 deletion src/Renderer/Latte/Templates/multiple.latte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\MultipleTemplate}

<div data-amp-banner="{$position->getCode()}" data-amp-attached>
<div data-amp-banner="{$position->getCode()}"
data-amp-banner-external="{=SixtyEightPublishers\AmpClient\Renderer\AmpBannerExternalAttribute::rendered($position)}"
n:attr="$elementAttributes">
{do $banners = array_filter($banners, fn(SixtyEightPublishers\AmpClient\Response\ValueObject\Banner $banner) => 0 < count($banner->getContents()))}
<div n:if="0 < count($banners)" class="amp-banner amp-banner--multiple">
<div class="amp-banner__list">
Expand Down
5 changes: 4 additions & 1 deletion src/Renderer/Latte/Templates/notFound.latte
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\NotFoundTemplate}

<div data-amp-banner="{$position->getCode()}" data-amp-attached></div>
<div data-amp-banner="{$position->getCode()}"
data-amp-banner-external="{=SixtyEightPublishers\AmpClient\Renderer\AmpBannerExternalAttribute::notFound($position)}"
n:attr="$elementAttributes">
</div>
4 changes: 3 additions & 1 deletion src/Renderer/Latte/Templates/random.latte
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{templateType SixtyEightPublishers\AmpClient\Renderer\Latte\Templates\RandomTemplate}

<div data-amp-banner="{$position->getCode()}" data-amp-attached>
<div data-amp-banner="{$position->getCode()}"
data-amp-banner-external="{=SixtyEightPublishers\AmpClient\Renderer\AmpBannerExternalAttribute::rendered($position)}"
n:attr="$elementAttributes">
<div n:if="null !== $banner && 0 < count($banner->getContents())"
class="amp-banner amp-banner--random"
data-amp-banner-fingerprint="{SixtyEightPublishers\AmpClient\Renderer\Fingerprint::create($position, $banner)}"
Expand Down
Loading

0 comments on commit d12decd

Please sign in to comment.