Skip to content

Commit 14dcfa6

Browse files
committed
Add Twig Extensions for page refreshes
1 parent 821f2ae commit 14dcfa6

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

src/Turbo/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 2.24.0
4+
5+
- Add Twig Extensions for `meta` tags
6+
37
## 2.22.0
48

59
- Add `<twig:Turbo:Stream>` component

src/Turbo/doc/index.rst

+68
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,74 @@ because these classes implement the ``BroadcasterInterface`` and
10461046
``TurboStreamListenRendererInterface`` interfaces, the related services
10471047
will be.
10481048

1049+
Meta Tags
1050+
~~~~~~~~~
1051+
1052+
turbo_exempts_page_from_cache
1053+
.............................
1054+
1055+
.. code-block:: twig
1056+
1057+
{{ turbo_exempts_page_from_cache() }}
1058+
1059+
Generates a <meta> tag to disable caching of a page.
1060+
1061+
turbo_exempts_page_from_preview
1062+
...............................
1063+
1064+
.. code-block:: twig
1065+
1066+
{{ turbo_exempts_page_from_preview() }}
1067+
1068+
Generates a <meta> tag to specify cached version of the page should not be shown as a preview on regular navigation visits.
1069+
1070+
turbo_page_requires_reload
1071+
..........................
1072+
1073+
.. code-block:: twig
1074+
1075+
{{ turbo_page_requires_reload() }}
1076+
1077+
Generates a <meta> tag to force a full page reload.
1078+
1079+
turbo_refreshes_with
1080+
....................
1081+
1082+
.. code-block:: twig
1083+
1084+
{{ turbo_refreshes_with(method: 'replace', scroll: 'reset') }}
1085+
1086+
``method`` *(optional)*
1087+
**type**: ``string`` **default**: ``replace`` **allowed values**: ``replace`` or ``morph``
1088+
``scroll`` *(optional)*
1089+
**type**: ``string`` **default**: ``reset`` **allowed values**: ``reset`` or ``preserve``
1090+
1091+
Generates <meta> tags to configure both the refresh method and scroll behavior for page refreshes.
1092+
1093+
turbo_refresh_method
1094+
....................
1095+
1096+
.. code-block:: twig
1097+
1098+
{{ turbo_refresh_method(method: 'replace') }}
1099+
1100+
``method`` *(optional)*
1101+
**type**: ``string`` **default**: ``replace`` **allowed values**: ``replace`` or ``morph``
1102+
1103+
Generates a <meta> tag to configure the refresh method for page refreshes.
1104+
1105+
turbo_refresh_scroll
1106+
....................
1107+
1108+
.. code-block:: twig
1109+
1110+
{{ turbo_refresh_scroll(scroll: 'reset') }}
1111+
1112+
``scroll`` *(optional)*
1113+
**type**: ``string`` **default**: ``reset`` **allowed values**: ``reset`` or ``preserve``
1114+
1115+
Generates a <meta> tag to configure the scroll behavior for page refreshes.
1116+
10491117
Backward Compatibility promise
10501118
------------------------------
10511119

src/Turbo/src/Twig/TwigExtension.php

