PluginProbe
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO / 1.30.0
ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO v1.30.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 1.0.2 1.1.0 1.10.0 All 48 releases
thinkrank / includes / frontend / template-functions.php

template-functions.php in ThinkRank AI SEO – AI SEO Plugin for WordPress: Schema, XML Sitemaps, Meta Tags, Search Console & Local SEO 1.30.0, at includes/frontend/template-functions.php

299 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Template Functions for ThinkRank SEO
4 *
5 * Helper functions for themes to display ThinkRank SEO elements
6 *
7 * @package ThinkRank\Frontend
8 * @since 1.0.0
9 */
10
11 // Prevent direct access
12 if (!defined('ABSPATH')) {
13 exit;
14 }
15
16 /**
17 * Display ThinkRank breadcrumbs
18 *
19 * Usage in theme templates:
20 * <?php thinkrank_breadcrumbs(); ?>
21 *
22 * @since 1.0.0
23 *
24 * @param array $args Optional. Arguments to customize breadcrumb display
25 * @return void
26 */
27 function thinkrank_breadcrumbs($args = []) {
28 /**
29 * Fires to display ThinkRank breadcrumbs
30 *
31 * @since 1.0.0
32 *
33 * @param array $args Breadcrumb display arguments
34 */
35 do_action('thinkrank_breadcrumbs', $args);
36 }
37
38 /**
39 * Get ThinkRank breadcrumbs data without displaying
40 *
41 * @since 1.0.0
42 *
43 * @return array|null Breadcrumb data or null if not available
44 */
45 function thinkrank_get_breadcrumbs() {
46 // Check if ThinkRank is loaded
47 if (!function_exists('thinkrank')) {
48 return null;
49 }
50
51 $plugin = thinkrank();
52 if (!$plugin) {
53 return null;
54 }
55
56 $seo_manager = $plugin->get_component('frontend_seo');
57
58 if (!$seo_manager || !method_exists($seo_manager, 'get_current_breadcrumbs')) {
59 return null;
60 }
61
62 return $seo_manager->get_current_breadcrumbs();
63 }
64
65 /**
66 * Display the ThinkRank hero section (Site Identity → Hero & Branding)
67 *
68 * Usage in theme templates:
69 * <?php thinkrank_hero(); ?>
70 *
71 * Also available as the [thinkrank_hero] shortcode for use in content.
72 *
73 * @since 1.19.0
74 *
75 * @param array $args Optional. Reserved for future display arguments.
76 * @return void
77 */
78 function thinkrank_hero($args = []) {
79 /**
80 * Fires to display the ThinkRank hero section.
81 *
82 * @since 1.19.0
83 *
84 * @param array $args Hero display arguments.
85 */
86 do_action('thinkrank_hero', $args);
87 }
88
89 /**
90 * Get the ThinkRank hero section data without displaying it
91 *
92 * @since 1.19.0
93 *
94 * @return array|null Hero data (title, subtitle, cta_text, cta_url,
95 * background_image, html) or null if not available
96 */
97 function thinkrank_get_hero() {
98 // Check if ThinkRank is loaded
99 if (!function_exists('thinkrank')) {
100 return null;
101 }
102
103 $plugin = thinkrank();
104 if (!$plugin) {
105 return null;
106 }
107
108 $seo_manager = $plugin->get_component('frontend_seo');
109
110 if (!$seo_manager || !method_exists($seo_manager, 'get_current_hero')) {
111 return null;
112 }
113
114 return $seo_manager->get_current_hero();
115 }
116
117 /**
118 * Check if ThinkRank SEO is handling the current page
119 *
120 * @since 1.0.0
121 *
122 * @return bool True if ThinkRank is handling SEO for current page
123 */
124 function thinkrank_is_seo_active() {
125 // Check if ThinkRank is loaded
126 if (!function_exists('thinkrank')) {
127 return false;
128 }
129
130 $plugin = thinkrank();
131 if (!$plugin) {
132 return false;
133 }
134
135 $seo_manager = $plugin->get_component('frontend_seo');
136
137 if (!$seo_manager || !method_exists($seo_manager, 'has_seo_data')) {
138 return false;
139 }
140
141 return $seo_manager->has_seo_data();
142 }
143
144 /**
145 * Get current page SEO metadata
146 *
147 * @since 1.0.0
148 *
149 * @return array Current SEO metadata
150 */
151 function thinkrank_get_seo_metadata() {
152 // Check if ThinkRank is loaded
153 if (!function_exists('thinkrank')) {
154 return [];
155 }
156
157 $plugin = thinkrank();
158 if (!$plugin) {
159 return [];
160 }
161
162 $seo_manager = $plugin->get_component('frontend_seo');
163
164 if (!$seo_manager || !method_exists($seo_manager, 'get_current_metadata')) {
165 return [];
166 }
167
168 return $seo_manager->get_current_metadata();
169 }
170
171 /**
172 * Get breadcrumb inline CSS
173 *
174 * @since 1.0.0
175 *
176 * @return string CSS styles for breadcrumbs
177 */
178 function thinkrank_get_breadcrumb_css(): string {
179 return '
180 .thinkrank-breadcrumbs {
181 margin: 1rem 0;
182 font-size: 0.9rem;
183 }
184 .thinkrank-breadcrumbs .breadcrumb-prefix {
185 font-weight: 600;
186 margin-right: 0.5rem;
187 }
188 .thinkrank-breadcrumbs .breadcrumb-list {
189 list-style: none;
190 margin: 0;
191 padding: 0;
192 display: flex;
193 flex-wrap: wrap;
194 align-items: center;
195 }
196 .thinkrank-breadcrumbs .breadcrumb-item {
197 margin: 0;
198 padding: 0;
199 display: flex;
200 align-items: center;
201 }
202 .thinkrank-breadcrumbs .breadcrumb-item a {
203 color: #0073aa;
204 text-decoration: none;
205 }
206 .thinkrank-breadcrumbs .breadcrumb-item a:hover {
207 text-decoration: underline;
208 }
209 .thinkrank-breadcrumbs .breadcrumb-item.current span {
210 color: #666;
211 font-weight: 500;
212 }
213 .thinkrank-breadcrumbs .breadcrumb-separator {
214 margin: 0 0.5rem;
215 color: #999;
216 }';
217 }
218
219 // Enqueue breadcrumb styles properly if breadcrumbs are enabled
220 add_action('wp_enqueue_scripts', function() {
221 // Check if ThinkRank is loaded
222 if (!function_exists('thinkrank')) {
223 return;
224 }
225
226 $plugin = thinkrank();
227 if (!$plugin) {
228 return;
229 }
230
231 $seo_manager = $plugin->get_component('frontend_seo');
232 if (!$seo_manager) {
233 return;
234 }
235
236 // Lightweight breadcrumb check — query the DB directly to avoid loading
237 // the full Site_Identity_Manager (115KB) on every frontend page
238 global $wpdb;
239 $table = $wpdb->prefix . 'thinkrank_seo_settings';
240
241 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Lightweight frontend check avoids loading heavy manager class
242 $breadcrumbs_enabled = $wpdb->get_var(
243 $wpdb->prepare(
244 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name uses WordPress prefix, safe to interpolate
245 "SELECT setting_value FROM `{$table}` WHERE context_type = %s AND context_id = %d AND setting_category = %s AND setting_key = %s AND is_active = 1",
246 'site',
247 0,
248 'site_identity',
249 'breadcrumbs_enabled'
250 )
251 );
252
253 if ($breadcrumbs_enabled) {
254 wp_enqueue_style(
255 'thinkrank-breadcrumbs',
256 THINKRANK_PLUGIN_URL . 'static/css/breadcrumbs.css',
257 [],
258 THINKRANK_VERSION
259 );
260 }
261
262 // Lightweight hero check — only load hero CSS when the hero will actually
263 // render. Mirrors the render gate in SEO_Manager::generate_hero_html():
264 // a title, a subtitle, or a COMPLETE CTA (both text and URL). A CTA with
265 // text but no URL renders nothing, so it must not pull in the stylesheet.
266 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Lightweight frontend check avoids loading heavy manager class
267 $hero_fields = $wpdb->get_results(
268 $wpdb->prepare(
269 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Table name uses WordPress prefix, safe to interpolate
270 "SELECT setting_key, setting_value FROM `{$table}` WHERE context_type = %s AND context_id = %d AND setting_category = %s AND setting_key IN (%s, %s, %s, %s) AND is_active = 1",
271 'site',
272 0,
273 'site_identity',
274 'hero_title',
275 'hero_subtitle',
276 'hero_cta_text',
277 'hero_cta_url'
278 ),
279 OBJECT_K
280 );
281
282 $hero_value = static function ($key) use ($hero_fields) {
283 return isset($hero_fields[$key]) ? trim((string) $hero_fields[$key]->setting_value) : '';
284 };
285
286 $hero_renders = '' !== $hero_value('hero_title')
287 || '' !== $hero_value('hero_subtitle')
288 || ('' !== $hero_value('hero_cta_text') && '' !== $hero_value('hero_cta_url'));
289
290 if ($hero_renders) {
291 wp_enqueue_style(
292 'thinkrank-hero',
293 THINKRANK_PLUGIN_URL . 'static/css/hero.css',
294 [],
295 THINKRANK_VERSION
296 );
297 }
298 });
299