Support

Account

Home Forums Feedback Location rules & WPML

Solving

Location rules & WPML

  • Hi,

    I just want to share two filters I’ve done to make WPML compatible with location rules for a Page or Post Taxonomy.

    I’ve been having this problem in many projects. Until now –as said previously in this forum– for pages I was solving this using Page Templates, which were the same in all the languages.

    However, I found a way to make Page location rule of ACF detect the correct page in all the languages without using Page Templates. This is the filter I created to make the Page location rule work between languages:

    
    //WPML support to page rule with ACF 5
    add_filter( 'acf/location/rule_match/page',	'rule_match_post_wpml', 10, 3 );
    function rule_match_post_wpml( $match, $rule, $options ) {
    		
    	// vars
    	$post_id = $options['post_id'];
    	
    	// validation
    	if( !$post_id ) {
    		return false;
    	}
    	
    	// compare
        if( $rule['operator'] == "==") {
        	
        	$match = ( icl_object_id($options['post_id'],'page',true) == $rule['value'] );
        
        } elseif( $rule['operator'] == "!=") {
        	
        	$match = ( icl_object_id($options['post_id'],'page',true) != $rule['value'] );
        
        }
    
        // return
        return $match;
    }
    

    Also, I needed this for some Post Taxonomies which also doesn’t keep their ID’s between languages. This is the filter I created for this:

    //WPML support to post taxonomy rule with ACF 5
    add_filter( 'acf/location/rule_match/post_taxonomy', 'rule_match_post_taxonomy_wpml', 10, 3 );
    function rule_match_post_taxonomy_wpml( $match, $rule, $options ) {
    	
    	// validate
    	if( !$options['post_id'] ) {
    		return false;
    	}
    	
    	// vars
    	$terms = $options['post_taxonomy'];
    		
    	// get term data
    	$data = acf_decode_taxonomy_term( $rule['value'] );
    	$field = is_numeric( $data['term'] ) ? 'id' : 'slug';
    	$term = get_term_by( $field, $data['term'], $data['taxonomy'] );
    
    	// validate term
    	if( empty($term) ) {	
    		return false;				
    	}
    	
    	// post type
    	if( !$options['post_type'] ) {
    		$options['post_type'] = get_post_type( $options['post_id'] );	
    	}
    	
    	// get terms
    	if( !$options['ajax'] ) {
    	
    		$terms = wp_get_post_terms( $options['post_id'], $term->taxonomy, array('fields' => 'ids') );
    		
    	}
    	
    	// If no terms, this is a new post and should be treated as if it has the "Uncategorized" (1) category ticked
    	if( empty($terms) ) {
    		if( is_object_in_taxonomy($options['post_type'], 'category') ) {
    			$terms = array( 1 );
    		}
    	}
    	
    	// compare
        if( $rule['operator'] == "==") {
        	
        	$match = in_array(icl_object_id($term->term_id,$data['taxonomy'],true), $terms);
        
        } elseif( $rule['operator'] == "!=") {
        	
        	$match = !in_array(icl_object_id($term->term_id,$data['taxonomy'],true), $terms);
        
        }		
            
        // return
        return $match;
    }
    

    Hope this helps somebody with the same problem as me. Maybe something like this could be added as an improvement for the compatibility of both plugins.

  • Have also used templates in the past, but stumbled on this post when wanting to have a cleaner solution for a new project. Unfortunately I can’t get this to work for pages. I don’t translate custom field groups, they’re the same in all languages. But the location rule only works for the language that was active when selecting a page.

    I know this is an old post, but perhaps I’m missing something or the have been updates to ACF that means this doesn’t work any longer? Would be good if this was built into core ACF, seems quite logical that the system could convert which page/ID is being used.

  • I think there’s an error in andreu’s post and I found 2 sulutions to this case.

    For example, we have a page in English with id 1 and it’s translation to Spanish with id 2. And we have an ACF field group with a rule to match id 1

    Andreu’s first code compares current page ID translated to current language of backend/frontend and the ID. If the user is viewing the translated page (ID=2), the function still returns 2 and the match is 2!=1, but that’s not what we want.

    The first solution is to use WPML function to get ID not for the current language, but for the default language, that the match is set in (note that icl_object_id function is now considered deprecated in WPML):

    global $sitepress;
    //get the default language code
    $default_lang = $sitepress->get_default_language();
    
    /* icl_object is deprecated in WPML, but I leave it here as an example:
    $translated_id = icl_object_id($options['post_id'],'page',true, $default_lang);*/ 
    
    // Proper way to do it now:
    $translated_id = apply_filters( 'wpml_object_id', $options['post_id'], 'page', true, $default_lang);//add defualt lang parameter

    The second and better, IMO, solution is to translate the ID to match instead:

    //WPML support to page rule with ACF 5
    add_filter( 'acf/location/rule_match/page', 'rule_match_post_wpml', 10, 3 );
    function rule_match_post_wpml( $match, $rule, $options ) {
    
    	// vars
    	$post_id = $options['post_id'];
    	$trans_id =  apply_filters( 'wpml_object_id', $rule['value'], 'page', true);
    
    	// validation
    	if( !$post_id ) {
    		return false;
    	}
    
    	// compare
    	if( $rule['operator'] == "==") {
    
    		$match = ( $post_id == $trans_id );  
    
    	} elseif( $rule['operator'] == "!=") {
    
    		$match = ( $post_id != $trans_id );  
    
    	}
    
    	// return
    	return $match;
    }
Viewing 3 posts - 1 through 3 (of 3 total)

The topic ‘Location rules & WPML’ is closed to new replies.