addExtension($root_path . '/core'); array_map([$this, 'addExtension'], $module_handler->getModuleDirectories()); array_map([$this, 'addExtension'], $theme_handler->getThemeDirectories()); } /** * Adds an extensions help_topics directory to the Twig loader. * * @param $path * The path to the extension. */ protected function addExtension($path) { $path .= DIRECTORY_SEPARATOR . 'help_topics'; if (is_dir($path)) { $this->cache = $this->errorCache = []; $this->paths[self::MAIN_NAMESPACE][] = rtrim($path, '/\\'); } } /** * {@inheritdoc} */ public function getSourceContext(string $name): Source { $path = $this->findTemplate($name); $contents = file_get_contents($path); try { // Note: always use \Drupal\Core\Serialization\Yaml here instead of the // "serializer.yaml" service. This allows the core serializer to utilize // core related functionality which isn't available as the standalone // component based serializer. $front_matter = new FrontMatter($contents, Yaml::class); // Reconstruct the content if there is front matter data detected. Prepend // the source with {% line \d+ %} to inform Twig that the source code // actually starts on a different line past the front matter data. This is // particularly useful when used in error reporting. if ($front_matter->getData() && ($line = $front_matter->getLine())) { $contents = "{% line $line %}" . $front_matter->getContent(); } } catch (InvalidDataTypeException $e) { throw new LoaderError(sprintf('Malformed YAML in help topic "%s": %s.', $path, $e->getMessage())); } return new Source($contents, $name, $path); } /** * {@inheritdoc} */ protected function findTemplate($name, $throw = TRUE) { if (!str_ends_with($name, '.html.twig')) { if (!$throw) { return NULL; } $extension = pathinfo($name, PATHINFO_EXTENSION); throw new LoaderError(sprintf("Help topic %s has an invalid file extension (%s). Only help topics ending .html.twig are allowed.", $name, $extension)); } return parent::findTemplate($name, $throw); } }