WordPress.org

Ready to get started?Download WordPress

Forums

Polylang
Identical page names in different languages (8 posts)

  1. mambu
    Member
    Posted 2 years ago #

    First of all, thanks for creating polylang, it's a great! However, I have a problem I cannot solve on my own.

    Sometimes, there might be a page which has the same name in several languages, e.g., the page "Downloads" would have the same name in English, German, Dutch etc. But of course, I would like to have pretty permalinks like this:
    /downloads/ (for the default language)
    /nl/downloads (Dutch)
    /de/downloads (German)

    Is it possible to do just that? The same problem might also occur when having posts with identical names. Perhaps I would like to have a post in three languages about one particular person, and I would like to have links like
    /stevebuscemi/
    /nl/stevebuscemi/
    /de/stevebuscemi/

    Any suggestions?

    Best regards
    Mambu

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

  2. mambu
    Member
    Posted 2 years ago #

    And furthermore, same thing with categories, of course. For example, "videos" would be a category name for both English and German.

  3. sostoss
    Member
    Posted 2 years ago #

    did you try to make different categories under the same name but different language setting? like downloads set language-->english
    downloads set language-->german
    etc...

  4. mambu
    Member
    Posted 2 years ago #

    It doesn't work, I can't use the category name twice unless it has a different parent. And speaking of pages, I can't use the same slug twice either.

  5. AndyDeGroo
    Member
    Posted 2 years ago #

    This is because WordPress does not filter posts and pages by language when checking if the slug is unique.

    I had same problem and just finished code as a workaround for this. Until Chouby includes this in Polylang core you can use following code in your theme functions.php or create a plugin out of it:

    global $polylang;
    // Check if Polylang_Base exists and if $polylang is the right object
    if(is_admin() && class_exists('Polylang_Base') && $polylang instanceof Polylang_Base){
    
    	// The wp_unique_post_slug filter is applied only after WordPress checks if the slug is unique and adds suffix otherwise
    	// the function returns unique post slug within language
    	add_filter('wp_unique_post_slug', 'unique_slug_in_language', 10, 5);
    	function unique_slug_in_language($slug, $post_ID, $post_status, $post_type, $post_parent = 0){
    		global $polylang, $wpdb;
    
    		// Get language of a post
    		$lang = $polylang->get_post_language($post_ID);
    		// return the slug if Polylang does not return post language
    		if(empty($lang))
    			return $slug;
    
    		// Remove suffix if it was added
    		// this might remove any dash and number at the end of a slug
    		$new_slug = isset($_POST['new_slug'])? sanitize_title($_POST['new_slug']) : preg_replace('@-\d$@', '', $slug);
    
    		// Return slug if it was not changed
    		if($new_slug == $slug)
    			return $slug;
    
    		// prepare statements to filter by language
    		$join = $wpdb->prepare(" INNER JOIN $wpdb->term_relationships AS pll_tr ON pll_tr.object_id = ID");
    		$where_lang = $wpdb->prepare(" AND pll_tr.term_taxonomy_id = %d", $lang->term_id);
    
    		$hierarchical_post_types = get_post_types( array('hierarchical' => true) );
    
    		// Polylang does not translate attachements - skip if it is one
    		if ( 'attachment' == $post_type ) {
    			return $slug;
    
    		} elseif ( in_array( $post_type, $hierarchical_post_types ) ) {
    			// Page slugs must be unique within their own trees. Pages are in a separate
    			// namespace than posts so page slugs are allowed to overlap post slugs.
    			$check_sql = "SELECT post_name FROM $wpdb->posts
    			$join
    			WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d
    			$where_lang
    			LIMIT 1";
    			$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $new_slug, $post_ID, $post_parent ) );
    			if(!$post_name_check)
    				return $new_slug;
    
    		} else {
    			// Post slugs must be unique across all posts.
    			$check_sql = "SELECT post_name FROM $wpdb->posts
    			$join
    			WHERE post_name = %s AND post_type = %s AND ID != %d
    			$where_lang
    			LIMIT 1";
    			$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $new_slug, $post_type, $post_ID ) );
    			if(!$post_name_check)
    				return $new_slug;
    		}
    		return $slug;
    	}
    
    }

    It is smart enough not to just strip the suffix added by WordPress. It really checks if there are no duplicates in post/page language and under same parent. Code is partially taken from wp-includes/post.php wp_unique_post_slug function with some stuff from Polylang core.php.

    Not pretty, but it works and I don't know any better way to do this right now. Additions or suggestion are welcome.

  6. AndyDeGroo
    Member
    Posted 2 years ago #

    NOTE: If you create pages or posts with identical slugs and disable Polylang after that, only first matching post or page will be displayed in front-end. And this may not work for pages.

    EDIT: Currently there are problems querying right posts in front-end when using this code. I'll post more code as soon as I get it fixed.

    It appears that Polylang is setting current language from current post or page in single view instead of getting it from query variable.

  7. Chouby
    Member
    Plugin Author

    Posted 2 years ago #

    The way Polylang works, you can't use same slugs for two different pages, but you can use the same title (the same for posts, categories, tags...).
    So you can create an English page 'download' with url mysite.com/download-en/ and a German page 'download' with url mysite.com/download-de/. Checking the "add language info to all url" will not change that because (as written by AndyDeGroo, although the language code is optionally present for posts, pages, categories and tags, Polylang does not use this information).

    @AndyDeGroo, I will study your code. Thank for posting it.

  8. ronenschmitz
    Member
    Posted 1 year ago #

    @AndyDeGroo:
    Thank you for your solution – working just fine after adding your code to my theme functions.php.

    So I now have post slugs like:
    /projects/stereo-deluxe
    /projekte/stereo-deluxe

    I didn't ran into this problems with pages though. They worked right away without your code.

    Thanks again.

Topic Closed

This topic has been closed to new replies.

About this Plugin

About this Topic