1 | PHP-gettext 1.0 (https://launchpad.net/php-gettext) |
---|
2 | |
---|
3 | Copyright 2003, 2006, 2009 -- Danilo "angry with PHP[1]" Segan |
---|
4 | Licensed under GPLv2 (or any later version, see COPYING) |
---|
5 | |
---|
6 | [1] PHP is actually cyrillic, and translates roughly to |
---|
7 | "works-doesn't-work" (UTF-8: Ради-Не-Ради) |
---|
8 | |
---|
9 | |
---|
10 | Introduction |
---|
11 | |
---|
12 | How many times did you look for a good translation tool, and |
---|
13 | found out that gettext is best for the job? Many times. |
---|
14 | |
---|
15 | How many times did you try to use gettext in PHP, but failed |
---|
16 | miserably, because either your hosting provider didn't support |
---|
17 | it, or the server didn't have adequate locale? Many times. |
---|
18 | |
---|
19 | Well, this is a solution to your needs. It allows using gettext |
---|
20 | tools for managing translations, yet it doesn't require gettext |
---|
21 | library at all. It parses generated MO files directly, and thus |
---|
22 | might be a bit slower than the (maybe provided) gettext library. |
---|
23 | |
---|
24 | PHP-gettext is a simple reader for GNU gettext MO files. Those |
---|
25 | are binary containers for translations, produced by GNU msgfmt. |
---|
26 | |
---|
27 | Why? |
---|
28 | |
---|
29 | I got used to having gettext work even without gettext |
---|
30 | library. It's there in my favourite language Python, so I was |
---|
31 | surprised that I couldn't find it in PHP. I even Googled for it, |
---|
32 | but to no avail. |
---|
33 | |
---|
34 | So, I said, what the heck, I'm going to write it for this |
---|
35 | disguisting language of PHP, because I'm often constrained to it. |
---|
36 | |
---|
37 | Features |
---|
38 | |
---|
39 | o Support for simple translations |
---|
40 | Just define a simple alias for translate() function (suggested |
---|
41 | use of _() or gettext(); see provided example). |
---|
42 | |
---|
43 | o Support for ngettext calls (plural forms, see a note under bugs) |
---|
44 | You may also use plural forms. Translations in MO files need to |
---|
45 | provide this, and they must also provide "plural-forms" header. |
---|
46 | Please see 'info gettext' for more details. |
---|
47 | |
---|
48 | o Support for reading straight files, or strings (!!!) |
---|
49 | Since I can imagine many different backends for reading in the MO |
---|
50 | file data, I used imaginary abstract class StreamReader to do all |
---|
51 | the input (check streams.php). For your convenience, I've already |
---|
52 | provided two classes for reading files: FileReader and |
---|
53 | StringReader (CachedFileReader is a combination of the two: it |
---|
54 | loads entire file contents into a string, and then works on that). |
---|
55 | See example below for usage. You can for instance use StringReader |
---|
56 | when you read in data from a database, or you can create your own |
---|
57 | derivative of StreamReader for anything you like. |
---|
58 | |
---|
59 | |
---|
60 | Bugs |
---|
61 | |
---|
62 | Report them on https://bugs.launchpad.net/php-gettext |
---|
63 | |
---|
64 | Usage |
---|
65 | |
---|
66 | Put files streams.php and gettext.php somewhere you can load them |
---|
67 | from, and require 'em in where you want to use them. |
---|
68 | |
---|
69 | Then, create one 'stream reader' (a class that provides functions |
---|
70 | like read(), seekto(), currentpos() and length()) which will |
---|
71 | provide data for the 'gettext_reader', with eg. |
---|
72 | $streamer = new FileStream('data.mo'); |
---|
73 | |
---|
74 | Then, use that as a parameter to gettext_reader constructor: |
---|
75 | $wohoo = new gettext_reader($streamer); |
---|
76 | |
---|
77 | If you want to disable pre-loading of entire message catalog in |
---|
78 | memory (if, for example, you have a multi-thousand message catalog |
---|
79 | which you'll use only occasionally), use "false" for second |
---|
80 | parameter to gettext_reader constructor: |
---|
81 | $wohoo = new gettext_reader($streamer, false); |
---|
82 | |
---|
83 | From now on, you have all the benefits of gettext data at your |
---|
84 | disposal, so may run: |
---|
85 | print $wohoo->translate("This is a test"); |
---|
86 | print $wohoo->ngettext("%d bird", "%d birds", $birds); |
---|
87 | |
---|
88 | You might need to pass parameter "-k" to xgettext to make it |
---|
89 | extract all the strings. In above example, try with |
---|
90 | xgettext -ktranslate -kngettext:1,2 file.php |
---|
91 | what should create messages.po which contains two messages for |
---|
92 | translation. |
---|
93 | |
---|
94 | I suggest creating simple aliases for these functions (see |
---|
95 | example/pigs.php for how do I do it, which means it's probably a |
---|
96 | bad way). |
---|
97 | |
---|
98 | |
---|
99 | Usage with gettext.inc (standard gettext interfaces emulation) |
---|
100 | |
---|
101 | Check example in examples/pig_dropin.php, basically you include |
---|
102 | gettext.inc and use all the standard gettext interfaces as |
---|
103 | documented on: |
---|
104 | |
---|
105 | http://www.php.net/gettext |
---|
106 | |
---|
107 | The only catch is that you can check return value of setlocale() |
---|
108 | to see if your locale is system supported or not. |
---|
109 | |
---|
110 | |
---|
111 | Example |
---|
112 | |
---|
113 | See in examples/ subdirectory. There are a couple of files. |
---|
114 | pigs.php is an example, serbian.po is a translation to Serbian |
---|
115 | language, and serbian.mo is generated with |
---|
116 | msgfmt -o serbian.mo serbian.po |
---|
117 | There is also simple "update" script that can be used to generate |
---|
118 | POT file and to update the translation using msgmerge. |
---|
119 | |
---|
120 | TODO: |
---|
121 | |
---|
122 | o Improve speed to be even more comparable to the native gettext |
---|
123 | implementation. |
---|
124 | |
---|
125 | o Try to use hash tables in MO files: with pre-loading, would it |
---|
126 | be useful at all? |
---|
127 | |
---|
128 | Never-asked-questions: |
---|
129 | |
---|
130 | o Why did you mark this as version 1.0 when this is the first code |
---|
131 | release? |
---|
132 | |
---|
133 | Well, it's quite simple. I consider that the first released thing |
---|
134 | should be labeled "version 1" (first, right?). Zero is there to |
---|
135 | indicate that there's zero improvement and/or change compared to |
---|
136 | "version 1". |
---|
137 | |
---|
138 | I plan to use version numbers 1.0.* for small bugfixes, and to |
---|
139 | release 1.1 as "first stable release of version 1". |
---|
140 | |
---|
141 | This may trick someone that this is actually useful software, but |
---|
142 | as with any other free software, I take NO RESPONSIBILITY for |
---|
143 | creating such a masterpiece that will smoke crack, trash your |
---|
144 | hard disk, and make lasers in your CD device dance to the tune of |
---|
145 | Mozart's 40th Symphony (there is one like that, right?). |
---|
146 | |
---|
147 | o Can I...? |
---|
148 | |
---|
149 | Yes, you can. This is free software (as in freedom, free speech), |
---|
150 | and you might do whatever you wish with it, provided you do not |
---|
151 | limit freedom of others (GPL). |
---|
152 | |
---|
153 | I'm considering licensing this under LGPL, but I *do* want |
---|
154 | *every* PHP-gettext user to contribute and respect ideas of free |
---|
155 | software, so don't count on it happening anytime soon. |
---|
156 | |
---|
157 | I'm sorry that I'm taking away your freedom of taking others' |
---|
158 | freedom away, but I believe that's neglible as compared to what |
---|
159 | freedoms you could take away. ;-) |
---|
160 | |
---|
161 | Uhm, whatever. |
---|