PluginProbe
Polylang / 0.2
Polylang v0.2
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / polylang.php

polylang.php in Polylang 0.2, at polylang.php

692 lines 25.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Polylang
4 Plugin URI: http://wordpress.org/extend/plugins/polylang/
5 Version: 0.2
6 Author: F. Demarle
7 Description: Adds multilingual capability to Wordpress
8 */
9
10 /* Copyright 2011 F. Demarle
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License, version 2, as
14 published by the Free Software Foundation.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 define('POLYLANG_VERSION', '0.2');
27 define('POLYLANG_DIR', dirname(__FILE__));
28 require_once(POLYLANG_DIR.'/base.php');
29 require_once(POLYLANG_DIR.'/admin.php');
30 require_once(POLYLANG_DIR.'/widget.php');
31
32 class Polylang extends Polylang_Base {
33 var $curlang;
34 var $default_locale;
35 var $list_textdomains = array();
36 var $search_form_filter = false;
37
38 function __construct() {
39
40 // manages plugin activation and deactivation
41 register_activation_hook( __FILE__, array(&$this, 'activate') );
42 register_deactivation_hook( __FILE__, array(&$this, 'deactivate') );
43
44 // plugin and widget initialization
45 add_action('init', array(&$this, 'init'));
46 add_action('widgets_init', array(&$this, 'widgets_init'));
47
48 // rewrite rules
49 add_filter('rewrite_rules_array', array(&$this, 'rewrite_rules_array' ));
50
51 // filters categories and post tags by language
52 add_filter('terms_clauses', array(&$this, 'terms_clauses'), 10, 3);
53
54 if (is_admin())
55 new Polylang_Admin();
56 else {
57 // text domain management
58 add_filter('locale', array(&$this, 'get_locale'));
59 add_filter('override_load_textdomain', array(&$this, 'mofile'), 10, 3);
60 add_action('wp', array(&$this, 'load_textdomains'));
61
62 // filters posts according to the language
63 add_filter('pre_get_posts', array(&$this, 'pre_get_posts'));
64
65 // meta in the html head section
66 remove_action('wp_head', 'rel_canonical');
67 add_action('wp_head', array(&$this, 'wp_head'));
68
69 // prevents redirection of the homepage
70 add_filter('redirect_canonical', array(&$this, 'redirect_canonical'), 10, 2);
71
72 // adds javascript at the end of the document
73 add_action('wp_print_footer_scripts', array(&$this, 'wp_print_footer_scripts'));
74
75 // adds the language information in the search form
76 add_filter('get_search_form', array(&$this, 'get_search_form'));
77
78 // filters the pages according to the current language
79 add_filter('get_pages', array(&$this, 'get_pages'), 10, 2);
80
81 // filters the comments according to the current language
82 add_filter('comments_clauses', array(&$this, 'comments_clauses'));
83
84 // rewrites feed links to filter them by language
85 add_filter('feed_link', array(&$this, 'feed_link'), 10, 2);
86
87 // rewrites archives links to filter them by language
88 add_filter('getarchives_join', array(&$this, 'posts_join'));
89 add_filter('getarchives_where', array(&$this, 'posts_where'));
90 add_filter('get_archives_link', array(&$this, 'get_archives_link'));
91
92 // rewrites next and previous post links to filter them by language
93 add_filter('get_previous_post_join', array(&$this, 'posts_join'));
94 add_filter('get_next_post_join', array(&$this, 'posts_join'));
95 add_filter('get_previous_post_where', array(&$this, 'posts_where'));
96 add_filter('get_next_post_where', array(&$this, 'posts_where'));
97
98 // filters the nav menus according to current language
99 add_filter('wp_nav_menu_args', array(&$this, 'wp_nav_menu_args'));
100
101 // allows a new value for the 'show' parameter to display the homepage url according to the current language
102 add_filter('bloginfo_url', array(&$this, 'bloginfo_url'), 10, 2);
103
104 // Template tags
105 add_action('the_languages', array(&$this, 'the_languages'));
106 }
107 }
108
109 // plugin activation
110 function activate() {
111 // create the termmeta table - not provided by WP by default - if it does not already exists
112 // uses exactly the same model as other meta tables to be able to use access functions provided by WP
113 global $wpdb;
114 $charset_collate = '';
115 if ( ! empty($wpdb->charset) )
116 $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
117 if ( ! empty($wpdb->collate) )
118 $charset_collate .= " COLLATE $wpdb->collate";
119
120 $table = $wpdb->prefix . 'termmeta';
121
122 $tables = $wpdb->get_results("show tables like '$table'");
123 if (!count($tables))
124 $wpdb->query("CREATE TABLE $table (
125 meta_id bigint(20) unsigned NOT NULL auto_increment,
126 term_id bigint(20) unsigned NOT NULL default '0',
127 meta_key varchar(255) default NULL,
128 meta_value longtext,
129 PRIMARY KEY (meta_id),
130 KEY term_id (term_id),
131 KEY meta_key (meta_key)
132 ) $charset_collate;");
133
134 // codex tells to use the init action to call register_taxonomy but I need it now for my rewrite rules
135 register_taxonomy('language', array('post', 'page'), array('label' => false, 'query_var'=>'lang'));
136
137 // defines default values for options in case this is the first installation
138 $options = get_option('polylang');
139 if (!$options) {
140 $options['browser'] = 1; // default language for the front page is set by browser preference
141 $options['rewrite'] = 0; // do not remove /language/ in permalinks
142 }
143 $options['version'] = POLYLANG_VERSION; // do not manage versions yet but prepare for it
144 update_option('polylang', $options);
145
146 // add our rewrite rules
147 global $wp_rewrite;
148 $wp_rewrite->flush_rules();
149 }
150
151 // plugin deactivation
152 function deactivate() {
153 // delete our rewrite rules
154 remove_filter('rewrite_rules_array', array(&$this,'rewrite_rules_array' ));
155 global $wp_rewrite;
156 $wp_rewrite->flush_rules();
157 }
158
159 // some initialization
160 function init() {
161 global $wpdb;
162 $wpdb->termmeta = $wpdb->prefix . 'termmeta'; // registers the termmeta table in wpdb
163
164 // registers the language taxonomy
165 // codex: use the init action to call this function
166 register_taxonomy('language', 'post', array(
167 'label' => false,
168 'query_var'=>'lang',
169 'update_count_callback' => '_update_post_term_count'));
170
171 // optionaly removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/
172 // the simple line of code is inspired by the WP No Category Base plugin : http://wordpresssupplies.com/wordpress-plugins/no-category-base/
173 $options = get_option('polylang');
174 if ($options['rewrite']) {
175 global $wp_rewrite;
176 $wp_rewrite->extra_permastructs['language'][0] = '%language%';
177 }
178
179 $this->default_locale = get_locale(); // save the default locale before we start any language manipulation
180 load_plugin_textdomain('polylang', false, dirname(plugin_basename( __FILE__ ))); // plugin i18n
181 }
182
183 // registers our widget
184 function widgets_init() {
185 register_widget('Polylang_Widget');
186 }
187
188 // rewrites rules if pretty permalinks are used
189 function rewrite_rules_array($rules) {
190 $options = get_option('polylang');
191 $newrules = array();
192 $listlanguages = $this->get_languages_list();
193
194 // modifies the rules created by WordPress when '/language/' is removed in permalinks
195 if ($options['rewrite']) {
196 foreach ($listlanguages as $language) {
197 $newrules[$language->slug.'/feed/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?lang='.$language->slug.'&feed=$matches[1]';
198 $newrules[$language->slug.'/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?lang='.$language->slug.'&feed=$matches[1]';
199 $newrules[$language->slug.'/page/?([0-9]{1,})/?$'] = 'index.php?lang='.$language->slug.'&paged=$matches[1]';
200 $newrules[$language->slug.'/?$'] = 'index.php?lang='.$language->slug;
201 }
202 unset($rules['([^/]+)/feed/(feed|rdf|rss|rss2|atom)/?$']); // => index.php?lang=$matches[1]&feed=$matches[2]
203 unset($rules['([^/]+)/(feed|rdf|rss|rss2|atom)/?$']); // => index.php?lang=$matches[1]&feed=$matches[2]
204 unset($rules['([^/]+)/page/?([0-9]{1,})/?$']); // => index.php?lang=$matches[1]&paged=$matches[2]
205 unset($rules['([^/]+)/?$']); // => index.php?lang=$matches[1]
206 }
207
208 $options['rewrite'] ? $base = '' : $base = 'language/';
209
210 // rewrite rules for comments feed filtered by language
211 foreach ($listlanguages as $language) {
212 $newrules[$base.$language->slug.'/comments/feed/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?lang='.$language->slug.'&feed=$matches[1]&withcomments=1';
213 $newrules[$base.$language->slug.'/comments/(feed|rdf|rss|rss2|atom)/?$'] = 'index.php?lang='.$language->slug.'&feed=$matches[1]&withcomments=1';
214 }
215 unset($rules['comments/feed/(feed|rdf|rss|rss2|atom)/?$']); // => index.php?&feed=$matches[1]&withcomments=1
216 unset($rules['comments/(feed|rdf|rss|rss2|atom)/?$']); // => index.php?&feed=$matches[1]&withcomments=1
217
218 // rewrite rules for archives filtered by language
219 foreach ($rules as $key => $rule) {
220 $is_archive = strpos($rule, 'year=') && !(
221 strpos($rule, 'p=') ||
222 strpos($rule, 'name=') ||
223 strpos($rule, 'page=') ||
224 strpos($rule, 'cpage=') );
225
226 if ($is_archive) {
227 foreach ($listlanguages as $language)
228 $newrules[$base.$language->slug.'/'.$key] = str_replace('?', '?lang='.$language->slug.'&', $rule);
229
230 unset($rules[$key]); // now useless
231 }
232 }
233
234 return $newrules + $rules;
235 }
236
237 // filters categories and post tags by language when needed (both in admin panels and frontend)
238 function terms_clauses($clauses, $taxonomies, $args) {
239 // does nothing except on categories and post tags
240 if ( !in_array('category', $taxonomies) && !in_array('post_tag', $taxonomies) )
241 return $clauses;
242
243 if (is_admin()) {
244 $screen = get_current_screen(); //FIXME breaks a user's admin -> use pagenow instead ? Or simply test the function.
245
246 // NOTE: $screen is not defined in the tag cloud of the Edit Post panel ($pagenow set to admin-ajax.php)
247 if (isset($screen))
248 // does nothing in the Categories, Post tags, Languages an Posts* admin panels
249 if ($screen->base == 'edit-tags' || $screen->base == 'toplevel_page_mlang' || $screen->base == 'edit')
250 return $clauses;
251
252 // *FIXME I want all categories in the dropdown list and only the ones in the right language in the inline edit
253 // It seems that I need javascript to get the post_id as inline edit data are manipulated in inline-edit-post.js
254
255 $this->curlang = $this->get_current_language();
256 }
257
258 // adds our clauses to filter by current language
259 if ($this->curlang) {
260 global $wpdb;
261 $value = $this->curlang->term_id;
262 $clauses['join'] .= " INNER JOIN $wpdb->termmeta AS tm ON t.term_id = tm.term_id";
263 $clauses['where'] .= " AND tm.meta_key = '_language' AND tm.meta_value = $value";
264 }
265 return $clauses;
266 }
267
268 // returns the language according to browser preference or the default language
269 function get_preferred_language() {
270 // check first is the user was already browsing this site
271 if (isset($_COOKIE['wordpress_polylang']))
272 return $this->get_language($_COOKIE['wordpress_polylang']);
273
274 // sets the browsing language according to the browser preferences
275 // code adapted from http://www.thefutureoftheweb.com/blog/use-accept-language-header
276 $options = get_option('polylang');
277 if ($options['browser']) {
278 $accept_langs = array();
279
280 if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
281 // break up string into pieces (languages and q factors)
282 preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
283
284 if (count($lang_parse[1])) {
285 $accept_langs = array_combine($lang_parse[1], $lang_parse[4]); // create a list like "en" => 0.8
286 // set default to 1 for any without q factor
287 foreach ($accept_langs as $accept_lang => $val) {
288 if ($val === '') $accept_langs[$accept_lang] = 1;
289 }
290 arsort($accept_langs, SORT_NUMERIC); // sort list based on value
291 }
292 }
293
294 // looks through sorted list and use first one that matches our language list
295 $listlanguages = $this->get_languages_list(true); // hides languages with no post
296 foreach ($accept_langs as $accept_lang => $val) {
297 foreach ($listlanguages as $language) {
298 if (strpos($accept_lang, $language->slug) === 0 && !isset($pref_lang)) {
299 $pref_lang = $language;
300 }
301 }
302 }
303 } // options['browser']
304
305 // either there is no preference in the browser or preferences does not match our language list or it is requested not to use the browser preference
306 if (!isset($pref_lang))
307 $pref_lang = $this->get_language($options['default_lang']);
308
309 return $pref_lang;
310 }
311
312 // returns the current language
313 function get_current_language() {
314 global $post_ID;
315
316 if($this->curlang)
317 return $this->curlang;
318
319 if (is_404())
320 return $this->get_preferred_language();
321
322 if (is_admin()) {
323 if (isset($post_ID))
324 $lang = $this->get_post_language($post_ID);
325
326 // trick to get the post number in the Post Tags metabox in the Edit Post screen (as $post_ID not defined)
327 $qvars = $this->get_referer_vars();
328 if (isset($qvars['post']))
329 $lang = $this->get_post_language($qvars['post']);
330 }
331 else {
332 $var = get_query_var('lang');
333 if ($var)
334 $lang = $this->get_language($var);
335 else {
336 $var = get_queried_object_id();
337 if ($var && is_single() || is_page())
338 $lang = $this->get_post_language($var);
339 else {
340 $var = get_query_var('cat');
341 if ($var)
342 $lang = $this->get_term_language($var);
343 else {
344 $var = get_query_var('tag_id');
345 if ($var)
346 $lang = $this->get_term_language($var);
347 }
348 }
349 }
350 }
351
352 return (isset($lang)) ? $lang : NULL;
353 }
354
355 // returns the locale based on current language
356 function get_locale($locale) {
357 if ($this->curlang)
358 $locale = $this->curlang->description;
359 return $locale;
360 }
361
362 // saves all text domains in a table for later usage
363 function mofile( $bool, $domain, $mofile) {
364 $this->list_textdomains[] = array ('mo' => $mofile, 'domain' => $domain);
365 return true; // prevents WP loading text domains as we will load them all later
366 }
367
368 // NOTE: I believe there are two ways for a plugin to force the WP language
369 // as done by xili_language and here : load text domains and reinitialize wp_locale with the action 'wp'
370 // as done by qtranslate : define the locale with the action 'plugins_loaded', but in this case, the language must be specified in the url.
371 function load_textdomains() {
372 // sets the current language and set a cookie to remember it
373 if ($this->curlang = $this->get_current_language())
374 setcookie('wordpress_polylang', $this->curlang->slug, time() + 31536000 /* 1 year */, COOKIEPATH, COOKIE_DOMAIN);
375
376 // our override_load_textdomain has done its job. let's remove it before calling load_textdomain
377 remove_filter('override_load_textdomain', array(&$this, 'mofile'));
378
379 // now we can load text domains with the right language
380 $new_locale = get_locale();
381 foreach ($this->list_textdomains as $textdomain)
382 load_textdomain( $textdomain['domain'], str_replace($this->default_locale, $new_locale, $textdomain['mo']));
383
384 global $wp_locale;
385 $wp_locale->init(); // reinitializes wp_locale for weekdays and months
386 }
387
388 // filters posts according to the language
389 function pre_get_posts($query) {
390
391 if (empty($query->query)) {
392
393 // sets the language according to browser preference or default language
394 $this->curlang = $this->get_preferred_language();
395
396 // redirect to the right translated page in case a static page is used as front page
397 $post_id = get_option('page_on_front');
398 if (isset($this->curlang) && $post_id) {
399 // a static page is used as front page
400 $language = $this->get_post_language($post_id);
401 if ($language->slug != $this->curlang->slug) {
402 // but the one defined in the "Reading Settings" panel is not in the right language, so let's redirect to the right one
403 $link_id = $this->get_translated_post($post_id, $this->curlang);
404 if ($link_id) {
405 $url = _get_page_link($link_id);
406 wp_redirect($url);
407 exit;
408 }
409 }
410 }
411 }
412
413 $qvars = $query->query_vars;
414
415 // filters recent posts to the current language
416 // FIXME if $qvars['post_type'] == 'nav_menu_item', setting lang breaks custom menus.
417 // since to get nav_menu_items, get_post is used and no language is linked to nav_menu_items
418 // (even if the object behind the nav_menu_item is linked to a language)
419 if ($query->is_home && $this->curlang && !isset($qvars['post_type']))
420 $query->set('lang', $this->curlang->slug);
421
422 // remove pages from archives when the language is set
423 if (isset($qvars['m']) && isset($qvars['lang']))
424 $query->set('post_type', 'post');
425 }
426
427 function wp_head() {
428 // modifies the canonical link to the homepage
429 if (is_singular()) {
430 global $wp_the_query;
431 if ($id = $wp_the_query->get_queried_object_id()) {
432 if (is_page())
433 $link = _get_page_link($id); // ignores page_on_front unlike get_permalink
434 else
435 $link = get_permalink ($id);
436 echo "<link rel='canonical' href='$link' />\n";
437 }
438 }
439
440 // outputs references to translated pages (if exists) in the html head section
441 $listlanguages = $this->get_languages_list();
442 foreach ($listlanguages as $language) {
443 if ($language->slug != $this->curlang->slug) {
444 $url = $this->get_translation_url($language);
445 if ($url)
446 echo "<link hreflang='$language->slug' href='$url' rel='alternate' />\n";
447 }
448 }
449 }
450
451 // prevents redirection of the homepage
452 function redirect_canonical($redirect_url, $requested_url) {
453 if($requested_url == _get_page_link(get_option('page_on_front')))
454 return false;
455 return $redirect_url;
456 }
457
458 // adds some javascript workaround knowing it's not perfect...
459 function wp_print_footer_scripts() {
460 if ($this->curlang) {
461 $js = "<script type='text/javascript'>";
462
463 // modifies links to the homepage to filter by the right language
464 // since filtering home_url breaks things in the core and filtering bloginfo_url is not enough if the template uses home_url()
465 $url = rtrim(home_url(), '/');
466
467 if ($page = get_option('page_on_front'))
468 $newurl = _get_page_link($this->get_post($page, $this->curlang));
469 else
470 $newurl = get_term_link($this->curlang->slug, 'language');
471
472 $js .= "var e = document.getElementsByTagName('a');
473 for (var i = 0; i < e.length; i++) {
474 var href = e[i].href;
475 if (href == '$url' || href == '$url/') {
476 e[i].href = '$newurl';
477 }
478 }";
479
480 // modifies the search form since filtering get_search_form won't work if the template uses searchform.php
481 // don't use directly e[0] just in case there is somewhere else an element named 's'
482 // check before if the hidden input has not already been introduced by get_search_form
483 if (!$this->search_form_filter) {
484 $lang = $this->curlang->slug;
485 $js .= "e = document.getElementsByName('s');
486 for (i = 0; i < e.length; i++) {
487 if (e[i] == '[object HTMLInputElement]') {
488 var ih = document.createElement('input');
489 ih.type = 'hidden';
490 ih.name = 'lang';
491 ih.value = '$lang';
492 e[i].parentNode.appendChild(ih);
493 }
494 }";
495 }
496
497 $js .= "</script>";
498 echo $js;
499 }
500 }
501
502 // adds the language information in the search form
503 // FIXME does not work if searchform.php is used
504 function get_search_form($form) {
505 if ($form) {
506 $this->search_form_filter = true;
507 $form = str_replace('</form>', '<input type="hidden" name="lang" value="'.$this->curlang->slug.'" /></form>', $form);
508 }
509 return $form;
510 }
511
512 // filters the list of pages according to the current language
513 // FIXME: it seems that there is currently no way to filter before the database query (3.2) -> lot of sql queries
514 // cannot play with widget_pages_args filter either as it seems that get_pages does not query taxonomies :(
515 // should try to improve this...
516 function get_pages($pages, $r) {
517 if (isset($this->curlang)) {
518 foreach ($pages as $key => $page) {
519 $lang = $this->get_post_language($page->ID);
520 if (!$lang || $this->curlang->slug != $lang->slug)
521 unset($pages[$key]);
522 }
523 }
524 return $pages;
525 }
526
527 // filters the comments according to the current language
528 function comments_clauses($clauses) {
529 if ($this->curlang) {
530 global $wpdb;
531 $value = $this->curlang->term_id;
532 $clauses['join'] .= " INNER JOIN $wpdb->term_relationships AS tr ON tr.object_id = ID";
533 $clauses['join'] .= " INNER JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id";
534 $clauses['where'] .= " AND tt.term_id = $value";
535 }
536 return $clauses;
537 }
538
539 // Modifies the feed link to add the language parameter
540 // FIXME should be an option to do this ?
541 function feed_link($url, $feed) {
542 global $wp_rewrite;
543 $options = get_option('polylang');
544
545 if ($this->curlang) {
546 if ($wp_rewrite->using_permalinks()) {
547 $home = home_url();
548 $options['rewrite'] ? $base = '/' : $base = '/language/';
549 $url = str_replace($home, $home.$base.$this->curlang->slug, $url);
550 }
551 else {
552 if ($feed)
553 $url = home_url('?lang='.$this->curlang->slug.'&feed='.$feed);
554 }
555 }
556 return $url;
557 }
558
559 // modifies the sql request for wp_get_archives an get_adjacent_post to filter by the current language
560 function posts_join($sql) {
561 if ($this->curlang) {
562 global $wpdb;
563 $sql .= " INNER JOIN $wpdb->term_relationships ON object_id = ID";
564 }
565 return $sql;
566 }
567
568 // modifies the sql request for wp_get_archives and get_adjacent_post to filter by the current language
569 function posts_where($sql) {
570 if ($this->curlang) {
571 global $wpdb;
572 $lang_id = $this->curlang->term_id;
573 $sql .= " AND term_taxonomy_id = $lang_id";
574 }
575 return $sql;
576 }
577
578 // modifies the archives link to add the language parameter
579 function get_archives_link($link_html) {
580 if ($this->curlang) {
581 global $wp_rewrite;
582 $options = get_option('polylang');
583 $home = home_url();
584 if ($wp_rewrite->using_permalinks()) {
585 $options['rewrite'] ? $base = '/' : $base = '/language/';
586 $link_html = str_replace($home, $home.$base.$this->curlang->slug, $link_html);
587 }
588 else
589 $link_html = str_replace($home.'/?', $home.'/?lang='.$this->curlang->slug.'&amp;', $link_html);
590 }
591 return $link_html;
592 }
593
594 // returns the url of the translation (if exists) of the current page
595 function get_translation_url($language) {
596
597 if ( is_single()) {
598 $id = $this->get_post(get_the_ID(), $language);
599 if ($id)
600 $url = get_permalink($id);
601 }
602
603 elseif ( is_page() ) {
604 $id = $this->get_post(get_the_ID(), $language);
605 if ($id)
606 $url = _get_page_link($id);
607 }
608
609 elseif ( is_category() || is_tag() ) {
610 $term = get_queried_object();
611 $term_id = $term->term_id;
612 $taxonomy = $term->taxonomy;
613 $lang = $this->get_term_language($term_id);
614
615 if ($language->slug == $lang->slug)
616 $url = get_term_link($term->slug, $taxonomy); // self link
617 else {
618 $link_id = $this->get_translated_term($term_id, $language);
619 if ($link_id) {
620 $term = get_term($link_id,$taxonomy); // We need the slug for get_term_link
621 $url = get_term_link($term->slug, $taxonomy);
622 }
623 }
624 }
625
626 // FIXME for date links, if I simply modify the lang query, there is a risk that there is no posts (if all are not translated at this date)
627 // do nothing for now
628 elseif ( is_year() ) {
629 }
630
631 elseif ( is_month() ) {
632 }
633
634 elseif (is_home() || is_tax('language') )
635 $url = get_term_link($language->slug, 'language');
636
637 return isset($url) ? $url : null;
638 }
639
640 // filters the nav menus according to current language
641 function wp_nav_menu_args($args) {
642 if (!$args['menu'] && $args['theme_location'] && $this->curlang) {
643 $menu_lang = get_option('polylang_nav_menus');
644 $args['menu'] = $menu_lang[$args['theme_location']][$this->curlang->slug];
645 }
646 return $args;
647 }
648
649 // returns the home url in the right language
650 function get_home_url($language) {
651 $post_id = get_option('page_on_front');
652 if ($post_id) {
653 // a static page is used as front page
654 $id = $this->get_post($post_id, $language);
655 if($id)
656 $url = _get_page_link($id);
657 }
658 return isset($url) ? $url : get_term_link($language->slug, 'language');
659 }
660
661 // adds 'lang_url' as possible value to the 'show' parameter of bloginfo to display the home url in the correct language
662 // FIXME not tested
663 function bloginfo_url($output, $show) {
664 if ($show == 'lang_url' && $this->curlang) {
665 $url = $this->get_home_url($this->curlang);
666 $output = isset($url) ? $url : home_url('/');
667 }
668 return $output;
669 }
670
671 // Template tag : Displays links to the current page in other languages
672 // Usage : do_action('the_languages');
673 function the_languages() {
674 $listlanguages = $this->get_languages_list(true); // hides languages with no posts
675 $output = "<ul>\n";
676 foreach ($listlanguages as $language) {
677 $url = $this->get_translation_url($language);
678 if (!isset($url))
679 $url = $this->get_home_url($language); // if the page is not translated, link to the home page
680 $output .= "<li><a href='$url'>".$language->name."</a></li>\n";
681 }
682 $output .= "</ul>\n";
683 echo $output;
684 }
685
686 } // class Polylang
687
688 if (class_exists("Polylang"))
689 new Polylang();
690
691 ?>
692