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.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 1.25.0 trunk 1.0.0 All 52 releases
thinkrank / includes / ai / prompts / class-content-brief-prompts.php

class-content-brief-prompts.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 2.10.0, at includes/ai/prompts/class-content-brief-prompts.php

236 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Content Brief Prompts Class
4 *
5 * Handles content brief generation AI prompts.
6 * Preserves exact functionality from original Content Brief Generator implementation.
7 *
8 * @package ThinkRank
9 * @subpackage AI\Prompts
10 * @since 1.0.0
11 */
12
13 declare(strict_types=1);
14
15 namespace ThinkRank\AI\Prompts;
16
17 // Prevent direct access
18 if (!defined('ABSPATH')) {
19 exit;
20 }
21
22 /**
23 * Content Brief Prompts Class
24 *
25 * Centralized content brief prompt building for consistent AI optimization across all providers.
26 * Handles comprehensive content brief generation with SEO, competitor analysis, and content strategy.
27 *
28 * @since 1.0.0
29 */
30 class Content_Brief_Prompts {
31
32 /**
33 * Build content brief generation prompt
34 *
35 * @since 1.0.0
36 *
37 * @param array $target_keywords Primary and secondary keywords
38 * @param string $content_type Type of content
39 * @param string $target_audience Target audience
40 * @param string $content_length Desired content length
41 * @param string $tone Content tone
42 * @param string $competitor_analysis Pre-analyzed competitor content (or empty string)
43 * @param string $additional_context Additional context
44 * @param string $provider AI provider
45 * @return string Generated prompt
46 */
47 public function build_content_brief_prompt(
48 array $target_keywords,
49 string $content_type,
50 string $target_audience,
51 string $content_length,
52 string $tone,
53 string $competitor_analysis,
54 string $additional_context,
55 string $provider = 'openai',
56 string $language = ''
57 ): string {
58 $primary_keyword = $target_keywords[0] ?? '';
59 $secondary_keywords = array_slice($target_keywords, 1);
60
61 $word_count_map = [
62 'short' => '500-800 words',
63 'medium' => '1000-1500 words',
64 'long' => '2000+ words'
65 ];
66
67 $prompt = "Generate a comprehensive content brief for a {$content_type} targeting \"{$primary_keyword}\" with these specifications:\n\n";
68 if ($language !== '') {
69 // Keep the whole brief in the site/post language instead of
70 // defaulting to English on non-English sites (issue #234).
71 $prompt .= "LANGUAGE (critical): Write the ENTIRE brief — outline, titles, descriptions, keywords and every other piece of text — in {$language}. Do NOT translate to English or switch languages.\n\n";
72 }
73 $prompt .= "Target Keywords: " . implode(', ', $target_keywords) . "\n";
74 $prompt .= "Content Type: {$content_type}\n";
75 $prompt .= "Target Audience: {$target_audience}\n";
76 $prompt .= "Desired Length: {$word_count_map[$content_length]}\n";
77 $prompt .= "Tone: {$tone}\n";
78
79 if (!empty($competitor_analysis)) {
80 $prompt .= "Competitor Analysis:\n" . $competitor_analysis . "\n";
81 }
82
83 if (!empty($additional_context)) {
84 $prompt .= "Additional Context: {$additional_context}\n";
85 }
86
87 $prompt .= "\nPlease provide a comprehensive, structured response with:\n\n";
88
89 $prompt .= "1. CONTENT OUTLINE:\n";
90 $prompt .= " Create a detailed H1-H3 structure with:\n";
91 $prompt .= " - Clear, SEO-optimized headings\n";
92 $prompt .= " - Word count estimates for each section\n";
93 $prompt .= " - 2-3 key points to cover under each heading\n";
94 $prompt .= " - Relevant keywords to include in each section\n\n";
95
96 $prompt .= "2. SEO METADATA PACKAGE:\n";
97 $prompt .= " TITLES:\n";
98 $prompt .= " - 3-5 compelling title suggestions (50-60 characters)\n";
99 $prompt .= " META DESCRIPTIONS:\n";
100 $prompt .= " - 3-4 meta description variations (150-160 characters)\n";
101 $prompt .= " - Include primary keyword and compelling CTA in each\n";
102 $prompt .= " URL SLUGS:\n";
103 $prompt .= " - 3 SEO-friendly URL slug suggestions (lowercase, hyphens)\n";
104 $prompt .= " FOCUS KEYWORD ANALYSIS:\n";
105 $prompt .= " - Primary keyword placement recommendations\n";
106 $prompt .= " - Secondary keyword integration strategy\n";
107 $prompt .= " - Keyword density guidelines (1-2% for primary)\n";
108 $prompt .= " RELATED KEYWORDS:\n";
109 $prompt .= " - 8-12 LSI and semantic keywords to naturally include\n";
110 $prompt .= " - Long-tail keyword variations\n";
111 $prompt .= " INTERNAL LINKING:\n";
112 $prompt .= " - Specific internal linking opportunities\n\n";
113
114 $prompt .= "3. SOCIAL MEDIA & SCHEMA MARKUP:\n";
115 $prompt .= " SOCIAL MEDIA META TAGS:\n";
116 $prompt .= " - Open Graph title (55 characters max)\n";
117 $prompt .= " - Open Graph description (125 characters max)\n";
118 $prompt .= " - Twitter Card title (70 characters max)\n";
119 $prompt .= " - Twitter Card description (125 characters max)\n";
120 $prompt .= " SCHEMA MARKUP SUGGESTIONS:\n";
121 $prompt .= " - Recommended schema types (Article, FAQ, HowTo, etc.)\n";
122 $prompt .= " - Key schema properties to include\n";
123 $prompt .= " - FAQ schema questions if applicable\n\n";
124
125 $prompt .= "4. VISUAL CONTENT STRATEGY:\n";
126 $prompt .= " IMAGE RECOMMENDATIONS:\n";
127 $prompt .= " - 5-8 specific image types needed\n";
128 $prompt .= " - Alt text suggestions for each image type\n";
129 $prompt .= " - Image placement recommendations\n";
130 $prompt .= " INFOGRAPHIC OPPORTUNITIES:\n";
131 $prompt .= " - Data visualization suggestions\n";
132 $prompt .= " - Process diagrams or flowcharts\n\n";
133
134 $prompt .= "5. COMPETITOR ANALYSIS & CONTENT GAPS:\n";
135 if (!empty($competitor_urls)) {
136 $prompt .= " Based on the competitor analysis above:\n";
137 $prompt .= " - Specific content gaps in competitor articles\n";
138 $prompt .= " - How to improve upon competitor headings and structure\n";
139 $prompt .= " - Topics competitors cover poorly or miss entirely\n";
140 $prompt .= " - Opportunities to create more comprehensive content\n";
141 } else {
142 $prompt .= " - What competitors typically miss in this topic area\n";
143 $prompt .= " - Unique angles or perspectives to take\n";
144 $prompt .= " - Questions readers have that aren't being answered\n";
145 }
146 $prompt .= "\n";
147
148 $prompt .= "6. CALL-TO-ACTION SUGGESTIONS:\n";
149 $prompt .= " - 3-5 compelling CTAs appropriate for the content type\n";
150 $prompt .= " - Placement recommendations within the content\n\n";
151
152 $prompt .= "7. WRITING GUIDELINES:\n";
153 $prompt .= " - Tone and style recommendations\n";
154 $prompt .= " - Key messages to emphasize\n";
155 $prompt .= " - Content format suggestions (lists, tables, etc.)\n\n";
156
157 $prompt .= "8. FULL ARTICLE DRAFT:\n";
158 $prompt .= " Write the complete, publish-ready article body ({$word_count_map[$content_length]}) that follows the outline above.\n";
159 $prompt .= " - Format as clean HTML using <h2>/<h3> headings, <p>, <ul>/<ol>, and <blockquote>. Do NOT include an <h1> (the post title is the H1).\n";
160 $prompt .= " - Write in a {$tone} tone for a {$target_audience} audience, naturally weaving in the target and related keywords.\n";
161 $prompt .= " - Cover every outline section with real prose (no placeholders) and finish with a relevant call to action.\n\n";
162
163 $prompt .= "IMPORTANT: Respond with a valid JSON object using this exact structure:\n\n";
164 $prompt .= "{\n";
165 $prompt .= " \"title_suggestions\": [\"Title 1\", \"Title 2\", \"Title 3\", \"Title 4\", \"Title 5\"],\n";
166 $prompt .= " \"meta_descriptions\": [\"Meta 1\", \"Meta 2\", \"Meta 3\", \"Meta 4\"],\n";
167 $prompt .= " \"url_slugs\": [\"slug-1\", \"slug-2\", \"slug-3\"],\n";
168 $prompt .= " \"outline\": [\n";
169 $prompt .= " {\n";
170 // No level label in the value. It duplicated the `level` field on the
171 // next line and taught the model that a heading string begins with its
172 // own level, which it then carried into content_body — so drafted
173 // articles came back with <h2>H2: Real Heading</h2> (#410).
174 $prompt .= " \"heading\": \"Main Title\",\n";
175 $prompt .= " \"level\": 1,\n";
176 $prompt .= " \"word_count\": 50,\n";
177 $prompt .= " \"key_points\": [\"Point 1\", \"Point 2\", \"Point 3\"],\n";
178 $prompt .= " \"keywords\": [\"keyword1\", \"keyword2\"]\n";
179 $prompt .= " }\n";
180 $prompt .= " ],\n";
181 $prompt .= " \"focus_keyword_analysis\": {\n";
182 $prompt .= " \"primary_placement\": [\"H1 title\", \"First paragraph\", \"3-4 headings\"],\n";
183 $prompt .= " \"secondary_integration\": [\"Use secondary keywords naturally throughout content\", \"Focus on user intent and semantic relevance\"],\n";
184 $prompt .= " \"density_guidelines\": [\"Primary keyword: 1-2%\", \"Secondary keywords: 0.5-1%\"]\n";
185 $prompt .= " },\n";
186 $prompt .= " \"related_keywords\": [\"keyword1\", \"keyword2\", \"keyword3\"],\n";
187 $prompt .= " \"internal_linking\": [\"Link suggestion 1\", \"Link suggestion 2\"],\n";
188 $prompt .= " \"social_media\": {\n";
189 $prompt .= " \"open_graph\": {\n";
190 $prompt .= " \"title\": \"OG Title (55 chars max)\",\n";
191 $prompt .= " \"description\": \"OG Description (125 chars max)\"\n";
192 $prompt .= " },\n";
193 $prompt .= " \"twitter_card\": {\n";
194 $prompt .= " \"title\": \"Twitter Title (70 chars max)\",\n";
195 $prompt .= " \"description\": \"Twitter Description (125 chars max)\"\n";
196 $prompt .= " }\n";
197 $prompt .= " },\n";
198 $prompt .= " \"schema_markup\": {\n";
199 $prompt .= " \"recommended_types\": [\"Article\", \"HowTo\", \"FAQ\"],\n";
200 $prompt .= " \"key_properties\": [\"headline\", \"description\", \"author\"],\n";
201 $prompt .= " \"faq_questions\": [\"Question 1?\", \"Question 2?\"]\n";
202 $prompt .= " },\n";
203 $prompt .= " \"visual_content\": {\n";
204 $prompt .= " \"image_recommendations\": [\n";
205 $prompt .= " {\n";
206 $prompt .= " \"type\": \"Featured Image\",\n";
207 $prompt .= " \"description\": \"Professional image description\",\n";
208 $prompt .= " \"alt_text\": \"Alt text suggestion\"\n";
209 $prompt .= " }\n";
210 $prompt .= " ],\n";
211 $prompt .= " \"infographic_opportunities\": [\"Data visualization 1\", \"Process diagram 2\"]\n";
212 $prompt .= " },\n";
213 $prompt .= " \"competitor_analysis\": {\n";
214 $prompt .= " \"content_gaps\": [\"Gap 1\", \"Gap 2\"],\n";
215 $prompt .= " \"unique_angles\": [\"Angle 1\", \"Angle 2\"],\n";
216 $prompt .= " \"unanswered_questions\": [\"Question 1\", \"Question 2\"]\n";
217 $prompt .= " },\n";
218 $prompt .= " \"call_to_actions\": [\n";
219 $prompt .= " {\n";
220 $prompt .= " \"text\": \"CTA text\",\n";
221 $prompt .= " \"placement\": \"End of post\"\n";
222 $prompt .= " }\n";
223 $prompt .= " ],\n";
224 $prompt .= " \"writing_guidelines\": {\n";
225 $prompt .= " \"tone_recommendations\": [\"Professional\", \"Informative\", \"Actionable\"],\n";
226 $prompt .= " \"key_messages\": [\"Message 1\", \"Message 2\"],\n";
227 $prompt .= " \"format_suggestions\": [\"Bullet points\", \"Short paragraphs\", \"Clear headings\"]\n";
228 $prompt .= " },\n";
229 $prompt .= " \"content_body\": \"<h2>Section heading</h2><p>The complete article written out in clean HTML, following the outline...</p>\"\n";
230 $prompt .= "}\n\n";
231 $prompt .= "Respond ONLY with valid JSON. Do not include any text before or after the JSON object.";
232
233 return $prompt;
234 }
235 }
236