> */ public static function export(): array { return [ self::row( 'techarticle-goal', TechArticleWrappers::GOAL_BLOCK, 'TechArticle Goal', 'Goal', 'Role: outcome. H2 until the next H2. Heading text is set in Drive Patterns or pinned in Incoming.' ), self::row( 'techarticle-context', TechArticleWrappers::CONTEXT_BLOCK, 'TechArticle Context', 'Context', 'Role: problem / context. H2 until the next H2. Add language aliases in Patterns.' ), self::row( 'techarticle-steps', TechArticleWrappers::STEPS_BLOCK, 'TechArticle Steps', 'Steps', 'Role: steps. Numbered list or H3 items stay as core blocks inside the wrapper.' ), self::row( 'techarticle-issues', TechArticleWrappers::ISSUES_BLOCK, 'TechArticle Common mistakes', 'Common mistakes', 'Role: common mistakes. List or paragraphs until the next H2.' ), ]; } /** * @param array> $items Drive catalog. * @return array> */ public static function register( array $items ): array { foreach ( self::export() as $row ) { $items[] = $row; } return $items; } /** * Import templates for Drive Patterns (editable H2 aliases). * * @param array> $templates Template id => definition. * @return array> */ public static function register_templates( array $templates ): array { foreach ( self::export() as $row ) { $id = (string) ( $row['id'] ?? '' ); if ( '' === $id ) { continue; } $templates[ $id ] = [ 'label' => (string) ( $row['label'] ?? $id ), 'description' => (string) ( $row['prompt'] ?? '' ), 'recipe_type' => 'section-wrap', 'block' => (string) ( $row['block'] ?? '' ), 'requires_plugins' => [], 'available' => true, 'default_enabled' => false, 'doc_hint' => (string) ( $row['prompt'] ?? '' ), ]; } return $templates; } /** * Upgrade default Map when the document is already a TechArticle. * * @param string $map Current map. * @param string $header Header text. * @param string $body Body HTML. */ public static function detect_map( string $map, string $header, string $body ): string { if ( self::signals_tech_article( $header, $body ) ) { return self::MAP; } return $map; } public static function signals_tech_article( string $header, string $body ): bool { if ( TechArticleMarkup::has_techarticle_blocks( $body ) ) { return true; } $blob = $header . "\n" . $body; return (bool) preg_match( '/\btech[\s_-]*article\b/i', $blob ); } /** * @return array */ private static function row( string $id, string $block, string $label, string $heading_seed, string $prompt ): array { return [ 'id' => $id, 'origin' => 'family', 'plugin' => '4wp-seo-helper', 'block' => $block, 'label' => $label, 'maps' => [ self::MAP ], 'wrap' => 'section', 'match' => [ 'type' => 'heading', 'level' => 2, 'pattern' => '', ], 'heading_seeds' => $heading_seed, 'prompt' => $prompt, 'auto' => false, 'manual' => true, ]; } }