Find all twig templates and bolt php code, extract translatables strings, merge with existing translations.
519915
private function gatherTranslatableStrings()
    {
        $this->translatables = [];

        $this->scanTwigFiles();
        $this->scanPhpFiles();

        ksort($this->translatables);
    }
404531
protected function translations()
    {
        $translations = collect($this->getFiles(resource_path('lang/')))->flatMap(function ($file) {
            return [
                ($translation = $file->getBasename('.php')) => trans($translation),
            ];
        });

        return $translations->merge($this->packageTranslations());
    }
114124
public function actionUpdate()
    {
        
        $this->outVerbose("Updating language '" . $this->options['language'] . "' for extension '" . $this->options['extension'] . "'...");
        $sortingMethod = tao_helpers_translation_TranslationFile::SORT_ASC_I;
        
       	// Get virgin translations from the source code and manifest.
       	$filePaths = array();
        foreach (self::$WHITE_LIST as $subFolder) {
            $filePaths[] = $this->options['input'] . DIRECTORY_SEPARATOR. $subFolder;
        }
        
       	$extensions = array('php', 'tpl', 'js', 'ejs');
       	$sourceCodeExtractor = new tao_helpers_translation_SourceCodeExtractor($filePaths, $extensions);
       	$sourceCodeExtractor->extract();
    	
       	$translationFile = new tao_helpers_translation_POFile();
        $translationFile->setSourceLanguage(tao_helpers_translation_Utils::getDefaultLanguage());
        $translationFile->setTargetLanguage($this->options['language']);
       	$translationFile->addTranslationUnits($sourceCodeExtractor->getTranslationUnits());
       	
        $file = MenuService::getStructuresFilePath($this->options['extension']);
        if (!is_null($file)) {
            $structureExtractor = new tao_helpers_translation_StructureExtractor(array($file));
           	$structureExtractor->extract();
            $structureUnits = $structureExtractor->getTranslationUnits();
            $this->outVerbose(count($structureUnits) . ' units extracted from structures.xml.');
            $translationFile->addTranslationUnits($structureUnits);
        }

       	// For each TU that was recovered, have a look in an older version
       	// of the translations.
       	$oldFilePath = $this->buildLanguagePath($this->options['extension'], $this->options['language']) . '/' .self::DEF_PO_FILENAME;
       	$translationFileReader = new tao_helpers_translation_POFileReader($oldFilePath);
       	$translationFileReader->read();
       	$oldTranslationFile = $translationFileReader->getTranslationFile();
       	
       	foreach ($oldTranslationFile->getTranslationUnits() as $oldTu) {
       		if (($newTu = $translationFile->getBySource($oldTu)) !== null && $oldTu->getTarget() != '') {
       			// No duplicates in TFs so I simply add it whatever happens.
       			// If it already has the same one, it means we will update it.
       			$newTu->setTarget($oldTu->getTarget());
       		}
       	}
        
       	$sortedTranslationFile = new tao_helpers_translation_POFile();
        $sortedTranslationFile->setSourceLanguage($translationFile->getSourceLanguage());
        $sortedTranslationFile->setTargetLanguage($translationFile->getTargetLanguage());
       	$sortedTranslationFile->addTranslationUnits($translationFile->sortBySource($sortingMethod));
       	$this->preparePOFile($sortedTranslationFile, true);
       	
       	// Write the new ones.
       	$poFileWriter = new tao_helpers_translation_POFileWriter($oldFilePath, $sortedTranslationFile);
       	$poFileWriter->write();
        $this->outVerbose("PO translation file '" . basename($oldFilePath) . "' in '" . $this->options['language'] . "' updated for extension '" . $this->options['extension'] . "'.");

		$translatableProperties = array(OntologyRdfs::RDFS_LABEL, OntologyRdfs::RDFS_COMMENT);

		// We now deal with RDF models.
        foreach ($this->getOntologyFiles() as $f){
                // Loop on 'master' models.
				$translationFile = $this->extractPoFileFromRDF($f, $translatableProperties);

                // The slave RDF file is the translation of the ontology that we find in /extId/Locales/langCode.
                $slavePOFilePath = $this->buildLanguagePath($this->options['extension'], $this->options['language']) . '/' . $this->getOntologyPOFileName($f);
                if (file_exists($slavePOFilePath)){
                    // Read the existing RDF Translation file for this RDF model.
                    $poReader = new tao_helpers_translation_POFileReader($slavePOFilePath);
                    $poReader->read();
                    $slavePOFile = $poReader->getTranslationFile();
                    
                    // Try to update translation units found in the master PO file with
                    // targets found in the old translation of the ontology.
                    foreach ($slavePOFile->getTranslationUnits() as $oTu){
                        $translationFile->addTranslationUnit($oTu);
                    }
                    
                    // Remove Slave PO file. It will be overwritten by the modified Master PO file.
                    tao_helpers_File::remove($slavePOFilePath);
                }
                
                // Write Master PO file as the new Slave PO file.
                $rdfWriter = new tao_helpers_translation_POFileWriter($slavePOFilePath, $translationFile);
                $rdfWriter->write();
                $this->outVerbose("Translation model {$this->getOntologyPOFileName($f)}  in '" . $this->options['language'] . "' updated for extension '" . $this->options['extension'] . "'.");
        }
        
       	$this->outVerbose("Language '" . $this->options['language'] . "' updated for extension '" . $this->options['extension'] . "'.");
        
    }
