1111
1212namespace App \Twig ;
1313
14+ use Symfony \Component \DependencyInjection \Attribute \Autowire ;
15+ use Symfony \Component \ErrorHandler \ErrorRenderer \FileLinkFormatter ;
1416use Twig \Environment ;
1517use Twig \Extension \AbstractExtension ;
1618use Twig \TemplateWrapper ;
2830 */
2931final class SourceCodeExtension extends AbstractExtension
3032{
33+ private FileLinkFormatter $ fileLinkFormat ;
34+ private string $ projectDir ;
3135 /**
3236 * @var callable|null
3337 */
3438 private $ controller ;
3539
40+ public function __construct (
41+ FileLinkFormatter $ fileLinkFormat ,
42+ #[Autowire('%kernel.project_dir% ' )]
43+ string $ projectDir ,
44+ ) {
45+ $ this ->fileLinkFormat = $ fileLinkFormat ;
46+ $ this ->projectDir = str_replace ('\\' , '/ ' , $ projectDir ).'/ ' ;
47+ }
48+
3649 public function setController (?callable $ controller ): void
3750 {
3851 $ this ->controller = $ controller ;
@@ -41,10 +54,29 @@ public function setController(?callable $controller): void
4154 public function getFunctions (): array
4255 {
4356 return [
44- new TwigFunction ('show_source_code ' , [$ this , 'showSourceCode ' ], ['is_safe ' => ['html ' ], 'needs_environment ' => true ]),
57+ new TwigFunction ('link_source_file ' , $ this ->linkSourceFile (...), ['is_safe ' => ['html ' ], 'needs_environment ' => true ]),
58+ new TwigFunction ('show_source_code ' , $ this ->showSourceCode (...), ['is_safe ' => ['html ' ], 'needs_environment ' => true ]),
4559 ];
4660 }
4761
62+ /**
63+ * Render a link to a source file.
64+ */
65+ public function linkSourceFile (Environment $ twig , string $ file , int $ line ): string
66+ {
67+ $ text = str_replace ('\\' , '/ ' , $ file );
68+ if (str_starts_with ($ text , $ this ->projectDir )) {
69+ $ text = substr ($ text , \strlen ($ this ->projectDir ));
70+ }
71+ $ link = $ this ->fileLinkFormat ->format ($ file , $ line );
72+
73+ return sprintf ('<a href="%s" title="Click to open this file" class="file_link">%s</a> at line %d ' ,
74+ htmlspecialchars ($ link , \ENT_COMPAT | \ENT_SUBSTITUTE , $ twig ->getCharset ()),
75+ htmlspecialchars ($ text , \ENT_COMPAT | \ENT_SUBSTITUTE , $ twig ->getCharset ()),
76+ $ line ,
77+ );
78+ }
79+
4880 /**
4981 * @param string|TemplateWrapper $template
5082 */
0 commit comments