function _potx_parse_twig_file in Translation template extractor 8
Same name and namespace in other branches
- 6.3 potx.inc \_potx_parse_twig_file()
- 7.3 potx.inc \_potx_parse_twig_file()
- 7.2 potx.inc \_potx_parse_twig_file()
Parse a Twig template for translatables. Drupal 8+.
2 calls to _potx_parse_twig_file()
- _potx_process_file in ./
potx.inc - Process a file and put extracted information to the given parameters.
- _potx_process_inline_templates in ./
potx.inc - Process Twig inline templates inside PHP files. Drupal 8+.
File
- ./
potx.inc, line 1960 - Extraction API used by the web and command line interface.
Code
function _potx_parse_twig_file($code, $file, $save_callback) {
// Extract front-matter data, and save text in certain ones.
$keys_to_save = [
'label',
];
// Implementation copied from core's \Drupal\help_topics\FrontMatter class.
$fm_separator = '---';
$fm_regexp = '/\\A(' . $fm_separator . '(.*?)?\\R' . $fm_separator . ')(\\R.*)?\\Z/s';
// Check for front matter data.
$len = strlen($fm_separator);
$matches = [];
if (substr($code, 0, $len + 1) === $fm_separator . "\n" || substr($code, 0, $len + 2) === $fm_separator . "\r\n") {
preg_match($fm_regexp, $code, $matches);
$matches = array_map('trim', $matches);
}
if (!empty($matches[1])) {
// Set the extracted source code.
$code = $matches[3];
try {
$metadata = Yaml::parse($matches[2]);
foreach ($metadata as $key => $content) {
if (in_array($key, $keys_to_save, TRUE)) {
$save_callback(_potx_format_quoted_string('"' . trim($content) . '"'), POTX_CONTEXT_NONE, $file, 1);
break;
}
}
} catch (ParseException $e) {
potx_status('error', t("YAML parsing error on file @path: @error", [
'@path' => $file,
'@error' => $e
->getMessage(),
]), $file);
}
}
if (Environment::MAJOR_VERSION < 2) {
$twig_lexer = new Lexer(new Environment());
}
else {
// For D9 and superior the environment needs a loader.
$twigLoader = new FilesystemLoader();
$twig_lexer = new Lexer(new Environment($twigLoader));
}
try {
$source = new Source($code, $file);
$stream = $twig_lexer
->tokenize($source);
} catch (SyntaxError $e) {
potx_status('error', t("Twig parsing error on file @path: @error", [
'@path' => $file,
'@error' => $e
->getMessage(),
]), $file);
return;
}
while (!$stream
->isEOF()) {
$token = $stream
->next();
// Capture strings translated with the t or trans filter.
if ($token
->test(Twig_Token::NAME_TYPE)) {
$token = $stream
->next();
if ($token
->test(Twig_Token::OPERATOR_TYPE, '=')) {
$token = $stream
->next();
if ($token
->test(Twig_Token::STRING_TYPE)) {
_potx_process_twig_t_filter($token, $stream, $file, $save_callback);
}
}
}
elseif ($token
->test(Twig_Token::VAR_START_TYPE)) {
$token = $stream
->next();
if ($token
->test(Twig_Token::NAME_TYPE)) {
continue;
}
$string = $token
->getValue();
$line = $token
->getLine();
$has_t = FALSE;
$chained = FALSE;
$is_concat = FALSE;
if ($stream
->test(Twig_Token::PUNCTUATION_TYPE, '.')) {
$is_concat = TRUE;
}
while (!$stream
->isEOF() && ($token = $stream
->next()) && !$token
->test(Twig_Token::VAR_END_TYPE)) {
if ($token
->test(Twig_Token::PUNCTUATION_TYPE, '|')) {
if ($stream
->test([
't',
'trans',
])) {
$has_t = TRUE;
}
else {
$chained = TRUE;
}
}
}
if ($has_t) {
if (!$chained && !$is_concat) {
$save_callback(_potx_format_quoted_string('"' . trim($string) . '"'), POTX_CONTEXT_NONE, $file, $line);
}
else {
$message = t('Uses of the t filter in Twig templates should start with a single literal string, and should not be chained.');
// TODO: Fill in specific URL for Twig documentation once it exists.
potx_status('error', $message, $file, NULL, NULL, 'https://drupal.org/developing/api/localization');
}
}
}
elseif ($token
->test(Twig_Token::BLOCK_START_TYPE)) {
$token = $stream
->next();
if ($token
->test('trans')) {
_potx_process_twig_trans_tag($stream, $file, $save_callback);
}
}
elseif ($token
->test(Twig_Token::STRING_TYPE)) {
_potx_process_twig_t_filter($token, $stream, $file, $save_callback);
}
}
}