WordPress.org

Ready to get started?Download WordPress

Forums

Polylang
[resolved] Language switching from a Post (15 posts)

  1. abuhaafidh
    Member
    Posted 2 years ago #

    Hi Chouby! Hope everything is going well with you. I'm wondering if you could add a feature where people can click on a link from a post to view a translated post of their preferred language. For example

    Title: Test Title
    Content:
    This is a test content for a post in English.

    View other translations: ENGLISH | FRENCH | GREEK

    All the best!

    http://wordpress.org/extend/plugins/polylang/

  2. Chouby
    Member
    Plugin Author

    Posted 2 years ago #

    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.

  3. abuhaafidh
    Member
    Posted 2 years ago #

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

  4. AndyDeGroo
    Member
    Posted 2 years ago #

    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?

  5. abuhaafidh
    Member
    Posted 2 years ago #

    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.

  6. AndyDeGroo
    Member
    Posted 2 years ago #

    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

  7. abuhaafidh
    Member
    Posted 2 years ago #

    Now I destroyed the whole blog, haha!

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

  8. AndyDeGroo
    Member
    Posted 2 years ago #

    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.

  9. abuhaafidh
    Member
    Posted 2 years ago #

    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

  10. AndyDeGroo
    Member
    Posted 2 years ago #

    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.

  11. abuhaafidh
    Member
    Posted 2 years ago #

    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!

  12. AndyDeGroo
    Member
    Posted 2 years ago #

    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.

  13. abuhaafidh
    Member
    Posted 2 years ago #

    Thank you so much! Everything works really nice now.

  14. LudovicB
    Member
    Posted 1 year ago #

    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.

  15. Chouby
    Member
    Plugin Author

    Posted 1 year ago #

    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.

Topic Closed

This topic has been closed to new replies.

About this Plugin

About this Topic

Tags