818281
private function findTemplate(string $name)
    {
        if (!preg_match(sprintf('|^%s|', preg_quote(self::PREFIX)), $name)) {
            $prefix = self::PREFIX;
            throw new \Twig_Error_Loader("Only supported template starts with $prefix.");
        }

        if ($template = $this->repository->findTemplate($this->getTemplateName($name))) {
            $this->definedTranslation->addTranslations($template);

            return $template;
        }

        throw new \Twig_Error_Loader("Not found template named $name.");
    }
122345
public function lang($name, $vars = [], $template = self::USE_NOT_TPL) {
        $request = Request::instance();
        $config = $this->resolve(RESOLVE_LANG, $name);
        $name = $config[1];
        $config = $config[0];

        if (isset($config[$request->lang][$name])) {
            if ($template == self::USE_NOT_TPL) {
                if (count($vars) == 0) {
                    return $config[$request->lang][$name];
                }
                else {
                    $content = $config[$request->lang][$name];

                    foreach ($vars as $key => $value) {
                        $content = preg_replace('#\{' . $key . '\}#isU', $value, $content);
                    }

                    return $content;
                }
            }
            else {
                $tpl = new Template($config[$request->lang][$name], $name, 0, Template::TPL_STRING);
                $tpl->assign($vars);

                return $tpl->show(Template::TPL_COMPILE_TO_STRING, Template::TPL_COMPILE_LANG);
            }
        }
        else {
            $this->addError('sentence ' . $name . '/' . $request->lang . ' not found', __FILE__, __LINE__, ERROR_WARNING);

            return 'sentence not found (' . $name . ',' . $request->lang . ')';
        }
    }
634119
private function parsePathTranslations($domains)
    {
        $translations = array();
        if (!empty($domains)) {
            foreach ($domains as $domain => $paths) {
                if (strlen($domain) && array_key_exists('template', $paths)) {
                    $this->addPath($paths['template'], $domain);
                    $translations[] = $this->generateTemplate($paths['template'], $domain);
                }
            }
        }

        return $translations;
    }
590702
protected function loadTemplates()
	{
		$loader = new \Twig_Loader_Filesystem(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'templates');
		$this->twigEnv = new Twig_Environment($loader, ['cache' => false, 'debug' => true]);
		$this->twigEnv->addExtension(new Twig_Extension_Debug());

		// Custom filter for phpdoc
		$filter = new \Twig_Filter('phpdoc', function($string, $indentationCount = 0, $indentChar = "\t") {
			$result = str_repeat($indentChar, $indentationCount) . '/**' . "\n";
			// Split per line
			$lines = explode("\n", trim($string));
			foreach ($lines as $line) {
				$result .= str_repeat($indentChar, $indentationCount) . ' * ' . $line . "\n";
			}
			$result .= str_repeat($indentChar, $indentationCount) . ' */' . "\n";
			return $result;
		});

		$this->twigEnv->addFilter($filter);

		$this->managerTemplate = $this->twigEnv->load('manager.php.twig');
		$this->resourceTemplate = $this->twigEnv->load('resource.php.twig');
		$this->mainClientTemplate = $this->twigEnv->load('mainClient.php.twig');
		$this->mainExceptionTemplate = $this->twigEnv->load('mainException.php.twig');
		$this->unexpectedResponseExceptionTemplate = $this->twigEnv->load('unexpectedResponseException.php.twig');

		if (!is_null($this->testsOutputPath)) {
			$this->mainClientTestTemplate = $this->twigEnv->load('mainClientTest.php.twig');
			$this->managerTestTemplate = $this->twigEnv->load('managerTest.php.twig');
		}
	}
