Stripping CVS keywords
[project/i18n.git] / i18n.module
1 <?php
2 /**
3 * Internationalization (i18n) module
4 *
5 * @author Jose A. Reyero, 2004
6 */
7
8 /**
9 * Common module functions
10 */
11
12 // This runs after user has ben initialized and path may be already translated
13
14 function i18n_init(){
15 global $i18n_langpath;
16
17 // Quick fix, check if called from bootstrap.inc
18 if(!function_exists("drupal_get_path_map")) return 0;
19
20 if($lang=i18n_get_lang()){
21 i18n_set_lang($lang);
22 }else{
23 $lang= i18n_get_default_lang();
24 }
25
26 if(variable_get("i18n_interface",0)) i18n_set_default_lang($lang);
27
28 if(variable_get("i18n_content",0)){
29 $original=i18n_get_original_path();
30 if(!$i18n_langpath && $trpath=i18n_get_normal_path("$lang/$original")){
31 $_GET["q"]=$trpath;
32 }elseif(!$original || $i18n_langpath==$original){
33 $_GET["q"]=drupal_get_normal_path(i18n_front_page($lang));
34 }
35 }
36 }
37 function i18n_front_page($lang){
38 return variable_get("i18n_front_page",0) ? $lang.'/'.variable_get('site_frontpage','node') : variable_get('site_frontpage','node');
39 }
40 function i18n_help($section = "admin/help#i18n") {
41 switch ($section) {
42 case "admin/help#i18n":
43 $output = t("
44 <p>This module provides support for internationalization of Drupal sites in various ways:</p>
45 <ul><li>Translation of the user interface for registered and anonymous users</li>
46 <li>Multi-language for content, combined with url aliasing. For this feature to be used, you must enable it in the module configuration and then use url aliasing to keep pages in various languages. I.e. 'en/mypage', 'es/mypage' should be English and Spanish versions of the same page</li>
47 <li>Detection of the brower language</li>
48 <li>Keeps the language settings accross consecutive requests, using a number of methods: URL rewriting, sessions, cookies</li>
49 <li>Provides a block for language selection and two theme functions: <i>i18n_flags</i> and <i>i18n_links</i></li></ul>
50 <p>For url rewriting you need to have the file <b>i18n.inc</b> in the <i>includes</i> folder and add the following line to your configuration file:</p>
51 <pre>
52 include 'includes/i18n.inc';
53 </pre>
54 <p>You can try different settings to have only content translation, interface translation or both.</p>
55 <p><small>Module developed by <a href=\"http://freelance.reyero.net\">freelance.reyero.net</a></small></p>");
56 break;
57 case "admin/system/modules#description":
58 $output = t("Supports site internationalization (i18n).");
59 break;
60 }
61 return $output;
62 }
63
64 function i18n_settings(){
65 $output .= form_radios(t("Interface translation"),"i18n_interface",variable_get("i18n_interface",0),array(t("Disabled"),t("Enabled")),t("If disabled, uses Drupal's default. If enabled, translates the interface to selected language"));
66 $output .= form_radios(t("Content translation"),"i18n_content",variable_get("i18n_content",0),array(t("Disabled"),t("Enabled")),t("If enabled, prepends language code to url and searches for translated content"));
67 $output .= form_select(t("Front page"),"i18n_front_page",variable_get("i18n_front_page",0),array(t("Default"),t("Language dependant")),t("If language dependant and <i>Content translation</i> is enabled, default front page will be prepended with language code, i.e. 'en/node'"));
68 $output .=form_radios(t("Keep Language"),"i18n_keep",variable_get("i18n_keep",'url'),
69 array( ""=>t("Disabled"),
70 "url" => t("URL rewriting"),
71 "session" => t("Session"),
72 "cookie" => t("Cookie")
73 ),t("A language code independent of user's language will be kept accross requests using the selected method"));
74 $output .= form_radios(t("Detect browser language"),"i18n_browser",variable_get("i18n_browser",0),array(t("Disabled"),t("Enabled")));
75 $output .= form_textfield(t("Flags directory"),"i18n_flags",variable_get("i18n_flags","misc/flags/*.gif"),70,180,t("Path for flags. Asterisk '*' is a placeholder for language code. This is only needed when you want a language selector block"));
76
77 return $output;
78 }
79
80 function i18n_block($op = 'list', $delta = 0) {
81 if ($op == 'list') {
82 $blocks[0]['info'] = t('Languages');
83 }
84 else {
85 $blocks['subject']=t('Languages');
86 $content = "<table><tr><td>";
87 $content .= theme("i18n_links",1,1,"</td><td>","</td></tr><tr><td>");
88 $content .= "</td></tr></table>";
89 $blocks['content'] =$content;
90 }
91
92 return $blocks;
93 }
94
95
96 /**
97 * i18n api
98 */
99
100 if(!function_exists("i18n_get_lang_prefix")){
101 function i18n_get_lang_prefix($path){
102 global $languages;
103 $split=split("/",$path);
104 $maybelang=$split[0];
105 if($languages[$maybelang]){
106 return $maybelang;
107 }
108 }
109 }
110
111 function i18n_get_lang(){
112 global $i18n_lang;
113 if($i18n_lang){
114 return $i18n_lang;
115 } elseif($lang=$_GET['i18n_lang']) {
116 return $i18n_lang=$lang;
117 } else {
118 switch(variable_get('i18n_keep','')){
119 case 'url': // URL
120 $lang= i18n_get_lang_prefix(i18n_get_original_path());
121 break;
122 case 'session': // Session
123 session_start();
124 $lang = $_SESSION['i18n_lang'];
125 break;
126 case 'cookie': // Cookie
127 $lang=$_COOKIE['i18n_lang'];
128 break;
129 default:
130 $lang=$_GET['i18n_lang'];
131 }
132 }
133 return $i18n_lang=$lang;
134 }
135
136 function i18n_set_lang($lang){
137 global $i18n_lang;
138 global $i18n_langpath;
139 $i18n_lang=$lang;
140 switch(variable_get('i18n_keep','')){
141 case 'url': // URL
142 case 'query': // Query string
143 $i18n_langpath=$lang;
144 break;
145 case 'session': // Session
146 session_start();
147 $_SESSION["i18n_lang"]=$lang;
148 break;
149 case 'cookie': // Cookie
150 setcookie('i18n_lang',$lang,NULL,'/');
151 break;
152 }
153 }
154
155 function i18n_get_default_lang(){
156 global $user;
157 global $languages;
158 if(!$lang=$user->language){
159 if(variable_get('i18n_browser',0) && $lang=i18n_get_browser_lang()){
160 i18n_set_default_lang($lang);
161 } else {
162 $lang=key($languages);
163 reset($languages);
164 }
165 }
166 return $lang;
167 }
168
169 // Set language as default rearranging $languages array
170 function i18n_set_default_lang($lang){
171 global $languages;
172 global $i18n_lang;
173 $i18n_lang=$lang;
174 if(variable_get("i18n_interface",0)){
175 $deflang=key($languages);
176 if($lang != $deflang){
177 // Reorder $languages to set $lang as the first element...
178 $languages=array_merge(array($lang => $languages[$lang]),$languages);
179 } else { //Language is the default
180 reset($languages);
181 }
182 }
183 }
184
185 // Function based on common.inc::drupal_get_normal_path, but returns nothing if mapping not found
186 function i18n_get_normal_path($path) {
187 if (($map = drupal_get_path_map()) && isset($map[$path])) {
188 return $map[$path];
189 }
190 }
191
192 // To get the original path. Cannot use $_GET["q"] cause it may have been already changed
193 function i18n_get_original_path(){
194 $path=$_REQUEST["q"];
195 return trim($path,"/");
196 }
197
198 // Get language from browser settings, but only if it is in the $languages array
199 function i18n_get_browser_lang(){
200 global $languages;
201 $accept=explode(",",array_shift( explode(";",$_SERVER["HTTP_ACCEPT_LANGUAGE"])));
202 foreach($accept as $lang){
203 $lang=substr($lang,0,2);
204 if($languages[$lang]) return $lang;
205 }
206 }
207
208 /**
209 * Theme functions
210 */
211
212 /**
213 * Returns language links with optional flags
214 *
215 * @param $flags an integer, 1 to use language flags
216 * @param $names an integer, 1 to use language names
217 * @param $delim1 delimiter to place between language name and flag
218 * @param $delim2 delimiter to place between different languages
219 *
220 * @return a string containing the @a links output.
221 */
222
223 function theme_i18n_links($flags=1,$names=1,$delim1=" ",$delim2=" "){
224 global $languages;
225 global $i18n_lang;
226
227 foreach($languages as $lang => $langname){
228 $name= $names ? t($langname): ""; // Should be localized??
229 $flag= $flags ? _i18n_flag($lang) :"";
230 if($lang==$i18n_lang){
231 $links[] = "<strong>$name</strong>$delim1$flag";
232 }else {
233 $links[] = i18n_l($name,$lang).$delim1.i18n_l($flag,$lang);
234 }
235 }
236 $output =implode($delim2,$links);
237 return $output;
238 }
239
240 function theme_i18n_flags(){
241 return theme_i18n_links(1,0);
242 }
243
244 function _i18n_flag($lang,$attribs=array()){
245 if($path=variable_get("i18n_flags","misc/flags/*.gif")){
246 $flag=str_replace("*",$lang,$path);
247 return "<img class=\"i18n\" src=\"$flag\"".drupal_attributes($attribs)." />";
248 }
249 }
250
251 // Creates links for different languages
252 function i18n_l($text, $lang , $url="",$attributes=array(),$query=NULL) {
253 global $i18n_langpath;
254 // If !url get from original request
255 if(!$url) $url=i18n_get_original_path();
256 // If url has lang_prefix, remove it
257 if(i18n_get_lang_prefix($url)) $url=substr($url,3);
258
259 if(variable_get('i18n_keep','')=='url'){
260 $url="$lang/$url";
261 } else {
262 if(variable_get('i18n_content',0)) $url="$lang/$url";
263 $query= $query ? $query.'&i18n_lang='.$lang : "i18n_lang=$lang";
264 }
265 // Save $i18n_langpath, and set to null to avoid url_rewriting
266 $tmp=$i18n_langpath;
267 $i18n_langpath="";
268 $result= l($text,$url,$attributes,$query);
269 // Restore $i18n_langpath
270 $i18n_langpath=$tmp;
271 return $result;
272 }
273
274 ?>