Skip to content

Commit c3f7627

Browse files
committed
[Icons] Improve cache warmup by looking at every string
1 parent 554ebba commit c3f7627

File tree

8 files changed

+43
-10
lines changed

8 files changed

+43
-10
lines changed

src/Icons/config/iconify.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
->set('.ux_icons.iconify', Iconify::class)
2727
->args([
28+
service('cache.system'),
2829
abstract_arg('endpoint'),
2930
service('http_client')->nullOnInvalid(),
3031
])

src/Icons/doc/index.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,22 @@ In production, you can pre-warm the cache by running the following command:
115115
116116
This command looks in all your twig templates for ``ux_icon`` calls and caches the icons it finds.
117117

118+
.. caution::
119+
120+
Icons that have a name built dynamically will not be cached. It's advised to have the icon
121+
name as a string literal in your templates.
122+
123+
.. code-block:: twig
124+
125+
{# This will be cached #}
126+
{{ ux_icon('flag-fr') }}
127+
128+
{# This will NOT be cached #}
129+
{{ ux_icon('flag-' ~ locale) }}
130+
131+
{% set flags = {fr: 'flag-fr', de: 'flag-de'} %} {# both "flag-fr" and "flag-de" will be cached #}
132+
{{ ux_icon(flags[locale]) }}
133+
118134
.. note::
119135

120136
During development, if you modify an icon, you will need to clear the cache (``bin/console cache:clear``)

src/Icons/src/Command/WarmCacheCommand.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int
4545
$io->writeln(sprintf(' Warmed icon <comment>%s</comment>.', $name));
4646
}
4747
},
48-
onFailure: fn (string $name) => $io->warning(sprintf('Icon <comment>%s</comment> not found.', $name))
4948
);
5049

5150
$io->success('Icon cache warmed.');

src/Icons/src/DependencyInjection/UXIconsExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
9191
$loader->load('iconify.php');
9292

9393
$container->getDefinition('.ux_icons.iconify')
94-
->setArgument(0, $mergedConfig['iconify']['endpoint'])
94+
->setArgument(1, $mergedConfig['iconify']['endpoint'])
9595
;
9696
}
9797

src/Icons/src/Iconify.php

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\HttpClient\Exception\JsonException;
1515
use Symfony\Component\HttpClient\HttpClient;
1616
use Symfony\Component\HttpClient\ScopingHttpClient;
17+
use Symfony\Contracts\Cache\CacheInterface;
1718
use Symfony\Contracts\HttpClient\HttpClientInterface;
1819
use Symfony\UX\Icons\Exception\IconNotFoundException;
1920
use Symfony\UX\Icons\Svg\Icon;
@@ -26,8 +27,10 @@
2627
final class Iconify
2728
{
2829
private HttpClientInterface $http;
30+
private \ArrayObject $sets;
2931

3032
public function __construct(
33+
private CacheInterface $cache,
3134
string $endpoint = 'https://api.iconify.design',
3235
?HttpClientInterface $http = null,
3336
) {
@@ -40,13 +43,15 @@ public function __construct(
4043

4144
public function metadataFor(string $prefix): array
4245
{
43-
$response = $this->http->request('GET', sprintf('/collections?prefix=%s', $prefix));
44-
45-
return $response->toArray()[$prefix] ?? throw new \RuntimeException(sprintf('The icon prefix "%s" does not exist on iconify.design.', $prefix));
46+
return $this->sets()[$prefix] ?? throw new \RuntimeException(sprintf('The icon prefix "%s" does not exist on iconify.design.', $prefix));
4647
}
4748

4849
public function fetchIcon(string $prefix, string $name): Icon
4950
{
51+
if (!isset($this->sets()[$prefix])) {
52+
throw new IconNotFoundException(sprintf('The icon "%s:%s" does not exist on iconify.design.', $prefix, $name));
53+
}
54+
5055
$response = $this->http->request('GET', sprintf('/%s.json?icons=%s', $prefix, $name));
5156

5257
try {
@@ -66,6 +71,10 @@ public function fetchIcon(string $prefix, string $name): Icon
6671

6772
public function fetchSvg(string $prefix, string $name): string
6873
{
74+
if (!isset($this->sets()[$prefix])) {
75+
throw new IconNotFoundException(sprintf('The icon "%s:%s" does not exist on iconify.design.', $prefix, $name));
76+
}
77+
6978
$content = $this->http
7079
->request('GET', sprintf('/%s/%s.svg', $prefix, $name))
7180
->getContent()
@@ -77,4 +86,13 @@ public function fetchSvg(string $prefix, string $name): string
7786

7887
return $content;
7988
}
89+
90+
private function sets(): \ArrayObject
91+
{
92+
return $this->sets ??= $this->cache->get('ux-iconify-sets', function () {
93+
$response = $this->http->request('GET', '/collections');
94+
95+
return new \ArrayObject($response->toArray());
96+
});
97+
}
8098
}

src/Icons/src/Twig/IconFinder.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,7 @@ public function icons(): array
3838
foreach ($this->files($this->twig->getLoader()) as $file) {
3939
$contents = file_get_contents($file);
4040

41-
if (preg_match_all('#ux_icon\(["\']([\w:-]+)["\']#', $contents, $matches)) {
42-
$found[] = $matches[1];
43-
}
44-
45-
if (preg_match_all('#name=["\']([\w:-]+)["\']#', $contents, $matches)) {
41+
if (preg_match_all('#["\']([\w:-]+)["\']#', $contents, $matches)) {
4642
$found[] = $matches[1];
4743
}
4844
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
{% set icon = 'flag:eu-4x3' %}
2+
13
{{ ux_icon('something:invalid') }}
24
{{ ux_icon('invalid') }}
35
{{ ux_icon('iconamoon:invalid') }}

src/Icons/tests/Integration/Command/WarmCacheCommandTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public function testCanWarmCache(): void
2929
->assertOutputContains('Warmed icon user.')
3030
->assertOutputContains('Warmed icon sub:check.')
3131
->assertOutputContains('Warmed icon iconamoon:3d-duotone.')
32+
->assertOutputContains('Warmed icon flag:eu-4x3.')
3233
->assertOutputContains('Icon cache warmed.')
3334
;
3435
}

0 commit comments

Comments
 (0)