WordPress.org

Support

Support » Plugins and Hacks » [Resolved] [Plugin: Polylang] Language switching from a Post

[Resolved] [Plugin: Polylang] Language switching from a Post

Viewing 14 replies - 1 through 14 (of 14 total)
  • Plugin Author Chouby
    Participant

    @chouby

    I did not try to do this, but I believe that it should be reachable using the function ‘pll_the_languages’ in your theme. All existing options (more than available with the widget) are included in the documentation.

    abuhaafidh
    Member

    @abuhaafidh

    I don’t really understand what you mean. Am I supposed to add ‘pll_the_languages’ to one of the .php files?

    AndyDeGroo
    Member

    @andydegroo

    It would be easier to do this if there was a function in API to get list of all languages.

    Well, I did the work for you so you can put this code in your theme functions.php
    If you decide to make a plugin from this code, wrap it in plugins_loaded hook.

    if(class_exists('Polylang_Base') && !function_exists('pll_languages_list')){
    
    	/**
    	 * Gets list of Polylang languages
    	 * @param boolean $hide_empty Optional, default is to return all language taxonomies.
    	 * @return array Array of language taxonomy term objects
    	 */
    	function pll_languages_list($hide_empty = FALSE){
    		global $polylang;
    		$langs = array();
    		if( $polylang instanceof Polylang_Base ){
    			$langs = (array)$polylang -> get_languages_list($hide_empty);
    		}
    		return $langs;
    	}
    
    	/**
    	 * Template tag to display other languages of a post
    	 * @param int $post_id Optional post ID, defaults to current post in the loop
    	 * @param array $args Optional arguments list
    	 */
    	function pll_the_post_translations($post_id = NULL, $args = array()){
    		global $post;
    		$defaults = array(
    			'sep' => "\n",
    			'before' => '<ol class="translations">',
    			'after' => '</ol>',
    			'echo' => TRUE,
    		);
    		$args = wp_parse_args($args, $defaults);
    		extract($args, EXTR_SKIP);
    
    		$the_post = ($post_id !== NULL)? get_post($post_id) : $post;
    		$languages = pll_languages_list();
    		$current_lang = pll_current_language();
    
    		$output = ''; $outarr = array();
    		if($languages && isset($the_post->ID)){
    			foreach($languages as $lang){
    				$translated_id = (int)pll_get_post($the_post->ID, $lang->slug);
    				if(!$translated_id && $current_lang != $lang->slug){
    					continue;
    				}
    				$tranlated_link = get_permalink($translated_id);
    				$class = ($current_lang == $lang->slug) ? 'current' : '';
    				$outarr[] = '<li class="'.$class.'"><a href="'.esc_url($tranlated_link).'" hreflang="'.esc_attr($lang->slug).'">'.$lang->name.'</a></li>';
    			}
    			$output = implode($sep, $outarr);
    		}
    		if(!$echo)
    			return $output;
    		 echo $output;
    	}
    }

    You can use it in your theme like this:

    <div class="translations-list">
    	<?php
    	if(function_exists('pll_the_post_translations'))
    		pll_the_post_translations();
    	?>
    </div>

    Now, where is my coffee?

    abuhaafidh
    Member

    @abuhaafidh

    Wow, the code looks neat! However, am I supposed to just copy and post the first bunch of codes at the end of functions.php? I tried it and my dashboard got messed up.

    AndyDeGroo
    Member

    @andydegroo

    I just edited the code in my previous post. I had left out one logical step to check if there is no translation and had left the debug code in.

    Copy it again and add in functions.php before closing ?> line

    abuhaafidh
    Member

    @abuhaafidh

    Now I destroyed the whole blog, haha!

    Parse error: syntax error, unexpected T_IF in functions.php on line 832

    AndyDeGroo
    Member

    @andydegroo

    Just look for missing semicolon ; at the end of line before the code you pasted.
    That or make the code into a plugin.
    Create a new file in plugins directory named pll-posttranslations.php with following content:

    <?php
    /*
    Plugin name: Polylang Post Translations
    Version: 0.1
    Description: Adds functions for displaying available translatins of a post
    Author: AndyDeGroo
    */
    
    add_action('plugins_loaded','pllpt_add_functions',1000);
    function pllpt_add_functions(){
    
    //[the code hoes here]
    
    }
    ?>

    replace //[the code hoes here] part with the code and activate the plugin.

    abuhaafidh
    Member

    @abuhaafidh

    I’ve added the missing semicolon, and it’s fine. Now I’ve just tried adding your div code above <?php the_post(); ?>, I get a message like this Fatal error: Call to undefined function pll_current_language() in /functions.php on line 866

    AndyDeGroo
    Member

    @andydegroo

    Sorry, that function was introduced around 0.8.0.6 development release.

    You can download the latest dev release from http://downloads.wordpress.org/plugin/polylang.zip
    Note: some things may have changed and it may not be entirely stable.

    Another option would be to add the function right after if(class_exists('Polylang_Base') && !function_exists('pll_languages_list')){ statement in the first code block:

    if(!function_exists('pll_current_language')){
    		/**
    		 * Polylang current languages
    		 * backcompat for versions before Polylang 0.8.0.6
    		 * @param string $args Optional, what to return, locale or slug. Defaults to slug.
    		 * @return string|array Array of language taxonomy term objects
    		 */
    		function pll_current_language($args = 'slug') {
    			global $polylang;
    			if(method_exists($polylang, 'current_language')){
    				return isset($polylang) ? $polylang->current_language($args) : false;
    			}else{
    				$curlang = $polylang->get_current_language();
    				return ( empty($curlang) || !isset($curlang->name) ) ? false :
    				$args == 'name' ? $curlang->name :
    				$args == 'locale' ? $curlang->description :
    				$curlang->slug;
    			}
    		}
    	}

    I tested it and it works.

    EDIT: There is another function missing in 0.8 which is needed by this code. I could implement it, but it is easier to download development version.

    abuhaafidh
    Member

    @abuhaafidh

    Great! This time no error is seen and I see a list of all the languages I have, and each language has linked itself to a post it’s translated to, but the ones that are not translated links to the post itself.

    Is there a way to remove a link from a language that has not been translated yet? Thanks heaps!

    AndyDeGroo
    Member

    @andydegroo

    I’ll quote myself:

    I just edited the code in my previous post. I had left out one logical step to check if there is no translation and had left the debug code in.

    I fixed it in original entry instead of posting new.

    abuhaafidh
    Member

    @abuhaafidh

    Thank you so much! Everything works really nice now.

    The following code (the long one that I paste in the end of this message, and that is meant to be put in the end of the functions.php of your current theme) adapts the one by AndyDeGroo.
    It is still called by a

    <div class="translations-list">
    	<?php
    	if(function_exists('pll_the_post_translations'))
    		pll_the_post_translations();
    	?>
    </div>

    that you put where you need it in your theme (ex, page.php, archives.php, etc).

    It lists the available translations of the current posts.

    Put
    $this->register_string('others', 'others');
    just after the code

    $this->register_string(__('Site Title'), get_option('blogname'));
    $this->register_string(__('Tagline'), get_option('blogdescription'));
    $this->register_string(__('Date Format'), get_option('date_format'));
    $this->register_string(__('Time Format'), get_option('time_format'));

    in the file plugins/polylang/include/admin.php

    –> It displays a text before the result, a text that is editable 🙂 in the settings of Polylang (Dashboard / Settings / Languages / Strings translation).

    if(class_exists('Polylang_Base') && !function_exists('pll_languages_list')){
    
    	/**
    	 * Gets list of Polylang languages
    	 * @param boolean $hide_empty Optional, default is to return all language taxonomies.
    	 * @return array Array of language taxonomy term objects
    	 */
    	function pll_languages_list($hide_empty = FALSE){
    		global $polylang;
    		$langs = array();
    		if( $polylang instanceof Polylang_Base ){
    			$langs = (array)$polylang -> get_languages_list($hide_empty);
    		}
    		return $langs;
    	}
    
    	/**
    	 * Template tag to display other languages of a post
    	 * @param int $post_id Optional post ID, defaults to current post in the loop
    	 * @param array $args Optional arguments list
    	 */
    	function pll_the_post_translations($post_id = NULL, $args = array()){
    		global $post;
    		$defaults = array(
    			'sep' => "\n",
    			'before' => pll__('others').':<br/><ul class="translations">',
    			'after' => '</ul>',
    			'echo' => TRUE,
    		);
    		$args = wp_parse_args($args, $defaults);
    		extract($args, EXTR_SKIP);
    
    		$the_post = ($post_id !== NULL)? get_post($post_id) : $post;
    		$languages = pll_languages_list();
    		$current_lang = pll_current_language();
    
    		$output = ''; $outarr = array();
    		if($languages && isset($the_post->ID)){
    			foreach($languages as $lang){
    				$translated_id = (int)pll_get_post($the_post->ID, $lang->slug);
    				if(!$translated_id || $current_lang == $lang->slug){
    					continue;
    				}
    				$tranlated_link = get_permalink($translated_id);
    				$class = ($current_lang == $lang->slug) ? 'current' : '';
    				$outarr[] = '<li class="'.$class.'"><a href="'.esc_url($tranlated_link).'" hreflang="'.esc_attr($lang->slug).'">'.esc_html(get_the_title($translated_id)).' ('.$lang->name.')</a></li>';
    			}
    			if (count($outarr)) {
    $output = $before . implode($sep, $outarr) . $after;
    }
    		}
    		if(!$echo)
    			return $output;
    		 echo $output;
    	}
    }
    
    ?>

    Hope it works for you!
    Don’t thank me, it’s a friend of mine who did the modifications.

    Plugin Author Chouby
    Participant

    @chouby

    Now there is another way to obtain almost the same result as the function proposed by @andydegroo:
    pll_the_languages('post_id' => $post_id);
    Though it does not implement the $args parameters

    And you can call:
    pll_register_string('others', 'others');
    somewhere in your code to avoid modifying the polylang code (modifications will be overwritten when updating the plugin)

    Hope it helps.

Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘[Resolved] [Plugin: Polylang] Language switching from a Post’ is closed to new replies.