navigation module causing twig error due to use of colon in filename

Created on 21 November 2024, 1 day ago

Problem/Motivation

Facing an issue with your Drupal 11 installation on a Windows system, where Twig template caching fails due to the following:

1. **Invalid Characters in File Paths:** Some filenames generated by Twig contain invalid characters, such as colons (`:`), which are not allowed in Windows file systems.

2. **Permission Issues:** Drupal cannot create directories or rename files in the `sites/default/files/php/twig` directory due to insufficient write permissions.

3. **Path Length Limitation:** The file paths may exceed Windows' default maximum path length of 260 characters, causing failures during file operations.

These issues result in errors like `rename(): The system cannot find the path specified` and `mkdir(): Permission Denied`, preventing Twig from saving cached files.

Steps to reproduce

Proposed resolution

i tried adding :

$settings['twig_settings'] = [
'hash_filename' => TRUE,
];

and clearing cache, to no avail.
when i disable the navigation module, error is gone.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Active

Version

11.0 🔥

Component

toolbar.module

Created by

🇯🇴Jordan bmustafa

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @bmustafa
  • 🇯🇴Jordan bmustafa

    this is the content of the twig file that fails to be renamed into the subfolder under files/php/twig/...

    <?php
    
    use Twig\Environment;
    use Twig\Error\LoaderError;
    use Twig\Error\RuntimeError;
    use Twig\Extension\CoreExtension;
    use Twig\Extension\SandboxExtension;
    use Twig\Markup;
    use Twig\Sandbox\SecurityError;
    use Twig\Sandbox\SecurityNotAllowedTagError;
    use Twig\Sandbox\SecurityNotAllowedFilterError;
    use Twig\Sandbox\SecurityNotAllowedFunctionError;
    use Twig\Source;
    use Twig\Template;
    use Twig\TemplateWrapper;
    
    /* navigation:toolbar-button */
    class __TwigTemplate_3f53f98db4a201dcd7a99fc0f37dfa04 extends Template
    {
        private Source $source;
        /**
         * @var array<string, Template>
         */
        private array $macros = [];
    
        public function __construct(Environment $env)
        {
            parent::__construct($env);
    
            $this->source = $this->getSourceContext();
    
            $this->parent = false;
    
            $this->blocks = [
                'content' => [$this, 'block_content'],
            ];
            $this->sandbox = $this->extensions[SandboxExtension::class];
            $this->checkSecurity();
        }
    
        protected function doDisplay(array $context, array $blocks = []): iterable
        {
            $macros = $this->macros;
            // line 1
            yield $this->extensions['Drupal\Core\Template\TwigExtension']->renderVar($this->extensions['Drupal\Core\Template\TwigExtension']->attachLibrary("core/components.navigation--toolbar-button"));
            yield $this->extensions['Drupal\Core\Template\TwigExtension']->renderVar($this->extensions['Drupal\Core\Template\ComponentsTwigExtension']->addAdditionalContext($context, "navigation:toolbar-button"));
            yield $this->extensions['Drupal\Core\Template\TwigExtension']->renderVar($this->extensions['Drupal\Core\Template\ComponentsTwigExtension']->validateProps($context, "navigation:toolbar-button"));
            // line 4
            $context["classes"] = ["toolbar-button", ((        // line 6
    ($context["icon"] ?? null)) ? (("toolbar-button--icon--" . $this->sandbox->ensureToStringAllowed(($context["icon"] ?? null), 6, $this->source))) : (""))];
            // line 9
            yield "
    ";
            // line 10
            if (is_iterable(($context["modifiers"] ?? null))) {
                // line 11
                yield "  ";
                $context["classes"] = Twig\Extension\CoreExtension::merge($this->sandbox->ensureToStringAllowed(($context["classes"] ?? null), 11, $this->source), Twig\Extension\CoreExtension::map($this->env, $this->sandbox->ensureToStringAllowed(($context["modifiers"] ?? null), 11, $this->source), function ($__modifier__) use ($context, $macros) { $context["modifier"] = $__modifier__; return ("toolbar-button--" . $this->sandbox->ensureToStringAllowed(($context["modifier"] ?? null), 11, $this->source)); }));
            }
            // line 13
            yield "
    ";
            // line 14
            if (is_iterable(($context["extra_classes"] ?? null))) {
                // line 15
                yield "  ";
                $context["classes"] = Twig\Extension\CoreExtension::merge($this->sandbox->ensureToStringAllowed(($context["classes"] ?? null), 15, $this->source), $this->sandbox->ensureToStringAllowed(($context["extra_classes"] ?? null), 15, $this->source));
            }
            // line 17
            yield "
    ";
            // line 18
            if ((($context["text"] ?? null) && (Twig\Extension\CoreExtension::length($this->env->getCharset(), ($context["text"] ?? null)) > 1))) {
                // line 19
                yield "  ";
                // line 21
                yield "  ";
                $context["icon_text"] = Twig\Extension\CoreExtension::join(Twig\Extension\CoreExtension::slice($this->env->getCharset(), $this->sandbox->ensureToStringAllowed(($context["text"] ?? null), 21, $this->source), 0, 2), "");
                // line 22
                yield "  ";
                $context["attributes"] = CoreExtension::getAttribute($this->env, $this->source, CoreExtension::getAttribute($this->env, $this->source, ($context["attributes"] ?? null), "setAttribute", ["data-index-text", Twig\Extension\CoreExtension::lower($this->env->getCharset(), Twig\Extension\CoreExtension::first($this->env->getCharset(), $this->sandbox->ensureToStringAllowed(($context["text"] ?? null), 22, $this->source)))], "method", false, false, true, 22), "setAttribute", ["data-icon-text", ($context["icon_text"] ?? null)], "method", false, false, true, 22);
            }
            // line 24
            yield "
    <";
            // line 25
            yield $this->extensions['Drupal\Core\Template\TwigExtension']->escapeFilter($this->env, ((array_key_exists("html_tag", $context)) ? (Twig\Extension\CoreExtension::default($this->sandbox->ensureToStringAllowed(($context["html_tag"] ?? null), 25, $this->source), "button")) : ("button")), "html", null, true);
            yield " ";
            yield $this->extensions['Drupal\Core\Template\TwigExtension']->escapeFilter($this->env, $this->sandbox->ensureToStringAllowed(CoreExtension::getAttribute($this->env, $this->source, ($context["attributes"] ?? null), "addClass", [($context["classes"] ?? null)], "method", false, false, true, 25), 25, $this->source), "html", null, true);
            yield ">
      ";
            // line 26
            if (($context["action"] ?? null)) {
                // line 27
                yield "    <span data-toolbar-action class=\"visually-hidden\">";
                yield $this->extensions['Drupal\Core\Template\TwigExtension']->escapeFilter($this->env, $this->sandbox->ensureToStringAllowed(($context["action"] ?? null), 27, $this->source), "html", null, true);
                yield "</span>
      ";
            }
            // line 29
            yield "  ";
            yield from $this->unwrap()->yieldBlock('content', $context, $blocks);
            // line 34
            yield "
    </";
            // line 35
            yield $this->extensions['Drupal\Core\Template\TwigExtension']->escapeFilter($this->env, ((array_key_exists("html_tag", $context)) ? (Twig\Extension\CoreExtension::default($this->sandbox->ensureToStringAllowed(($context["html_tag"] ?? null), 35, $this->source), "button")) : ("button")), "html", null, true);
            yield ">
    ";
            $this->env->getExtension('\Drupal\Core\Template\TwigExtension')
                ->checkDeprecations($context, ["icon", "modifiers", "modifier", "extra_classes", "text", "html_tag", "action"]);        yield from [];
        }
    
        // line 29
        /**
         * @return iterable<null|scalar|\Stringable>
         */
        public function block_content(array $context, array $blocks = []): iterable
        {
            $macros = $this->macros;
            // line 30
            yield "    ";
            if (($context["text"] ?? null)) {
                // line 31
                yield "      <span class=\"toolbar-button__label\" data-toolbar-text>";
                yield $this->extensions['Drupal\Core\Template\TwigExtension']->escapeFilter($this->env, $this->sandbox->ensureToStringAllowed(($context["text"] ?? null), 31, $this->source), "html", null, true);
                yield "</span>
        ";
            }
            // line 33
            yield "  ";
            yield from [];
        }
    
        /**
         * @codeCoverageIgnore
         */
        public function getTemplateName(): string
        {
            return "navigation:toolbar-button";
        }
    
        /**
         * @codeCoverageIgnore
         */
        public function isTraitable(): bool
        {
            return false;
        }
    
        /**
         * @codeCoverageIgnore
         */
        public function getDebugInfo(): array
        {
            return array (  131 => 33,  125 => 31,  122 => 30,  115 => 29,  107 => 35,  104 => 34,  101 => 29,  95 => 27,  93 => 26,  87 => 25,  84 => 24,  80 => 22,  77 => 21,  75 => 19,  73 => 18,  70 => 17,  66 => 15,  64 => 14,  61 => 13,  57 => 11,  55 => 10,  52 => 9,  50 => 6,  49 => 4,  45 => 1,);
        }
    
        public function getSourceContext(): Source
        {
            return new Source("", "navigation:toolbar-button", "D:\\wamp64\\www\\seo_oxygen_backoffice\\drupal11/core/modules/navigation\\components\\toolbar-button\\toolbar-button.twig");
        }
        
        public function checkSecurity()
        {
            static $tags = array("set" => 4, "if" => 10, "block" => 29);
            static $filters = array("merge" => 11, "map" => 11, "length" => 18, "join" => 21, "slice" => 21, "lower" => 22, "first" => 22, "escape" => 25, "default" => 25);
            static $functions = array();
    
            try {
                $this->sandbox->checkSecurity(
                    ['set', 'if', 'block'],
                    ['merge', 'map', 'length', 'join', 'slice', 'lower', 'first', 'escape', 'default'],
                    [],
                    $this->source
                );
            } catch (SecurityError $e) {
                $e->setSourceContext($this->source);
    
                if ($e instanceof SecurityNotAllowedTagError && isset($tags[$e->getTagName()])) {
                    $e->setTemplateLine($tags[$e->getTagName()]);
                } elseif ($e instanceof SecurityNotAllowedFilterError && isset($filters[$e->getFilterName()])) {
                    $e->setTemplateLine($filters[$e->getFilterName()]);
                } elseif ($e instanceof SecurityNotAllowedFunctionError && isset($functions[$e->getFunctionName()])) {
                    $e->setTemplateLine($functions[$e->getFunctionName()]);
                }
    
                throw $e;
            }
    
        }
    }
    
Production build 0.71.5 2024