129122
public function getTranslations($locale)
    {
        //Default locale
        if (null === $locale) {
            $locale = Config::getParam('default.language', 'es_ES');
        }

        //Generating the templates translations
        $translations = $this->tpl->regenerateTemplates();

        $localePath = realpath(BASE_DIR . DIRECTORY_SEPARATOR . 'locale');
        $localePath .= DIRECTORY_SEPARATOR . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR;

        //xgettext localizations
        $translations = array_merge($translations, GeneratorService::findTranslations(SOURCE_DIR, $locale));
        $translations = array_merge($translations, GeneratorService::findTranslations(CORE_DIR, $locale));
        $translations = array_merge($translations, GeneratorService::findTranslations(CACHE_DIR, $locale));

        $translations[] = "msgfmt {$localePath}translations.po -o {$localePath}translations.mo";
        $translations[] = shell_exec('export PATH=\$PATH:/opt/local/bin:/bin:/sbin; msgfmt '. $localePath . 'translations.po -o ' . $localePath . 'translations.mo');
        return $this->render('translations.html.twig', array(
            'translations' => $translations,
        ));
    }
551033
def translate_with_context(key, options={})
      # default to an empty scope
      scope = []

      # Use the template for scoping if there is a templ
      unless self.template.nil?
        # The outer scope will typically be the controller name ("blog_posts")
        # but can also be a dir of shared partials ("shared").
        outer_scope = self.template.base_path
        
        # The template will be the view being rendered ("show.erb" or "_ad.erb")
        inner_scope = self.template.name
        
        # Partials template names start with underscore, which should be removed
        inner_scope.sub!(/^_/, '')

        scope = [outer_scope, inner_scope]
      end
      
      # In the case of a missing translation, fall back to letting TranslationHelper
      # put in span tag for a translation_missing.
      begin
        Translator.translate_with_scope(scope, key, options.merge({:raise => true}))
      rescue Translator::TranslatorError, I18n::MissingTranslationData => exc
        # Call the original translate method
        str = translate_without_context(key, options)
        
        # View helper adds the translation missing span like:
        # In strict mode, do not allow TranslationHelper to add "translation missing" span like:
        # <span class="translation_missing">en, missing_string</span>
        if str =~ /span class\=\"translation_missing\"/
          # In strict mode, do not allow TranslationHelper to add "translation missing"
          raise if Translator.strict_mode?
          
          # Invoke callback if it is defined
          Translator.missing_translation_callback(exc, key, options)
        end

        str
      end
    end
922567
protected function buildTemplateIndex()
    {
        // We'll iterate the template paths and find
        // any routable templates. Note that if there is
        // more than one directory, the earlier directories
        // are checked first, then on down the stack to
        // mimic the behavior of Twig_Loader_Filesystem.

        if (false === $this->templateIndexBuilt) {
            foreach ($this->templatePath as $path) {
                $dir = new \RecursiveDirectoryIterator($path);
                $it = new \RecursiveIteratorIterator($dir);

                foreach ($it as $template_file) {
                    if ($this->validateTemplate($template_file)) {

                        // Strip the path from the template file relative to
                        // the root template directory to get the template "route"
                        $template_full_path = $template_file->getPathname();
                        $template_rel_path = str_replace($path, '', $template_full_path);
                        $template_route = '/' . $template_rel_path;

                        if (!array_key_exists($template_route, $this->templateIndex)) {
                            $this->debug(sprintf('buildTemplateIndex: Routable Template %s Found at %s.', $template_rel_path, $template_full_path));

                            $template = new Template($template_rel_path, $template_full_path);
                            $this->templateIndex[$template_route] = $template;
                        }
                    }
                }
            }

            $this->templateIndexBuilt = true;
        }
    }
