You shouldn’t rely on the global $post
variable for filters like this.
In your example you’re passing $event_city->ID
to get_the_permalink()
. This implies that the $event_city
post is not for the same post as the current $post
object. This is normal. Sometimes you want to use a function like get_the_title()
or get_the_permalink()
without changing the global $post
variable.
At some stage the value of get_the_permalink()
is passed through the post_type_link
filter. The problem then is that your custom_post_permalink()
function completely disregards the specific post that the link was requested for ($event_city
), and instead only uses the global post variable. This means that when the get_the_permalink()
function is called outside the loop, it will only ever retrieve a link based on the current post in the loop.
So how do we use the correct post in the filter? As documented, post_type_link
filter callbacks receive a post object as the 2nd argument. This object will represent the post that the link was requested for in get_the_permalink()
. So you need to use that object in your function:
function custom_post_permalink( $post_link, $post ) { // Accept $post argument.
$post_type = get_post_type( $post->ID ); // $post now refers to the one passed as an argument.
$post_type_data = get_post_type_object( $post_type );
$post_type_slug = $post_type_data->rewrite['slug'];
$post_type_slug_translated = apply_filters( 'wpml_get_translated_slug', $post_type_slug, $post_type );
$translated_home_url = apply_filters( 'wpml_home_url', home_url() );
$be_current_lang = apply_filters( 'wpml_current_language', NULL );
if ( $be_current_lang === 'fr' ) {
return $translated_home_url . $post_type_slug_translated . "https://wordpress.stackexchange.com/" . $post->post_name . '.html';
} else {
return $translated_home_url . "https://wordpress.stackexchange.com/" . $post_type_slug_translated . "https://wordpress.stackexchange.com/" . $post->post_name . '.html';
}
}
add_filter( 'post_type_link', 'custom_post_permalink', 10, 2 ); // Specify that we're accepting 2 arguments.
Whenever possible you should not rely on the global $post
variable. If the filter or action hook passed a post object to the callback function, always use that. If you had filtered the_title
the same way, relying on global $post
, you’d be having the exact same issue (in that case the filter gets the post ID, which you can use to get the object).