wp-multilang
wp-multilang copied to clipboard
issue with yoast SEO
on site 2 lang - ru & en save page in ru - showing ru meta on both. save page in en - showing en meta on both
As for me, temporary workaround was look like:
- Use remove_class_filter to get rid of \PHP_INT_MAX priority
Yoast\WP\SEO\Integrations\Watchers\Indexable_Post_Watcher::build_indexable
func, which fills %prefix%_yoast_indexable table. https://github.com/VaLeXaR/wp-multilang/blob/5c1556dd2a98d34df2ac7e15ef7429bb5e22dd49/includes/wpm-core-functions.php#L326
But instead of removing, I just re-add filter with new priority.
$fob->remove_filter( $tag, $filter['function'], $priority );
$fob->add_filter($tag, $filter['function'], $priority - 1, $filter['accepted_args']);
Then, I've just copy title & meta from %prefix%_postmeta to Yoast's indexable table through update.
You need to use same wp_insert_post
hook with maximum priority.
@Nekaravaev could you tell us more about your solution? Did you add filter to theme's function file or change files of WP-Multilang?
@KoalaMontana I'm stuck with that plugin after push site to production so solution dirty as.
Yoast change dramatically their plugin after 14 version and won't cooperate with users of multilang plugins, that store translation right in meta/posts table through shrotcode-like syntax (if you google some results, you saw so cold support responses as proof).
They change storage approach own data, moving to separate tables (which can store only one row for page). So if you save meta with WP Multilang translations, they sanitize it as simple string and collect to own table (which uses for formatting title, description, etc.). But post_meta field stay as we want.
So I decided to throw post_meta title & description to their table by hand (in functions.php to avoid modification of plugin files).
The problem here is it: they use \PHP_INT_MAX as own add_filter's priority. We need to override that value at first and copy meta then or changes will not apply.
Here modified popular helper: https://gist.github.com/Nekaravaev/77a0bc11fe8d1f4415b4609cb30a2e67
Then we just apply hook on wp_insert_post with dirty copy.
\add_action( "wp_insert_post", 'func', \PHP_INT_MAX, 1 );
func() {
global $wpdb;
$needed_fields = array('_yoast_wpseo_title', '_yoast_wpseo_focuskw', '_yoast_wpseo_metadesc');
$bindings = array(
'_yoast_wpseo_title' => 'title',
'_yoast_wpseo_metadesc' => 'description',
'_yoast_wpseo_focuskw' => 'primary_focus_keyword'
);
foreach ($needed_fields as $field ) {
$meta_value = $wpdb->get_col( $wpdb->prepare( "SELECT meta_value FROM {$wpdb->postmeta} WHERE meta_key = %s AND post_id = %d", $field, $post_id) );
if ( !empty( $meta_value ) ) {
$status = $wpdb->query("UPDATE " . $wpdb->prefix . "yoast_indexable SET " . $bindings[$field] . " = '".$meta_value[0]."' WHERE object_id = $post_id");
}
}
}
This will work only with plain text on Yoast's title field.
If you want to use Yoast's variables like PageTitle or Site Name, you should modify plugin's WPM_Yoast_Seo::translate_title
function in same way: read from yoast_indexable table and manipulate raw data.
$possible_placeholders = array("%%title%%", "%%sitename%%");
$title_col = $wpdb->get_col($wpdb->prepare("SELECT title from {$wpdb->prefix}yoast_indexable WHERE object_id=%d", $post->ID) );
if ( !empty( $title_col) ) {
$title_col = wpm_translate_value($title_col[0]);
$result_title = $title_col;
foreach ( $possible_placeholders as $placeholder ) {
if ( strpos($title_col, $placeholder ) !== false ) {
switch ($placeholder) {
case "%%title%%":
$result_title = str_replace($placeholder, get_the_title(), $result_title);
break;
case "%%sitename%%":
$result_title = str_replace($placeholder, get_bloginfo('name'), $result_title);
break;
}
}
}
return $result_title;
}
Hi, i try with
\add_action( "wp_insert_post", 'func', \PHP_INT_MAX, 1 );
and catch _yoast_wpseo_title and _yoast_wpseo_metadesc and push it to "yoast_indexable"
then i little change the code of WPM_Yoast_Seo::translate_title
to return oryginal parameter $title this way
public function translate_title( $title ) { return $title; }
and for me this workaround works fine.