+103
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@
2222
*/
2323
final class TwigExtension extends AbstractExtension
2424
{
25+
private const REFRESH_METHOD_REPLACE = 'replace';
26+
private const REFRESH_METHOD_MORPH = 'morph';
27+
28+
private const REFRESH_SCROLL_RESET = 'reset';
29+
private const REFRESH_SCROLL_PRESERVE = 'preserve';
30+
2531
public function __construct(
2632
private ContainerInterface $turboStreamListenRenderers,
2733
private string $default,
@@ -32,6 +38,12 @@ public function getFunctions(): array
3238
{
3339
return [
3440
new TwigFunction('turbo_stream_listen', $this->turboStreamListen(...), ['needs_environment' => true, 'is_safe' => ['html']]),
41+
new TwigFunction('turbo_exempts_page_from_cache', $this->turboExemptsPageFromCache(...), ['is_safe' => ['html']]),
42+
new TwigFunction('turbo_exempts_page_from_preview', $this->turboExemptsPageFromPreview(...), ['is_safe' => ['html']]),
43+
new TwigFunction('turbo_page_requires_reload', $this->turboPageRequiresReload(...), ['is_safe' => ['html']]),
44+
new TwigFunction('turbo_refreshes_with', $this->turboRefreshesWith(...), ['is_safe' => ['html']]),
45+
new TwigFunction('turbo_refresh_method', $this->turboRefreshMethod(...), ['is_safe' => ['html']]),
46+
new TwigFunction('turbo_refresh_scroll', $this->turboRefreshScroll(...), ['is_safe' => ['html']]),
3547
];
3648
}
3749

@@ -52,4 +64,95 @@ public function turboStreamListen(Environment $env, $topic, ?string $transport =
5264

5365
return $this->turboStreamListenRenderers->get($transport)->renderTurboStreamListen($env, $topic);
5466
}
67+
68+
/**
69+
* Generates a <meta> tag to disable caching of a page.
70+
*
71+
* Inspired by Turbo Rails
72+
* ({@see https://github.com/hotwired/turbo-rails/blob/main/app/helpers/turbo/drive_helper.rb}).
73+
*/
74+
public function turboExemptsPageFromCache(): string
75+
{
76+
return '<meta name="turbo-cache-control" content="no-cache">';
77+
}
78+
79+
/**
80+
* Generates a <meta> tag to specify cached version of the page should not be shown as a preview on regular navigation visits.
81+
*
82+
* Inspired by Turbo Rails
83+
* ({@see https://github.com/hotwired/turbo-rails/blob/main/app/helpers/turbo/drive_helper.rb}).
84+
*/
85+
public function turboExemptsPageFromPreview(): string
86+
{
87+
return '<meta name="turbo-cache-control" content="no-preview">';
88+
}
89+
90+
/**
91+
* Generates a <meta> tag to force a full page reload.
92+
*
93+
* Inspired by Turbo Rails
94+
* ({@see https://github.com/hotwired/turbo-rails/blob/main/app/helpers/turbo/drive_helper.rb}).
95+
*/
96+
public function turboPageRequiresReload(): string
97+
{
98+
return '<meta name="turbo-visit-control" content="reload">';
99+
}
100+
101+
/**
102+
* Generates <meta> tags to configure both the refresh method and scroll behavior for page refreshes.
103+
*
104+
* Inspired by Turbo Rails
105+
* ({@see https://github.com/hotwired/turbo-rails/blob/main/app/helpers/turbo/drive_helper.rb}).
106+
*
107+
* @param string $method The refresh method. Must be either 'replace' or 'morph'.
108+
* @param string $scroll The scroll behavior. Must be either 'reset' or 'preserve'.
109+
*
110+
* @return string The <meta> tags for the specified refresh method and scroll behavior
111+
*/
112+
public function turboRefreshesWith(string $method = self::REFRESH_METHOD_REPLACE, string $scroll = self::REFRESH_SCROLL_RESET): string
113+
{
114+
return $this->turboRefreshMethod($method).$this->turboRefreshScroll($scroll);
115+
}
116+
117+
/**
118+
* Generates a <meta> tag to configure the refresh method for page refreshes.
119+
*
120+
* Inspired by Turbo Rails
121+
* ({@see https://github.com/hotwired/turbo-rails/blob/main/app/helpers/turbo/drive_helper.rb}).
122+
*
123+
* @param string $method The refresh method. Must be either 'replace' or 'morph'.
124+
*
125+
* @return string The <meta> tag for the specified refresh method
126+
*
127+
* @throws \InvalidArgumentException If an invalid refresh method is provided
128+
*/
129+
public function turboRefreshMethod(string $method = self::REFRESH_METHOD_REPLACE): string
130+
{
131+
if (!\in_array($method, [self::REFRESH_METHOD_REPLACE, self::REFRESH_METHOD_MORPH], true)) {
132+
throw new \InvalidArgumentException(\sprintf('Invalid refresh option "%s".', $method));
133+
}
134+
135+
return \sprintf('<meta name="turbo-refresh-method" content="%s">', $method);
136+
}
137+
138+
/**
139+
* Generates a <meta> tag to configure the scroll behavior for page refreshes.
140+
*
141+
* Inspired by Turbo Rails
142+
* ({@see https://github.com/hotwired/turbo-rails/blob/main/app/helpers/turbo/drive_helper.rb}).
143+
*
144+
* @param string $scroll The scroll behavior. Must be either 'reset' or 'preserve'.
145+
*
146+
* @return string The <meta> tag for the specified scroll behavior
147+
*
148+
* @throws \InvalidArgumentException If an invalid scroll behavior is provided
149+
*/
150+
public function turboRefreshScroll(string $scroll = self::REFRESH_SCROLL_RESET): string
151+
{
152+
if (!\in_array($scroll, [self::REFRESH_SCROLL_RESET, self::REFRESH_SCROLL_PRESERVE], true)) {
153+
throw new \InvalidArgumentException(\sprintf('Invalid scroll option "%s".', $scroll));
154+
}
155+
156+
return \sprintf('<meta name="turbo-refresh-scroll" content="%s">', $scroll);
157+
}
55158
}

0 commit comments

Comments
 (0)