add_action('wp_head', [$this, 'output_meta_tags'], 1); // Replace the browser tab title add_filter('pre_get_document_title', [$this, 'output_seo_title'], 10); } /** * Replace the page tag with our custom SEO title */ public function output_seo_title($title) { if (!is_singular()) { return $title; } $post_id = get_queried_object_id(); $seo_title = get_post_meta($post_id, '_shadowsync_seo_meta_title', true); if (!empty($seo_title)) { return esc_html($seo_title); } return $title; } /** * Output all meta tags into <head> */ public function output_meta_tags() { if (!is_singular()) { return; } $post_id = get_queried_object_id(); $post = get_post($post_id); $seo_title = get_post_meta($post_id, '_shadowsync_seo_meta_title', true); $seo_desc = get_post_meta($post_id, '_shadowsync_seo_meta_description', true); $canonical = get_permalink($post_id); // Fallbacks if (empty($seo_title)) { $seo_title = get_the_title($post_id); } if (empty($seo_desc)) { // Auto-generate from content if missing $content = wp_strip_all_tags($post->post_content); $seo_desc = wp_trim_words($content, 25, '...'); } // The Social tab's title and description, when set, are what // Facebook, WhatsApp, LinkedIn and X show; otherwise the SEO ones. $social_title = get_post_meta($post_id, '_shadowsync_seo_social_title', true); $social_desc = get_post_meta($post_id, '_shadowsync_seo_social_description', true); $share_title = !empty($social_title) ? $social_title : $seo_title; $share_desc = !empty($social_desc) ? $social_desc : $seo_desc; // Thumbnail for OG image $og_image = ''; if (has_post_thumbnail($post_id)) { $thumb = wp_get_attachment_image_src(get_post_thumbnail_id($post_id), 'large'); $og_image = $thumb ? $thumb[0] : ''; } $site_name = get_bloginfo('name'); echo "\n<!-- ShadowSync SEO Meta Tags -->\n"; // Meta description if (!empty($seo_desc)) { echo '<meta name="description" content="' . esc_attr($seo_desc) . '">' . "\n"; } // Canonical URL echo '<link rel="canonical" href="' . esc_url($canonical) . '">' . "\n"; // Open Graph (Facebook, WhatsApp, LinkedIn) echo '<meta property="og:type" content="article">' . "\n"; echo '<meta property="og:title" content="' . esc_attr($share_title) . '">' . "\n"; echo '<meta property="og:description" content="' . esc_attr($share_desc) . '">' . "\n"; echo '<meta property="og:url" content="' . esc_url($canonical) . '">' . "\n"; echo '<meta property="og:site_name" content="' . esc_attr($site_name) . '">' . "\n"; if (!empty($og_image)) { echo '<meta property="og:image" content="' . esc_url($og_image) . '">' . "\n"; } // Twitter Card echo '<meta name="twitter:card" content="summary_large_image">' . "\n"; echo '<meta name="twitter:title" content="' . esc_attr($share_title) . '">' . "\n"; echo '<meta name="twitter:description" content="' . esc_attr($share_desc) . '">' . "\n"; if (!empty($og_image)) { echo '<meta name="twitter:image" content="' . esc_url($og_image) . '">' . "\n"; } echo "<!-- / ShadowSync SEO -->\n\n"; } }