gettext() is a translation system written by GNU people and is present on many systems natively. This makes it a good standard to use. Gettext does have some issues especially on PHP and I will outline what I have found here with possible solutions
I now use motranslator which is based on the same technology as gettext because of the following:
- gettext translation file (.mo) is cached by the server and is never refreshed until you restart server, so changes you make will not be seen untill then. Not practical for shared webhosting.
- On Windows gettext will not allow translations to other than default language - There are some untested workarounds but they are messy (Custom Code, Thread Safe?, PHP as FastCGI not as a module)
- On Windows gettext will only read the directory that belongs to the default language meaning all translations need to go in the default local directory to allow translations.
General Gettext
Gettext Tutorials
- How to Build a Multilingual PHP App | Toptal (Good Tut)
- PHP Gettext: Quick Start Guide to Creating Translations Using gettext in PHP (Good Tut)
- PHP internationalization with gettext tutorial - LingoHub - Translation Service Hub (Good Tut)
- Gettext i18n system - LingoHub - Translation Service Hub (Good Tut)
- A Quick Gettext Tutorial
- How to translate using gettext and poedit - YouTube
- PHP and Javascript Internationalization using Gettext and Poedit
- PHP internationalization with gettext tutorial - LingoHub - Translation Service Hub
- Localizing PHP web sites using gettext » Pablo's Development Blog
- Gettext i18n system - internationalization for gettext
- Gettext PO Localization - LingoHub - Translation Service Hub
- php - Gettext: Translation of strings with HTML inside? - Stack Overflow
Gettext Documentation
- GNU gettext - GNU Project - Free Software Foundation
- GNU gettext utilities
- gettext - Wikipedia
- PHP: Gettext - Manual
Gettext software
- GitHub - vslavik/gettext-tools-windows: GNU gettext tools compiled binaries for Windows
- GetText for Windows (Official Source)
- windows - What is msgcat and how to use it - Stack Overflow
- gettext 0.19.8.1 and iconv 1.14 - Binaries for Windows - mlocati - Michele Locati - Has both 32bit and 64bit with static and dll based version. These are kept upto date.
Misc documents
- National Language Support (NLS) API Reference
- php - Is en_UK an illegal locale? - Stack Overflow
- php - List of All Locales and Their Short Codes? - Stack Overflow
- Translate gettext PO Files | Transifex Documentation
- How to Translate With GetText PO and POT Files
- Ruby localization: i18n, g18n, gettext, padrino... - what's the difference? - Stack Overflow
- Why GetText is Better than Rails I18n - Translation.io
- Ruby gettext internationalization tutorial on using the fast_gettext gem
Issues I have found with gettext
It is not straight forward to getting gettext() to workout of the box, especially when using xammp on windows. HEre I will address the issues I came across while trying to get translation to work. These issues probably also appear on diffrent setups.
Apache Gettext Caching issue
When i was developing QWcrm on my windows xammp setup I would make changes to translation strings in th .PO file (via POedit) and these would not get reflected in my software. After a lot of research I discovered that when you run PHP as an Apache module the the getttext translation files upon first load are cached 'premanently' or for a time which I can not figure out. So to get around this I needed to find a way of refreshing the cache or turning it of for my development site.
Solutions I found
- change the .MO filenames loaded when ever you make changes - this works but is a bit of a mess and I would not recommend it for production sites.
- use PHP as Fast CGI. When PHP is loaded as a module the .MO files are cached 'permantely' or for an undisclosed time I can not figure out but this apparently is not the case when using PHP as Fast CGI
- The only true way to clear the cache it to restart apache. I think if you are running PHP as an Apache module, you have to restart Apache for the catalog to be reloaded.
- clearstatcache() - i could not get this to work
I will now outline my research below
Emptying of MO gettext cache without restarting apache links
- server caching of gettext translation files « zenphoto forums - renames the files on change before reload. this is more trick than emptying the cache
- https://blog.ghost3k.net/articles/php/11/gettext-caching-in-php - renames the files on change before reload. this is more trick than emptying the cache
- How to clear php's gettext cache without restart Apache nor change domain? (PHP) - Codedump.io - a few issues here including the use of symbolic links but i could not this to work on windows
- How to clear php's gettext cache without restart Apache nor change domain? - Stack Overflow - a few issues here, symbolic links and clearstatcache()
- PHP gettext caching workaround - renames the files on change before reload. this is more trick than emptying the cache. Also mentions changing the bindtextdomain
Gettext not working on windows / xampp
These following issues can cause a real problem when devloping with gettext on windows. The main issue I came across is the localisation handling.
Issue
- gettext will work but only with the default language/region
- The reason is that the language/region is set for the whole computer and cannot be changed for individual processes. I believe that this is why there are 2 types of apache/php thread safe and non thread safe. I am not 100% how to apply the 2 variants and I dont know of any work aruonds to change the settings just for xampp.
- Windows uses different region codes thant those used by gettext (gettext = de_DE whereas windows = deu)
Solutions
- if you use the standard gettext file layout windows will always be able to access the default language folder. This gives to unique features
- it allows translation to work normally by using the default language (at least you can test gettext is working)
- you can add in the other language translation files into the default language folder and then they can also be used (this is a workaround)
- not confirmed - is this because I do not have the other languages installed on my windows PC - see this thread
You can write code to utilise the workaround outline above by address the locale issue. When trying to fix this do not forget about the caching issue above.
Links
- Getting gettext to work in Apache on windows: Why the stupid script just won't work?
- php - Gettext will always use system default locale - Stack Overflow
- PHP, Apache, MySQL, Windows : WampServer
- PHP: setlocale - Manual
- php - Gettext example not working on Windows 7 - XAMPP - Stack Overflow
- PHP gettext on Windows - Stack Overflow - this outlines that setlocale(LC_MESSAGES, “en_US”); is for linux and putenv(“LC_ALL=en_US”); is for windows
- locale - PHP/Gettext Problems - Stack Overflow
- PHP :: Bug #66265 :: gettext is not working anymore - This has some code to possibly fox the windows regional issue and definately some pointers
- PHP :: Bug #49349 :: gettext behaves differently in php 5.3.0 (5.2.x ignored setlocale errors) - an insight to the history of the issue
xgettext will not scan within double quotes / remmed lines
xgettext is very particular about what it scans for, it seems to be syntax aware rather than just searching for the strings. i.e. if a line is remmed out it will ignore it.
- xgettext cannot extract strings from templates · Issue #622 · tornadoweb/tornado · GitHub
- you cannot put the gettext() or _() on the same lines as an remmed line (i.e. <!-- -->) because they will get ignored.
- Can cause the error unterminated character set constant error but the scanning carries on.
Scanning source files for translations strings
once you have your project done you need to grab all of the strings and translate them, doing this manually would be difficult and you would miss strings. I outline the options I have found below:
- Use software to extract the gettext strings
- Scan .tpl files with specialised scripts
- Compile all smarty templates and then just scan them with POedit. It is not ideal but will work
Applications
- POEdit- will scan your PHP files for standard gettext() strings. It will not scann for {t}..{/t} strings in the .tpl files
- POedit + a custom extractor that will scan the .tpl files. I dont currently have one.
- Eazy Po - Eazy Po is a translation editor and a catalog manager for Gettext translation files.
Smarty TPL Scanning software
- smarty-gettext tsmarty2c.php - the command line utility - This utility will scan templates for {t}...{/t} placeholders for translation strings and output a .pot file (.po template).
- tsmarty2c V2 - this is a custom command line PHP script
Poedit Links
- php - How to make gettext and poedit recognize custom file types? - Stack Overflow - mentions on how to add other file types to the extractors.
- GitHub - umpirsky/Twig-Gettext-Extractor: The Twig Gettext Extractor is Poedit friendly tool which extracts translations from twig templates. Twig Gettext extractor
- How to make gettext and poedit recognize custom file types? - php - smarty - gettext - poedit - TechQA - mentions on how to add other file types to the extractors.
- theme development - How to create .pot files with POedit? - WordPress Development Stack Exchange - covers the subject and mentions Eazy PO.
- php - How to use Poedit with smarty templates? - Stack Overflow - This is very useful and needs looking at further. Shows you how to use PoeditSmarty to create a .pot file.
- Smarty :: View topic - {t} tags and PoEdit parser - This tells you how to run tsmarty2c.php on the command line to output a .pot file. Basically using the > operator to output to a file.
- php - How to use Poedit with smarty templates? - Stack Overflow
- Poedit and smarty parser - A useful example using the command line
- How To Merge Two PO Files Using POEdit | MarketPressThemes
- Extract .po string from .volt file - Discussion - Phalcon Framework
Smarty Poedit Parsers (software) / and other parsers than can potentially be used
- smarty-gettext/smarty-gettext: Gettext plugin enabling internationalization in Smarty Package files. - this tutorial is based on this.
- PoeditSmarty: Gettext extension support for Smarty templates (*.tpl) - Library for syncing gettext catalogs with Smarty sources. Library parses files and writes results as xgettext files, whose are processed by Poedit parser. Soon I will make exe version without java (I dont have so much time)
- smarty-gettext/tsmarty2c: Smarty Gettext Translation String Ripper - a new verions that in not ready?
- GettextParser: Gettext parser for Poedit
- PoeditSmarty: Gettext extension support for Smarty templates (*.tpl) - Java version but source code is not available.
- Jsgettext - A Javascript parser for Poedit written in PHP
- xgettext-js: xgettext string extractor tool capable of parsing JavaScript files - gettext-js is a utility for extracting translatable strings, written in and capable of parsing JavaScript files. It is similar to the GNU xgettext program, but returns strings as a JavaScript array.
Poedit notes
- in version 2 all of the parsers have bve removed and put into 1 extractor which you cannot edit or turn off so you should use version v1.83
- because there are no extractors to see how they are configure i will give you one below. All of the parsers (except TWIG) use xgettext. the only different between the settings are the language name
- Language: Perl
- List of extensions: *.pl;*.PL;*.pm;*.perl;
- Command to extract translations: xgettext --language=Perl --add-comments=TRANSLATORS: --force-po -o %o %C %K %F
- An item in keywords list: -k%k
- An item in input files list: %f
- Source code charset: --from-code=%c
- if you run xgettext --help on the command line you will see all of the switches listed
- in ngettext -o is an alias of --output=FILE and all other switches are similiar.
Compiling all smarty templates
- php - How to use Poedit with smarty templates? - Stack Overflow - this also has some code to help with this option of $smarty->compileAllTemplates()
- Extracting PO Files automatically · bbrdaric/smarty-gettext Wiki · GitHub - this also deals with compiling the ttempaltes and this method allows you to keep the file names althought the line numbers will not match.
Translating in Smarty
This section is involve in actually translating the strings in the smarty software.
Smarty translation links (various)
- LAMP : Linux Apace PHP PERL mySQL: Internationalization PHP web sites using Smarty and gettext
- php - Smarty and gettext - Stack Overflow
Smarty Software
- GitHub - smarty-gettext/smarty-gettext: Gettext plugin enabling internationalization in Smarty Package files.
- GitHub - gueff/smarty_modifier_getText: PHP Smarty: a modifier for internationalization tool gettext
- PHP Smarty: a modifier for internationalization tool gettext
- php-gettext in Launchpad
- Google Code Archive - Long-term storage for Google Code Project Hosting.
- Extracting PO Files automatically · bbrdaric/smarty-gettext Wiki · GitHub
tsmarty2c.php Command line examples
setup the software as per these instructions - configure the software, you dont need the poedit software for this to work.
- php "D:\websites\php\gettext\tsmarty2c.php" D:\test.pot %f | "C:\Program Files (x86)\Poedit\GettextTools\bin\xgettext -LC --add-comments --no-location -"
- this involves sending it to xgettext and is not needed here
- i have just added to show you can send output to another program with a pipe (|) character
- php "D:\websites\php\gettext\tsmarty2c.php" -o test.pot "D:\websites\htdocs\develop\qwcrm\themes"
- this will scan the 'themes' directory recursively for all .tpl files and parse them for the {t}...{/t} strings
- php -q tsmarty2c.php mytemplate.tpl > mydomain.c
- this will output to a file
- you could just use the -o switch