function LocaleJs::parseJsFile
Same name and namespace in other branches
- main core/modules/locale/src/LocaleJs.php \Drupal\locale\LocaleJs::parseJsFile()
Parses a JavaScript file, extracts translatable strings, and saves them.
Strings are extracted from both Drupal.t() and Drupal.formatPlural().
@internal
Parameters
string $filepath: File name to parse.
Throws
\Exception If a non-local file is attempted to be parsed.
1 call to LocaleJs::parseJsFile()
- LocaleJs::jsTranslate in core/
modules/ locale/ src/ LocaleJs.php - Returns a list of translation files given a list of JavaScript files.
File
-
core/
modules/ locale/ src/ LocaleJs.php, line 150
Class
- LocaleJs
- Provides the locale javascript related methods.
Namespace
Drupal\localeCode
public function parseJsFile(string $filepath) : void {
// Regular expression pattern used to localize JavaScript strings.
$jsStringRegex = '(?:(?:\'(?:\\\\\'|[^\'])*\'|"(?:\\\\"|[^"])*")(?:\\s*\\+\\s*)?)+';
// Regular expression pattern used to match simple JS object literal.
// This pattern matches a basic JS object, but will fail on an object with
// nested objects. Used in JS file parsing for string arg processing.
$jsObjectRegex = '\\{.*?\\}';
// Regular expression to match an object containing a key 'context'.
// Pattern to match a JS object containing a 'context key' with a string
// value, which is captured. Will fail if there are nested objects.
$jsObjectContextRegex = '
\\{ # match object literal start
.*? # match anything, non-greedy
(?: # match a form of "context"
\'context\'
|
"context"
|
context
)
\\s*:\\s* # match key-value separator ":"
(' . $jsStringRegex . ') # match context string
.*? # match anything, non-greedy
\\} # match end of object literal
';
// The file path might contain a query string, so make sure we only use the
// actual file.
$parsedUrl = UrlHelper::parse($filepath);
$filepath = $parsedUrl['path'];
// If there is still a protocol component in the path, reject that.
if (strpos($filepath, ':')) {
throw new \Exception('Only local files should be passed to LocaleJs::parseJsFile().');
}
// Load the JavaScript file.
$file = file_get_contents($filepath);
// Match all calls to Drupal.t() in an array.
// Note: \s also matches newlines with the 's' modifier.
preg_match_all('~
[^\\w]Drupal\\s*\\.\\s*t\\s* # match "Drupal.t" with whitespace
\\(\\s* # match "(" argument list start
(' . $jsStringRegex . ')\\s* # capture string argument
(?:,\\s*' . $jsObjectRegex . '\\s* # optionally capture str args
(?:,\\s*' . $jsObjectContextRegex . '\\s*) # optionally capture context
?)? # close optional args
[,\\)] # match ")" or "," to finish
~sx', $file, $tMatches);
// Match all Drupal.formatPlural() calls in another array.
preg_match_all('~
[^\\w]Drupal\\s*\\.\\s*formatPlural\\s* # match "Drupal.formatPlural" with whitespace
\\( # match "(" argument list start
\\s*.+?\\s*,\\s* # match count argument
(' . $jsStringRegex . ')\\s*,\\s* # match singular string argument
( # capture plural string argument
(?: # non-capturing group to repeat string pieces
(?:
\'(?:\\\\\'|[^\'])*\' # match single-quoted string with any character except unescaped single-quote
|
"(?:\\\\"|[^"])*" # match double-quoted string with any character except unescaped double-quote
)
(?:\\s*\\+\\s*)? # match "+" with possible whitespace, for str concat
)+ # match multiple because we supports concatenating strs
)\\s* # end capturing of plural string argument
(?:,\\s*' . $jsObjectRegex . '\\s* # optionally capture string args
(?:,\\s*' . $jsObjectContextRegex . '\\s*)? # optionally capture context
)?
[,\\)]
~sx', $file, $pluralMatches);
$matches = [];
// Add strings from Drupal.t().
foreach ($tMatches[1] as $key => $string) {
$matches[] = [
'source' => $this->stripQuotes($string),
'context' => $this->stripQuotes($tMatches[2][$key]),
];
}
// Add string from Drupal.formatPlural().
foreach ($pluralMatches[1] as $key => $string) {
$matches[] = [
'source' => $this->stripQuotes($string) . PoItem::DELIMITER . $this->stripQuotes($pluralMatches[2][$key]),
'context' => $this->stripQuotes($pluralMatches[3][$key]),
];
}
// Loop through all matches and process them.
foreach ($matches as $match) {
$source = $this->localeStorage
->findString($match);
if (!$source) {
// We don't have the source string yet, thus we insert it into the
// database.
$source = $this->localeStorage
->createString($match);
}
// Besides adding the location this will tag it for current version.
$source->addLocation('javascript', $filepath);
$source->save();
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.