Auto-generate your languagefiles

Using the i18nTextCollector

Using the i18nTextCollector is simple - and it makes generating languagefiles for your modules a breeze! Make sure there is a /lang/ directory in your module, and make it writable. Then go visit:

http://www.mysite.ext/dev/tasks/i18nTextCollectorTask/?module=mymodule

You have to be logged in as administrator for this to work. The website will now shout: Running task 'i18n Textcollector Task'... and then nothing further seems to happen, but the language file will be created. Each time you run the collector, the file will be recreated, so all changes you might have made will be lost!

Note: before using the TextCollector on existing SilverStripe modules, you might want to have a look at the i18nTextCollector Issues and Tricks at the bottom of this page

How does it work?

The i18nTextCollector will search trough every class and every template to collect translations, and there are two different ways it can do that:

  • use every implementation of the _t( ... ) function it can find, and extract languagefile entries from that
  • look for the existance of the provideI18nEntities() method that provides extra languagefile entries

Note: To do this, it doesn't just search plain text, but instead instatiates classes, so you need to make sure they are valid, and every include is present!  

provideI18nEntities()

The provideI18nEntities() method is available in any class that implements the i18nEntityProvider interface. It is present in the DataObject and the SiteTree class, and can be extended in every subclass. The following is a very simple example, but the possibilities go much futher than that (have a look at 'Translating statics, fields and labels'.

class Page extends SiteTree implements i18nEntityProvider {

i18nEntityProvider...

	function provideI18nEntities() {

		$entities = parent::provideI18nEntities();
 		$entities["MyPage.SomeValue"] = array('Some Translation');
		return $entities;
	}

This will create the following entry in your languagefile:

$lang['en_US']['MyPage']['SomeValue'] = 'Some Translation'; 

There are some extra params that you can add to the entitty, which I don't really use - some examples are available in the SilverStripe API docs.

 The i18nTextCollector -issues and tricks

PHPUnit…

The SilverStripe docs state that you have to have the phpUnit testing framework installed to run the i18nTextCollector, but that's not entirely true: it is only necessary for modules that include PHPUnit. That's because the i18nTextCollector will instantiate each php class, so all included files need to be present to avoid errors…

Collecting mysite...

Mysite is probably the one 'core' module you'll want to collect, but there's an issue! For some reason the provideI18nEntities() method in the SiteTree class is set up to create entries for the Page's 'PLURALNAME' and 'SINGULARNAME' in the sapphire language file - where it would normally go to one in mysite. So when you start the i18TextCollector for the mysite module, it immediately wants to overwrite the sapphire file as well, creating just the two entries. That you definitely don't want.

Collecting for one module shouldn't reallyaffect other modules and I have as yet found no obvious reason why these entities can't exist in the mysite language file where the Page class resides. So I override the method in the Page class:

function provideI18nEntities() {
	$entities = parent::provideI18nEntities();

	if(isset($entities['Page.SINGULARNAME']))
		$entities['Page.SINGULARNAME'][3] = mysite';

	if(isset($entities['Page.PLURALNAME']))
		$entities['Page.PLURALNAME'][3] = 'mysite';

	return $entities;
}

Collecting sapphire...

Not everyone will want to create new languagefiles for sapphire or the cms, but if you want to - sapphire is the one module where the textcollector will stumble on files that use PHPUnit, like most files in the sapphire/dev folder. So you either need to install the framework - or do a quick search on files that include it and disable - I don't recall that being too much work…

Collecting cms...

As of rev. 105996 all now goes well. In older versions the following might still happen, so I'll leave it in for a while:

When performing a textCollection on the cms module, something weird happens concerning the translations for the main menu items in the CMS. These are not written to the cms language file, but an extra languagefile is created in a folder called 0 in the website root. Thes translations can be copied to the sapphire folder, and the new 0 folder then be removed:

$lang['en_US']['AssetAdmin']['MENUTITLE'] ='Files & Images';
$lang['en_US']['CMSMain']['MENUTITLE'] = 'Pages';
$lang['en_US']['CommentAdmin']['MENUTITLE'] = 'Comments';
$lang['en_US']['ReportAdmin']['MENUTITLE'] = 'Reports';
$lang['en_US']['SecurityAdmin']['MENUTITLE'] = 'Security';
$lang['en_US']['ModelAdmin']['MENUTITLE'] = 'ModelAdmin';

Collecting a theme...

A theme is technically not a module, so it can't be collected. Still there might be translations within it's templates, that need collecting. One way to overcome this is:

  1. copy the theme itself to the root of the website
  2. create a _config.php file so SilverStripe thinks it's a module
  3. make the theme writable or create a writable lang directory
  4. create an empty code/ directory within the theme
  5. perform textCollection
  6. copy the translations from the new en_US.php file to the one in mysite or some other module
  7.  remove the copied  theme from the website root

TODO: remember if I thoroughly tested this - but don't let it keep you from trying…

Comments

Het versturen van reacties is uitgeschakeld.

RSS feed voor reacties op deze pagina