Support » Plugin: Polylang » [Plugin: Polylang] Identical page names in different languages

  • 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

    Any suggestions?

    Best regards

Viewing 7 replies - 1 through 7 (of 7 total)
  • And furthermore, same thing with categories, of course. For example, “videos” would be a category name for both English and German.

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

    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.

    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
    			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
    			WHERE post_name = %s AND post_type IN ( '" . implode( "', '", esc_sql( $hierarchical_post_types ) ) . "' ) AND ID != %d AND post_parent = %d
    			LIMIT 1";
    			$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $new_slug, $post_ID, $post_parent ) );
    				return $new_slug;
    		} else {
    			// Post slugs must be unique across all posts.
    			$check_sql = "SELECT post_name FROM $wpdb->posts
    			WHERE post_name = %s AND post_type = %s AND ID != %d
    			LIMIT 1";
    			$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $new_slug, $post_type, $post_ID ) );
    				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.

    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.

    Plugin Author Chouby


    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 and a German page ‘download’ with url 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.

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

    So I now have post slugs like:

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

    Thanks again.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘[Plugin: Polylang] Identical page names in different languages’ is closed to new replies.