339646
function transformTemplates(templates) {
  const allTemplates = {
    ...templates,
    submit: templates.searchableSubmit,
    reset: templates.searchableReset,
    loadingIndicator: templates.searchableLoadingIndicator,
  };

  const {
    searchableReset,
    searchableSubmit,
    searchableLoadingIndicator,
    ...transformedTemplates
  } = allTemplates;

  return transformedTemplates;
}
355308
public function addTranslationFunctions($twig)
    {
        $twig->addFunction('_x', new Twig_SimpleFunction('_x',
            function ($text, $context, $domain = 'default') {
                return _x($text, $context, $domain);
            }
        ));

        $twig->addFunction('_n', new Twig_SimpleFunction('_n',
            function ($single, $plural, $number, $domain = 'default') {
                return _n($single, $plural, $number, $domain);
            }
        ));

        $twig->addFunction('_nx', new Twig_SimpleFunction('_nx',
            function ($single, $plural, $number, $context, $domain = 'default') {
                return _nx($single, $plural, $number, $context, $domain);
            }
        ));

        return $twig;
    }
648894
public function actionCompileAll()
    {
        
        // Get the list of languages that will be compiled.
        $this->outVerbose("Compiling all languages for extension '" . $this->options['extension'] . "'...");
        
        $rootDir = ROOT_PATH;
        $extensionDir = $rootDir . '/' . $this->options['extension'];
        $localesDir = $extensionDir . '/locales';
        $locales = array();
        
        $directories = scandir($localesDir);
        if ($directories === false) {
            $this->err("The locales directory of extension '" . $this->options['extension'] . "' cannot be read.", true);    
        } else {
            foreach ($directories as $dir) {
                if ($dir[0] !== '.') {
                    // It is a language directory.
                    $locales[] = $dir;
                }
            }
        }
        
        foreach ($locales as $l) {
            $this->options['language'] = $l;
            $this->checkCompileInput();
            $this->actionCompile();
            
            $this->outVerbose("");
        }
        
    }
1278713
function translateTemplates(templates) {
    var result = [];
    for (var _i = 0, templates_1 = templates; _i < templates_1.length; _i++) {
        var temp = templates_1[_i];
        var col = {};
        var props = Object.getOwnPropertyNames(temp);
        for (var _a = 0, props_1 = props; _a < props_1.length; _a++) {
            var prop = props_1[_a];
            col[prop] = temp[prop];
        }
        if (temp.headerTemplate) {
            col.headerTemplate = temp.headerTemplate;
        }
        if (temp.cellTemplate) {
            col.cellTemplate = temp.cellTemplate;
        }
        if (temp.summaryFunc) {
            col.summaryFunc = temp.summaryFunc;
        }
        if (temp.summaryTemplate) {
            col.summaryTemplate = temp.summaryTemplate;
        }
        result.push(col);
    }
    return result;
}
408242
protected function parseTemplate($variables = [], $template = null)
    {
        if (null === $template) $template = 'migration';
        $replacements = array_merge($variables, $this->templateVariables);
        return strtr(file_get_contents(dirname(__DIR__) . '/templates/' . $template . '.tpl'), $replacements);
    }
975331
def _get_translation_for_locale(self, locale):
        """"""
        translations = None

        for dirname in self.paths:
            # Load a single catalog.
            catalog = Translations.load(dirname, [locale], domain=self.domain)
            if translations is None:
                if isinstance(catalog, Translations):
                    translations = catalog
                continue

            try:
                # Merge catalog into global catalog
                translations.merge(catalog)
            except AttributeError:
                # Translations is probably NullTranslations
                if isinstance(catalog, NullTranslations):
                    current_app.logger.debug(
                        'Compiled translations seems to be missing'
                        ' in {0}.'.format(dirname))
                    continue
                raise

        return translations or NullTranslations()
789203
protected function collectTranslatable()
    {
        foreach ($this->request->get('translatable', []) as $key => $value) {
            $this->data[$key] = $value;
        }
    }