PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 2.14.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v2.14.0
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 1.27.0 1.26.0 All 55 releases
← All changes | includes/abilities/content/class-update-faq.php +17 -22 2.13.0 → 2.14.0 View file →
@@ -33,8 +33,18 @@
33 33 * block stored there would be invisible on the page and the write would produce
34 34 * exactly the violation above. Those surfaces have their own FAQ modules, which
35 35 * `get-faq` reads and a human edits in the builder.
36 36 *
37 + * Oxygen and Breakdance replace `post_content` just as thoroughly and have no
38 + * ThinkRank FAQ module, and until #831 the detection did not know them at all:
39 + * the refusal never fired, the block was stored, and `will_emit_faqpage()` then
40 + * published a FAQPage for questions that are on no page. They are refused for
41 + * the same reason as the other three, with a message that sends the author to
42 + * the builder's own accordion rather than to a ThinkRank module that does not
43 + * exist. `FAQ_Content` now reads that accordion, so the refusal is no longer a
44 + * dead end: the questions it holds are reported, and the author edits them where
45 + * they live.
46 + *
37 47 * Two properties of the write matter:
38 48 *
39 49 * - **Byte-level editing.** Blocks are located with core's tokenizer and
40 50 * replaced by byte range, so every other block in the post is left exactly as
@@ -62,9 +72,9 @@
62 72 */
63 73 public function __construct() {
64 74 $this->id = 'thinkrank/update-faq';
65 75 $this->label = __( 'Update ThinkRank FAQ', 'thinkrank' );
66 - $this->description = __( 'Add FAQ questions and answers to a post as a visible ThinkRank FAQ block, which also produces FAQPage schema. Use mode "append" to add a block alongside anything already there, or "replace" to remove every ThinkRank FAQ block on the post first. Only posts built with the block editor can be written: a post rendered by Elementor, Bricks or Beaver is refused with unsupported_builder, because a block stored in its content would never be shown and marking up invisible content breaks Google\'s structured data policy. Call get-faq first to see which builder a post uses and what it already asks. Note that Google shows FAQ rich results only for well-known, authoritative government and health websites, so for most sites the value is being quotable by answer engines rather than a rich result.', 'thinkrank' );
76 + $this->description = __( 'Add FAQ questions and answers to a post as a visible ThinkRank FAQ block, which also produces FAQPage schema. Use mode "append" to add a block alongside anything already there, or "replace" to remove every ThinkRank FAQ block on the post first. Only posts built with the block editor can be written: a post rendered by Elementor, Bricks, Beaver, Oxygen or Breakdance is refused with unsupported_builder, because a block stored in its content would never be shown and marking up invisible content breaks Google\'s structured data policy. Call get-faq first to see which builder a post uses and what it already asks. Note that Google shows FAQ rich results only for well-known, authoritative government and health websites, so for most sites the value is being quotable by answer engines rather than a rich result.', 'thinkrank' );
67 77 }
68 78
69 79 /**
70 80 * {@inheritDoc}
@@ -200,15 +210,16 @@
200 210 if ( '' !== $builder ) {
201 211 return new \WP_Error(
202 212 'thinkrank_unsupported_builder',
203 213 sprintf(
204 - /* translators: %s: page builder name. */
205 - __( 'This post is rendered by %s, which replaces the post content, so a FAQ block written here would never be shown. Add the questions with that builder\'s own ThinkRank FAQ module instead. Marking up content a reader cannot see breaks Google\'s structured data policy.', 'thinkrank' ),
206 - $this->builder_label( $builder )
214 + /* translators: %s: why the post cannot be written, naming the builder. */
215 + __( '%s Marking up content a reader cannot see breaks Google\'s structured data policy.', 'thinkrank' ),
216 + $this->writable_reason( $builder )
207 217 ),
208 218 [
209 - 'status' => 422,
210 - 'builder' => $builder,
219 + 'status' => 422,
220 + 'builder' => $builder,
221 + 'builder_has_reader' => FAQ_Content::builder_is_readable( $builder ),
211 222 ]
212 223 );
213 224 }
214 225
@@ -377,24 +388,8 @@
377 388 return [
378 389 'content' => $out . substr( $content, $cursor ),
379 390 'removed' => count( $spans ),
380 391 ];
381 - }
382 -
383 - /**
384 - * A readable name for a builder, for the refusal message.
385 - *
386 - * @param string $builder Builder key.
387 - * @return string
388 - */
389 - private function builder_label( string $builder ): string {
390 - $labels = [
391 - FAQ_Content::SOURCE_ELEMENTOR => __( 'Elementor', 'thinkrank' ),
392 - FAQ_Content::SOURCE_BRICKS => __( 'Bricks', 'thinkrank' ),
393 - FAQ_Content::SOURCE_BEAVER => __( 'Beaver Builder', 'thinkrank' ),
394 - ];
395 -
396 - return $labels[ $builder ] ?? $builder;
397 392 }
398 393
399 394 /**
400 395 * The newest revision ID for a post, or 0 when it keeps none.