From 8d37ffb57cfa580ddc8c50fe8ca1c3a9d2ffc730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Karlovi=C4=87?= Date: Mon, 11 Dec 2023 15:32:20 +0100 Subject: [PATCH] fix: relative thumbnails in Twig (#187) * feat: imgproxy in Twig * feat: imgproxy in Twig * feat: imgproxy in Twig --- psalm.baseline.xml | 17 +++++++++++++++- .../Twig/Extension/ThumbnailExtension.php | 18 +++++++++++++++++ src/Decoder/AssetQueueFileDecoder.php | 9 ++++----- src/Decoder/MarkdownFileDecoder.php | 2 +- src/Storage/DenormalizingStorage.php | 19 +++++++++++++++++- src/Storage/FilesystemStorage.php | 5 ++++- .../images/200ad8764a311b8ca90c5271eaf73efb | Bin 0 -> 3928 bytes .../site/fixtures/en/articles/1/index.html | 5 +++-- .../site/fixtures/en/articles/2/index.html | 4 ++-- .../site/fixtures/en/articles/3/index.html | 2 +- tests/functional/site/src/Model/Article.php | 7 ++++++- .../site/templates/pages/articles.html.twig | 3 +++ 12 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 tests/functional/site/fixtures/content/articles/images/200ad8764a311b8ca90c5271eaf73efb diff --git a/psalm.baseline.xml b/psalm.baseline.xml index 90f3285..fdd4edc 100644 --- a/psalm.baseline.xml +++ b/psalm.baseline.xml @@ -427,12 +427,19 @@ + + + + $item + + + __path]]> + imgproxyUrl]]> - ThumbnailExtension @@ -632,12 +639,19 @@ $locale $locale + + $key + cache[$this->class][$locale]]]> $locale $locale + $metadata[$key] + $object + $value + $value T @@ -649,6 +663,7 @@ denormalizer->denormalize($data, $this->class, null, $context + [ AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false, ])]]> + $object $context[LocaleContext::LOCALE] diff --git a/src/Bridge/Twig/Extension/ThumbnailExtension.php b/src/Bridge/Twig/Extension/ThumbnailExtension.php index 4c33f2f..13452c8 100644 --- a/src/Bridge/Twig/Extension/ThumbnailExtension.php +++ b/src/Bridge/Twig/Extension/ThumbnailExtension.php @@ -29,12 +29,30 @@ public function getFunctions(): array return [ new TwigFunction('yassg_thumbnail', function (array $context, string $path, array $options = []): string { if (str_starts_with($path, './')) { + if (! isset($context['_path'])) { + if (isset($options['self'])) { + $context['_path'] = $options['self']->__path; + } else { + $candidates = []; + foreach ($context as $item) { + if (\is_object($item) && property_exists($item, '__path')) { + $candidates[] = $item; + } + } + if (\count($candidates) !== 1) { + throw new \RuntimeException('Cannot use yassg_thumbnail() without a single Locatable object in context, pass {self: object} as the second argument'); + } + $context['_path'] = $candidates[0]->__path; + } + } + $newPath = realpath(\dirname($context['_path']).'/'.$path); if ($newPath === false) { throw new \RuntimeException('Invalid thumbnail path '.$path); } $path = $newPath; } + unset($options['self']); $filter = ''; if ($options !== []) { diff --git a/src/Decoder/AssetQueueFileDecoder.php b/src/Decoder/AssetQueueFileDecoder.php index 0b9c631..98533da 100644 --- a/src/Decoder/AssetQueueFileDecoder.php +++ b/src/Decoder/AssetQueueFileDecoder.php @@ -29,15 +29,14 @@ public function supports(\SplFileInfo $file): bool public function decode(\SplFileInfo $file): array { - /** @var array{"@assets"?: list} $decoded */ + /** @var array{"__assets"?: list} $decoded */ $decoded = $this->decoder->decode($file); - if (isset($decoded['@assets'])) { - foreach ($decoded['@assets'] as $thumbnail) { - $this->queue->add($thumbnail); + if (isset($decoded['__assets'])) { + foreach ($decoded['__assets'] as $asset) { + $this->queue->add($asset); } } - unset($decoded['@assets']); return $decoded; } diff --git a/src/Decoder/MarkdownFileDecoder.php b/src/Decoder/MarkdownFileDecoder.php index 9f38fa4..cba53c2 100644 --- a/src/Decoder/MarkdownFileDecoder.php +++ b/src/Decoder/MarkdownFileDecoder.php @@ -72,7 +72,7 @@ public function decode(\SplFileInfo $file): array $metadata = $result->getFrontMatter(); } $metadata['body'] = $result->getContent(); - $metadata['@assets'] = $assets; + $metadata['__assets'] = $assets; return $metadata; } diff --git a/src/Storage/DenormalizingStorage.php b/src/Storage/DenormalizingStorage.php index 5f07d99..86d798c 100644 --- a/src/Storage/DenormalizingStorage.php +++ b/src/Storage/DenormalizingStorage.php @@ -103,9 +103,26 @@ private function fetch(string $locale, string $id, array|object $item, array $co private function denormalize(string $id, array $data, array $context): object { try { - return $this->denormalizer->denormalize($data, $this->class, null, $context + [ + $metadata = []; + foreach ($data as $key => $value) { + if (str_starts_with($key, '__')) { + $metadata[$key] = $value; + unset($data[$key]); + } + } + $object = $this->denormalizer->denormalize($data, $this->class, null, $context + [ AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false, ]); + + // attach metadata to the object as dynamic properties + foreach ($metadata as $key => $value) { + /** + * @phpstan-ignore-next-line + */ + $object->{$key} = $value; + } + + return $object; } catch (ExtraAttributesException $extraAttributesException) { throw UnexpectedAttributeException::newSelf($id, $extraAttributesException->getMessage()); } diff --git a/src/Storage/FilesystemStorage.php b/src/Storage/FilesystemStorage.php index 6ae30f2..2f7c0c5 100644 --- a/src/Storage/FilesystemStorage.php +++ b/src/Storage/FilesystemStorage.php @@ -115,6 +115,9 @@ private function decode(\SplFileInfo $file): array throw new \RuntimeException(sprintf('Decoder does not know how to decode %1$s file', $file->getRealPath())); } - return $this->decoder->decode($file); + $decoded = $this->decoder->decode($file); + $decoded['__path'] = $file->getRealPath(); + + return $decoded; } } diff --git a/tests/functional/site/fixtures/content/articles/images/200ad8764a311b8ca90c5271eaf73efb b/tests/functional/site/fixtures/content/articles/images/200ad8764a311b8ca90c5271eaf73efb new file mode 100644 index 0000000000000000000000000000000000000000..d57cb63314e930dcc846b94b5cfab7e3afe13130 GIT binary patch literal 3928 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%0D6|)Z zuE51qgPDh$6#3kYKFM9!8D^&duSU{GcnO*4o8s090ztr1BXQe&e<0)GuX3?>7?~_0 z>D(EfFB3%=8X1L<>b0@Ex+I6rMLU<*oTBJsCbyt**E2UuS}+%J*dQ_f0=_8I-qL~4 zcQ(Rf^uhOXR=pBhRXEfTN%I+{Ac3%fQVc1%J&DQMg{iUKve3`X%36o9&@_`j8YV(@ zrc0GA|J{c7`8p&V#M0Q^wiCb?IE}FxH+z029-jJ4_9_`ikdz7bYB+Dv^Q+Q#&*q5d zCk^4JP3q$%`0mMT>h|uA5N1V}H$PfT1X>M8{3J4!A9A@&ubDbaY7x9^W|CDe^|bkS zCau#|KwKwmytn(v38t-vy=@hI{pHB&#=J@gy|J#XJzI|`zfWzY>WAgI0?965*~go= z9vI6wpZg}&_43Ff_e+A|QA=2r{(j&0e9?lx=)1%Xydwzdp?^n!1gG>-fY4m4{Q}I#YS^t*MPFG~{F0iFuaO(S zm`j_3t-t8URQzUr$H&rZoud!pMnrxRIltaAe4%==g)8>D{N94u$xG$N6_tdEneoZ) zDmfyYrAp58*elj}axhP(rjJ(0D%zTg$=Xa#9`SlMTZQI&&0_)UwhWfuHJN5PeXh3* zC_Oj~+@$kOs%`3{{c&|iNL*g?$$^bA^p+l5FWf18&Q4*Bc|v8pM@^DV^PqLICrMFXUJ%rW-<%K>y7OmbZxMq>ZTjFhxOWLt72 zrTo_1MuXzSnqjA&RS~#&3v}`!_(br)q9XfJHp4dhO0waDYnMBY?jj{YJ3cWVi?(#} znGr@3v}uC3|Hee`eYU`@^pTGGw+j&{ehY+~8KQah

Articles

Images!

-

20.07.2022. 12:35

+

+

20.07.2022. 12:35

Lists!

-

19.07.2022. 12:13

+

19.07.2022. 12:13

  • diff --git a/tests/functional/site/fixtures/en/articles/2/index.html b/tests/functional/site/fixtures/en/articles/2/index.html index 0e8dece..ecb4b27 100644 --- a/tests/functional/site/fixtures/en/articles/2/index.html +++ b/tests/functional/site/fixtures/en/articles/2/index.html @@ -16,9 +16,9 @@

    Articles

    Titles!

    -

    19.07.2022. 12:11

    +

    19.07.2022. 12:11

    Paragraphs!

    -

    19.07.2022. 12:09

    +

    19.07.2022. 12:09

    • diff --git a/tests/functional/site/fixtures/en/articles/3/index.html b/tests/functional/site/fixtures/en/articles/3/index.html index 9816d3b..3109318 100644 --- a/tests/functional/site/fixtures/en/articles/3/index.html +++ b/tests/functional/site/fixtures/en/articles/3/index.html @@ -16,7 +16,7 @@

      Articles

      Hello World!

      -

      18.07.2022. 12:44

      +

      18.07.2022. 12:44

      • diff --git a/tests/functional/site/src/Model/Article.php b/tests/functional/site/src/Model/Article.php index 7ef55a6..ebd4556 100644 --- a/tests/functional/site/src/Model/Article.php +++ b/tests/functional/site/src/Model/Article.php @@ -20,8 +20,13 @@ final class Article public string $title; public string $slug; public string $body; - public string $image; + public ?string $image = null; #[Context(['datetime_format' => 'Y-m-d H:i:s'])] public \DateTimeInterface $publishedAt; + + public function getImage(): ?string + { + return $this->image; + } } diff --git a/tests/functional/site/templates/pages/articles.html.twig b/tests/functional/site/templates/pages/articles.html.twig index 8c19345..df51e39 100644 --- a/tests/functional/site/templates/pages/articles.html.twig +++ b/tests/functional/site/templates/pages/articles.html.twig @@ -13,6 +13,9 @@

        Articles

        {% for article in articles %}

        {{ article.title }}

        + {% if article.image %} +

        + {% endif %}

        {{ article.publishedAt|date('d.m.Y. H:i') }}

        {% endfor %}