PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.10.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.10.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 1.27.0 1.26.0 1.25.0 trunk 1.0.0 1.0.1 All 51 releases
← All changes | includes/frontend/class-seo-manager.php +25 -1 2.9.0 → 2.10.0 View file →
@@ -377,8 +377,16 @@
377 377 }
378 378
379 379 // Initialize Global SEO Schema Output and store reference
380 380 $this->global_seo_schema = new Global_SEO_Schema_Output();
381 + // Let schema reuse the description this class already resolves, so the
382 + // JSON-LD and the meta/og/twitter tags cannot disagree about what the
383 + // page is (#766). Passed as a callback rather than a value: schema is
384 + // built during wp_head, by which point the request context this
385 + // resolution depends on is set, and it must not be captured earlier.
386 + $this->global_seo_schema->set_description_resolver(
387 + fn (): string => (string) $this->get_meta_description()
388 + );
381 389 $this->global_seo_schema->init();
382 390 }
383 391
384 392 /**
@@ -2954,10 +2962,22 @@
2954 2962 $context_type,
2955 2963 $context_id
2956 2964 );
2957 2965
2966 + // A deployed node is a snapshot from Deploy time and outranks
2967 + // the automatic node, so page and article types would publish
2968 + // a frozen excerpt instead of the description the head
2969 + // resolves. Give them the live one, as the automatic node has.
2970 + $context_post = get_post($context_id);
2971 +
2958 2972 foreach ($page_specific_schemas as $schema_type => $schema_info) {
2959 - Schema_Graph::instance()->add_primary($schema_info['data'], (string) $schema_type, 'schema_manager');
2973 + $node = $schema_info['data'];
2974 +
2975 + if ($this->global_seo_schema && $context_post instanceof \WP_Post) {
2976 + $node = $this->global_seo_schema->refresh_deployed_description($node, (string) $schema_type, $context_post);
2977 + }
2978 +
2979 + Schema_Graph::instance()->add_primary($node, (string) $schema_type, 'schema_manager');
2960 2980 }
2961 2981 $has_schema_manager_output = true;
2962 2982 }
2963 2983 }
@@ -3015,8 +3035,12 @@
3015 3035 'url' => home_url('/'),
3016 3036 ];
3017 3037
3018 3038 $description = !empty($settings['site_description']) ? $settings['site_description'] : get_bloginfo('description');
3039 + // The tagline is stored esc_html()'d by sanitize_option(), so a site
3040 + // called "Fish & Chips" published `&` literally in its WebSite
3041 + // node; nothing decodes JSON-LD downstream.
3042 + $description = \ThinkRank\Core\Seo_Text::normalize_schema_text((string) $description);
3019 3043 if (!empty($description)) {
3020 3044 $schema['description'] = $description;
3021 3045 }
3022 3046