PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.14.2
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.14.2
2.14.2 2.14.1 2.14.0 2.13.0 2.12.0 2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.0 2.5.0 2.4.0 2.3.0 2.2.0 2.1.1 2.1.0 2.0.2 2.0.1 2.0.0 1.32.0 1.31.0 1.30.0 1.29.0 1.28.0 All 57 releases
← All changes | includes/admin/importers/class-yoast-exporter.php +73 -10 2.11.0 → 2.14.2 View file →
@@ -128,10 +128,10 @@
128 128 'object_id' => $post_id,
129 129 'object_type' => 'post',
130 130 'source_plugin' => $this->plugin_slug,
131 131 'data' => [
132 - 'seo_title' => $this->convert_template_variables($meta['_yoast_wpseo_title'] ?? '', $post_id),
133 - 'meta_description' => $this->convert_template_variables($meta['_yoast_wpseo_metadesc'] ?? '', $post_id),
132 + 'seo_title' => $this->convert_post_value($meta['_yoast_wpseo_title'] ?? '', $post_id),
133 + 'meta_description' => $this->convert_post_value($meta['_yoast_wpseo_metadesc'] ?? '', $post_id),
134 134 'focus_keyword' => $meta['_yoast_wpseo_focuskw'] ?? '',
135 135 // Full keyword list (primary + Yoast Premium's additional
136 136 // keyphrases) for ThinkRank's keyword array — without this
137 137 // the migrator falls back to the single focus_keyword and
@@ -148,13 +148,13 @@
148 148 'nofollow' => $robots['nofollow'],
149 149 'noarchive' => $advanced_robots['noarchive'],
150 150 'noimageindex' => $advanced_robots['noimageindex'],
151 151 'nosnippet' => $advanced_robots['nosnippet'],
152 - 'og_title' => $this->convert_template_variables($meta['_yoast_wpseo_opengraph-title'] ?? '', $post_id),
153 - 'og_description' => $this->convert_template_variables($meta['_yoast_wpseo_opengraph-description'] ?? '', $post_id),
152 + 'og_title' => $this->convert_post_value($meta['_yoast_wpseo_opengraph-title'] ?? '', $post_id),
153 + 'og_description' => $this->convert_post_value($meta['_yoast_wpseo_opengraph-description'] ?? '', $post_id),
154 154 'og_image' => $meta['_yoast_wpseo_opengraph-image'] ?? '',
155 - 'twitter_title' => $this->convert_template_variables($meta['_yoast_wpseo_twitter-title'] ?? '', $post_id),
156 - 'twitter_description' => $this->convert_template_variables($meta['_yoast_wpseo_twitter-description'] ?? '', $post_id),
155 + 'twitter_title' => $this->convert_post_value($meta['_yoast_wpseo_twitter-title'] ?? '', $post_id),
156 + 'twitter_description' => $this->convert_post_value($meta['_yoast_wpseo_twitter-description'] ?? '', $post_id),
157 157 'twitter_image' => $meta['_yoast_wpseo_twitter-image'] ?? '',
158 158 'primary_category' => (int) ($meta['_yoast_wpseo_primary_category'] ?? 0),
159 159 'product_identifier' => $this->extract_product_identifier($meta),
160 160 'schema_type' => $meta['_yoast_wpseo_schema_page_type'] ?? '',
@@ -209,16 +209,16 @@
209 209 'object_id' => $term_id,
210 210 'object_type' => 'term',
211 211 'source_plugin' => $this->plugin_slug,
212 212 'data' => [
213 - 'seo_title' => $this->convert_template_variables($meta['wpseo_title'] ?? ''),
214 - 'meta_description' => $this->convert_template_variables($meta['wpseo_desc'] ?? ''),
213 + 'seo_title' => $this->convert_term_value($meta['wpseo_title'] ?? ''),
214 + 'meta_description' => $this->convert_term_value($meta['wpseo_desc'] ?? ''),
215 215 'focus_keyword' => $meta['wpseo_focuskw'] ?? '',
216 216 'canonical_url' => $meta['wpseo_canonical'] ?? '',
217 217 'noindex' => $noindex,
218 218 'nofollow' => 0,
219 - 'og_title' => $this->convert_template_variables($meta['wpseo_opengraph-title'] ?? ''),
220 - 'og_description' => $this->convert_template_variables($meta['wpseo_opengraph-description'] ?? ''),
219 + 'og_title' => $this->convert_term_value($meta['wpseo_opengraph-title'] ?? ''),
220 + 'og_description' => $this->convert_term_value($meta['wpseo_opengraph-description'] ?? ''),
221 221 ],
222 222 'extended' => [
223 223 'breadcrumb_title' => $meta['wpseo_bctitle'] ?? '',
224 224 'og_image' => $meta['wpseo_opengraph-image'] ?? '',
@@ -511,8 +511,71 @@
511 511 // Strip any remaining unknown variables
512 512 $value = preg_replace('/%%[a-z0-9_-]+%%/i', '', $value);
513 513
514 514 return trim($value);
515 + }
516 +
517 + /**
518 + * Yoast per-post tokens ThinkRank resolves per request (#886): kept as
519 + * tags rather than frozen into text. Mirrors convert_template_pattern().
520 + */
521 + private const POST_TOKENS = [
522 + '%%title%%' => '%title%',
523 + '%%sitename%%' => '%sitename%',
524 + '%%sep%%' => '%sep%',
525 + '%%excerpt%%' => '%excerpt%',
526 + '%%date%%' => '%date%',
527 + '%%modified%%' => '%modified%',
528 + '%%name%%' => '%author%',
529 + '%%category%%' => '%category%',
530 + '%%primary_category%%' => '%category%',
531 + '%%wc_price%%' => '%price%',
532 + '%%wc_sku%%' => '%sku%',
533 + '%%wc_shortdesc%%' => '%short_description%',
534 + '%%wc_brand%%' => '%brand%',
535 + ];
536 +
537 + /**
538 + * Yoast per-term tokens ThinkRank resolves on a term archive. The term's
539 + * own name and description used to be stripped outright, since the
540 + * literal resolver only knows post context.
541 + */
542 + private const TERM_TOKENS = [
543 + '%%term_title%%' => '%term%',
544 + '%%term_description%%' => '%excerpt%',
545 + '%%category_description%%' => '%excerpt%',
546 + '%%tag_description%%' => '%excerpt%',
547 + '%%sitename%%' => '%sitename%',
548 + '%%sep%%' => '%sep%',
549 + ];
550 +
551 + /**
552 + * A per-post Yoast value: mapped tokens as ThinkRank tags, the rest literal.
553 + *
554 + * @param mixed $value Raw Yoast value
555 + * @param int $post_id Post ID
556 + * @return string
557 + */
558 + private function convert_post_value($value, int $post_id): string {
559 + return $this->tokenize_object_template(
560 + $this->stringify_template_value($value),
561 + self::literal_token_patterns(self::POST_TOKENS),
562 + fn(string $rest): string => $this->convert_template_variables($rest, $post_id)
563 + );
564 + }
565 +
566 + /**
567 + * A per-term Yoast value: mapped tokens as ThinkRank tags, the rest literal.
568 + *
569 + * @param mixed $value Raw Yoast value
570 + * @return string
571 + */
572 + private function convert_term_value($value): string {
573 + return $this->tokenize_object_template(
574 + $this->stringify_template_value($value),
575 + self::literal_token_patterns(self::TERM_TOKENS),
576 + fn(string $rest): string => $this->convert_template_variables($rest)
577 + );
515 578 }
516 579
517 580 /**
518 581 * Translate a Yoast title/description *template* into ThinkRank pattern syntax.