2222 */
2323final 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