Skip to main content

Overview

The GeoAI_Meta class manages all meta tag output in the website head section. It handles SEO titles, meta descriptions, robots directives, and canonical URLs. The class respects compatibility mode to avoid conflicts with other SEO plugins. Namespace: GeoAI\Core Location: includes/class-geoai-meta.php

Key Features

  • Custom SEO title output
  • Meta description generation
  • Robots meta tag control
  • Canonical URL management
  • Template variable parsing
  • Post editor meta box
  • Compatibility mode support

Public Methods

get_instance()

Returns the singleton instance of the meta class.
public static function get_instance()
Returns: GeoAI_Meta - The singleton instance Example:
$meta = \GeoAI\Core\GeoAI_Meta::get_instance();

filter_title()

Filters the document title with custom SEO title.
public function filter_title( $title )
title
string
required
The original document title
Returns: string - Filtered title or original if no custom title set Hooks: pre_get_document_title Example:
add_filter( 'pre_get_document_title', function( $title ) {
    return $title . ' - Custom Suffix';
}, 20 );

output_meta_tags()

Outputs meta tags in the website head section.
public function output_meta_tags()
Hooks: wp_head (priority 1) Outputs:
  • meta name="description" - Meta description
  • meta name="robots" - Robots directives
  • link rel="canonical" - Canonical URL

add_meta_box()

Adds GEO AI SEO meta box to post editor screens.
public function add_meta_box()
Hooks: add_meta_boxes Added to: All public post types (posts, pages, custom post types) Position: Normal, High priority

render_meta_box()

Renders the SEO meta box content in post editor.
public function render_meta_box( $post )
post
WP_Post
required
The post object being edited
Fields:
  • SEO Title (max 70 characters)
  • Meta Description (max 165 characters)
  • Robots Meta (dropdown)
  • AI Generate button

save_meta_box()

Saves meta box data when post is saved.
public function save_meta_box( $post_id )
post_id
int
required
The post ID being saved
Hooks: save_post Security:
  • Nonce verification
  • Autosave check
  • Capability check

Template Variables

The following variables can be used in title and meta templates:

Available Variables

%%title%%
string
Post or page title
%%sitename%%
string
Site name from WordPress settings
%%sitedesc%%
string
Site tagline/description
%%sep%%
string
Separator character (default: |)
%%excerpt%%
string
Post excerpt
%%date%%
string
Post publish date
%%modified%%
string
Post modified date
%%id%%
string
Post ID
%%author%%
string
Post author name

Template Examples

// Post title template
'%%title%% %%sep%% %%sitename%%'
// Output: "My Blog Post | My Website"

// Page title template  
'%%title%% - %%sitename%%'
// Output: "About Us - My Website"

// Homepage title
'%%sitename%% %%sep%% %%sitedesc%%'
// Output: "My Website | Your trusted source"

// Date-based title
'%%title%% (%%date%%) - %%sitename%%'
// Output: "News Article (March 4, 2026) - My Website"

Post Meta Keys

Stored Meta Data

_geoai_title
string
Custom SEO title for the post
_geoai_meta_desc
string
Custom meta description for the post
_geoai_robots
string
Robots meta directives (e.g., “noindex,follow”)

Reading Meta Data

$title = get_post_meta( $post_id, '_geoai_title', true );
$description = get_post_meta( $post_id, '_geoai_meta_desc', true );
$robots = get_post_meta( $post_id, '_geoai_robots', true );

Updating Meta Data

update_post_meta( $post_id, '_geoai_title', 'Custom SEO Title' );
update_post_meta( $post_id, '_geoai_meta_desc', 'Custom meta description here' );
update_post_meta( $post_id, '_geoai_robots', 'noindex,follow' );

Robots Meta Options

Available Directives

default
string
Empty value, uses default behavior (index, follow)
noindex,follow
string
Prevent indexing but allow following links
index,nofollow
string
Allow indexing but don’t follow links
noindex,nofollow
string
Prevent indexing and don’t follow links

Usage Examples

Get Current Page Title

$meta = \GeoAI\Core\GeoAI_Meta::get_instance();

// The title is automatically filtered
$title = wp_get_document_title();

Set Custom Meta for Post

$post_id = 123;

update_post_meta( $post_id, '_geoai_title', 'Complete Guide to WordPress SEO' );
update_post_meta( $post_id, '_geoai_meta_desc', 'Learn everything about WordPress SEO in this comprehensive guide. Improve rankings today!' );

Noindex a Post

update_post_meta( $post_id, '_geoai_robots', 'noindex,follow' );

Get Meta Description with Fallback

if ( is_singular() ) {
    $post_id = get_the_ID();
    $description = get_post_meta( $post_id, '_geoai_meta_desc', true );
    
    if ( empty( $description ) ) {
        // Fallback to excerpt
        $description = wp_trim_words( get_the_excerpt(), 30 );
    }
    
    echo esc_attr( $description );
}

Custom Template Variables

Extend available variables with a filter:
add_filter( 'geoai_template_variables', function( $variables ) {
    $variables['%%custom%%'] = 'My Custom Value';
    return $variables;
});

Compatibility Mode

The class checks compatibility mode before outputting meta tags:
if ( ! GeoAI_Compat::get_instance()->should_output_meta() ) {
    return; // Skip output in coexist mode
}
This prevents duplicate meta tags when using GEO AI alongside other SEO plugins.

Character Limits

SEO Title
string
50-60 characters (max 70) to avoid truncation in search results
Meta Description
string
150-160 characters (max 165) for optimal display in SERPs

Live Character Counter

The meta box includes JavaScript character counters that update in real-time:
jQuery('#geoai_title').on('input', function() {
    var length = jQuery(this).val().length;
    // Update counter display
});

Meta Box Features

AI Generation Integration

The meta box includes an “Generate with AI” button that:
  1. Sends AJAX request to geoai_generate_meta action
  2. Receives optimized title and description from Gemini API
  3. Auto-fills the meta fields
  4. Shows success/error status

JavaScript Events

// Listen for AI generation
jQuery(document).on('geoai_meta_generated', function(event, data) {
    console.log('Title:', data.title);
    console.log('Description:', data.description);
});

Build docs developers (and LLMs) love