kalakotra/silverstripe-pageanalyzer

AI-powered page content and SEO meta analyser for SilverStripe 6.1, powered by Kalakotra AIGateway.

Maintainers

Package info

github.com/kalakotra/silverstripe-pageanalyzer

Type:silverstripe-vendormodule

pkg:composer/kalakotra/silverstripe-pageanalyzer

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-04-10 12:48 UTC

This package is auto-updated.

Last update: 2026-04-15 07:07:37 UTC


README

AI-powered page content and SEO meta analyzer for SilverStripe 6.1+. Automatically generates optimized Meta Titles, Meta Descriptions, and page content suggestions powered by your configured AI provider (OpenAI, Gemini, or Anthropic Claude).

Integrates seamlessly with Kalakotra AIGateway for provider abstraction and audit logging.

Features

  • One-click AI analysis: "Analyse with AI" button in CMS toolbar
  • SEO meta optimization: AI-generated Meta Title (60 chars) and Meta Description (160 chars) with character count validation
  • Content suggestions: Full-page content rewrite suggestions based on focus keywords
  • Side-by-side comparison: Review current vs. AI-recommended values before applying
  • Single-click apply: Apply all recommendations in one action; creates a new draft version
  • Focus keywords: Configurable keywords to guide AI analysis prompt
  • Analysis tracking: Last analysed timestamp, model used, full audit trail via AIGateway logs
  • Smart indicators: Sidebar badge and "AI Analysis" tab show recommendation status
  • Read-only detail view: All recommendations displayed in a rich, styled comparison layout
  • Form integration: CMS-native UI using SilverStripe Forms API

Requirements

  • PHP: 8.2+
  • SilverStripe: 6.1+
  • Kalakotra AIGateway: * (latest version)
  • lekoala/silverstripe-cms-actions: For custom toolbar actions

Installation

Install via Composer:

composer require kalakotra/silverstripe-pageanalyzer

Run migrations:

vendor/bin/sake dev/build flush=all

Quick Start

1. Configure AI Gateway

Before using PageAnalyzer, set up at least one active AI provider:

  1. Go to CMS → AI Gateway → Providers
  2. Create and activate a provider (OpenAI, Gemini, or Anthropic)
  3. Test the connection

See Kalakotra AIGateway README for detailed setup.

2. (Optional) Set Focus Keywords

  1. Edit any page in the CMS
  2. Go to the SEO tab
  3. Enter comma-separated focus keywords (e.g., SEO, optimization, content)
  4. These keywords guide the AI analysis prompt for more targeted recommendations

3. Analyze & Review

  1. Click the 🤖 Analyse with AI button in the toolbar
  2. Copy/paste current page content into the prompt if desired (PageAnalyzer uses page title, meta, and content)
  3. Wait for analysis to complete (typically 2–10 seconds depending on provider)
  4. Review the AI Analysis tab to compare current vs. recommended values:
    • Meta Title (current length vs. SEO ideal ~55 chars)
    • Meta Description (current length vs. SEO ideal ~155 chars)
    • Full page content suggestions

4. Apply Recommendations

  1. Review the suggestions in the AI Analysis tab
  2. Click ✅ Apply All AI Changes to apply all three recommendations at once
  3. A new draft version is created; you can review the diff in version history
  4. The recommendation indicator badge disappears once applied

Configuration

Basic Setup

Apply to all pages via YAML:

# app/_config/pageanalyzer.yml
---
Name: myproject-pageanalyzer
After: pageanalyzer

SilverStripe\CMS\Model\SiteTree:
  extensions:
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerExtension
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerCMSExtension

Per-Page Type

Limit to specific page classes:

# app/_config/pageanalyzer.yml
---
Name: myproject-pageanalyzer-selective
After: pageanalyzer

App\Pages\BlogPost:
  extensions:
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerExtension
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerCMSExtension

App\Pages\ServicePage:
  extensions:
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerExtension
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerCMSExtension

Tune Analysis Parameters

# app/_config/pageanalyzer.yml
---
Name: myproject-pageanalyzer-tuning

Kalakotra\PageAnalyzer\Services\PageAnalysisService:
  meta_title_max: 60        # Target max length for Meta Title
  meta_description_max: 160 # Target max length for Meta Description
  caller_context: 'page-analysis'  # Audit log label

Usage

Enable for a Page

The extension is automatically enabled on all SiteTree pages (or your configured page types) once installed.

To manually check if a page has PageAnalyzer enabled:

use Kalakotra\PageAnalyzer\Extensions\PageAnalyzerExtension;

$page = $this->getPage();
if ($page->hasExtension(PageAnalyzerExtension::class)) {
    // PageAnalyzer is enabled
}

Programmatic Analysis

Run analysis from code (not just the CMS):

use Kalakotra\PageAnalyzer\Services\PageAnalysisService;
use SilverStripe\Core\Injector\Injector;

$service = Injector::inst()->get(PageAnalysisService::class);
$page = Page::get()->byID(1);

try {
    $service->analyse($page);
    
    // After analysis, recommendations are persisted on the page:
    echo $page->AIRecommendedMetaTitle;       // e.g., "Best SEO Tips 2024"
    echo $page->AIRecommendedMetaDescription; // e.g., "Learn proven SEO strategies..."
    echo $page->AIRecommendedContent;         // e.g., "Full optimized content..."
    echo $page->HasAIRecommendation;          // true
    
} catch (\Exception $e) {
    error_log("Analysis failed: " . $e->getMessage());
}

Apply Recommendations from Code

$page = Page::get()->byID(1);

if ($page->HasAIRecommendation) {
    // Copy AI recommendations to live fields
    $page->MetaTitle       = $page->AIRecommendedMetaTitle;
    $page->MetaDescription = $page->AIRecommendedMetaDescription;
    $page->Content         = $page->AIRecommendedContent;
    
    // Clear the flag
    $page->HasAIRecommendation = false;
    
    // Create new draft version
    $page->write();
    
    echo "✓ Recommendations applied.";
}

Check Analysis Status

$page = Page::get()->byID(1);

if ($page->HasAIRecommendation) {
    echo "📋 Pending recommendations from " . $page->obj('LastAnalysedAt')->Nice();
    echo "Model: " . $page->AnalysisModelUsed;
} else {
    echo "✓ No pending recommendations";
}

CMS Interface

AI Analysis Tab

Accessible when viewing any page with PageAnalyzer enabled:

Status Banner

  • Shows when recommendations are pending
  • Indicates how to review and apply them

Analysis Metadata

  • Last Analysed: Timestamp of most recent analysis
  • Model Used: Which AI model ran the analysis (e.g., "gpt-4o")

SEO Meta Recommendations Table

Three-column layout:

Field Current Value AI Recommendation
Meta Title (60 chars max) Example: "Home" Example: "Best SEO Practices for Home..."
Meta Description (160 chars max) Example: "Welcome" Example: "Learn proven SEO strategies to boost your ranking and drive organic traffic..."

Character count badges show:

  • 🟢 OK (within target range)
  • 🟡 Warning (close to limit)
  • 🔴 Over (exceeds recommended length)
  • Empty (no content)

Optimised Content Section

Side-by-side preview of:

  • Current Page Content (left, limited to 320px height with scroll)
  • AI Recommended Content (right, green background, same layout)

Sidebar Badge

Page listing shows at-a-glance status:

  • 💡 AI has suggestions for SEO — Recommendations pending
  • No AI suggestions — No pending recommendations (or not yet analysed)

Toolbar Actions

Only visible when editing a page with PageAnalyzer:

  1. 🤖 Analyse with AI (blue outline button)

    • Always visible
    • Runs analysis immediately
    • Shows refresh spinner while running
    • Displays success/error notification
    • Refreshes form to show new tab
  2. ✅ Apply All AI Changes (green button)

    • Only visible when HasAIRecommendation is true
    • Applies all three recommendations in one action
    • Closes the form and returns to page list
    • Creates new draft version for review in history

Architecture

Components

PageAnalyzerExtension

SiteTree DataObject extension that:

  • Adds AI recommendation fields (DB columns)
  • Adds analysis metadata (timestamp, model used, flag)
  • Provides updateCMSFields() to inject the AI Analysis tab
  • Implements action handlers doAnalyseWithAI() and doApplyAllAIChanges()
  • Computes virtual field AIStatusLabel for sidebar display

PageAnalyzerCMSExtension

SiteTree extension that:

  • Hooks into updateCMSActions() to add toolbar buttons
  • Creates CustomAction buttons for the CMS toolbar
  • Pushes actions to the MajorActions field list

PageAnalysisService

Orchestrator service that:

  • Takes a page object and optional focus keywords
  • Constructs an intelligent prompt based on page content and keywords
  • Calls AIGatewayService to get AI recommendations
  • Parses response and persists fields on the page
  • Sets HasAIRecommendation flag and LastAnalysedAt timestamp
  • Handles and re-throws exceptions with context

PageAnalysisException

Typed exception for analysis-specific errors:

throw new PageAnalysisException(
    'Analysis failed for page ' . $page->Title,
    reason: 'InvalidFocusKeywords'  // or other codes
);

Request Flow (CMS Action)

User clicks "🤖 Analyse with AI" button
      ↓
lekoala/silverstripe-cms-actions routes to PageAnalyzerExtension::doAnalyseWithAI()
      ↓
doAnalyseWithAI() calls PageAnalysisService::analyse($page)
      ↓
PageAnalysisService builds prompt (page content + focus keywords)
      ↓
Calls AIGatewayService::sendPrompt()
      ↓
AIGateway fetches active provider config
      ↓
Calls provider API (OpenAI/Gemini/Anthropic)
      ↓
Receives normalized AIResponseDTO
      ↓
AIGateway writes audit log entry to AILog
      ↓
PageAnalysisService parses response:
  - Extracts meta title
  - Extracts meta description
  - Extracts suggested content
      ↓
Persists to page:
  - page->AIRecommendedMetaTitle
  - page->AIRecommendedMetaDescription
  - page->AIRecommendedContent
  - page->HasAIRecommendation = true
  - page->LastAnalysedAt = now()
  - page->AnalysisModelUsed = model name
      ↓
page->write()  (creates new draft version)
      ↓
Return success message
      ↓
CMS form refreshes to show AI Analysis tab with new recommendations

Data Model

SiteTree Extensions (DB fields)

FocusKeywords              Varchar(255)    # User-provided keywords guiding analysis
AIRecommendedMetaTitle     Varchar(255)    # Generated meta title
AIRecommendedMetaDescription Text          # Generated meta description
AIRecommendedContent       HTMLText        # Generated page content
HasAIRecommendation        Boolean         # Flag: recommendations pending
LastAnalysedAt             Datetime        # When analysis was run
AnalysisModelUsed          Varchar(128)    # Which model generated these (gpt-4o, etc.)

Audit Trail

Full audit trail via AIGateway's AILog:

AILog entry created for every analysis call:
  - Provider slug & model used
  - Prompt (page content + keywords)
  - Response (AI recommendations)
  - Token accounting
  - Latency
  - Success/error status
  - Caller context: 'page-analysis'

View in CMS → AI Gateway → Call Logs.

Examples

Example 1: Basic Analysis

// In a BuildTask or controller
use Kalakotra\PageAnalyzer\Services\PageAnalysisService;
use SilverStripe\CMS\Model\SiteTree;
use SilverStripe\Core\Injector\Injector;

$pages = SiteTree::get()->filter('URLSegment', 'services');
$service = Injector::inst()->get(PageAnalysisService::class);

foreach ($pages as $page) {
    try {
        $service->analyse($page);
        echo "✓ Analysed: {$page->Title}\n";
    } catch (\Exception $e) {
        echo "✗ Error: {$e->getMessage()}\n";
    }
}

Example 2: Batch Apply Recommendations

// Auto-apply recommendations for all blog posts if they're "good"
use SilverStripe\CMS\Model\SiteTree;

$pages = SiteTree::get()->filter('HasAIRecommendation', true);

foreach ($pages as $page) {
    // Simple heuristic: apply if title is reasonable length
    $titleLen = strlen($page->AIRecommendedMetaTitle);
    if ($titleLen >= 40 && $titleLen <= 65) {
        $page->MetaTitle       = $page->AIRecommendedMetaTitle;
        $page->MetaDescription = $page->AIRecommendedMetaDescription;
        $page->Content         = $page->AIRecommendedContent;
        $page->HasAIRecommendation = false;
        $page->write();
        echo "✓ Applied: {$page->Title}\n";
    }
}

Example 3: Custom Prompt

If you need a different prompt format, extend PageAnalysisService:

namespace MyApp\Services;

use Kalakotra\PageAnalyzer\Services\PageAnalysisService as BaseService;
use SilverStripe\CMS\Model\SiteTree;

class CustomPageAnalysisService extends BaseService
{
    protected function buildPrompt(SiteTree $page, string $focusKeywords): string
    {
        // Custom prompt logic
        return sprintf(
            "You are an expert SEO content strategist.\n"
            . "Page Title: %s\n"
            . "Current Meta: %s\n"
            . "Focus Keywords: %s\n"
            . "Optimize for: technical SEO, user intent, keyword density\n"
            . "Content: %s",
            $page->Title,
            $page->MetaDescription,
            $focusKeywords,
            $page->Content
        );
    }
}

Register in YAML:

SilverStripe\Core\Injector\Injector:
  Kalakotra\PageAnalyzer\Services\PageAnalysisService:
    class: MyApp\Services\CustomPageAnalysisService

Performance

Token Usage

Analysis typically consumes:

  • Input tokens: 500–2000 (depends on page length + focus keywords)
  • Output tokens: 300–500 (recommendations are relatively compact)
  • Total per page: 1000–2500 tokens ($0.01–0.03 USD with GPT-4o)

Monitor via CMS → AI Gateway → Call Logs to understand your AI costs.

Caching Recommendations

To avoid re-analyzing unchanged content:

$page = Page::get()->byID(1);

// Check if content has changed since last analysis
$contentHash = md5($page->Content . $page->Title);
$hasChanged = ($page->ContentHash !== $contentHash);

if ($hasChanged || !$page->HasAIRecommendation) {
    $service->analyse($page);
}

Async Analysis (BuildTask)

For large-scale analysis, run asynchronously:

use SilverStripe\Dev\BuildTask;
use Kalakotra\PageAnalyzer\Services\PageAnalysisService;

class AnalyseAllPagesTask extends BuildTask
{
    private static string $segment = 'analyse-all-pages';
    protected string $title = 'Analyse all pages with AI';
    protected string $description = 'Run AI analysis on all SiteTree pages';

    private PageAnalysisService $service;

    public function __construct(PageAnalysisService $service)
    {
        parent::__construct();
        $this->service = $service;
    }

    public function run($request)
    {
        $pages = SiteTree::get()->exclude('ClassName', 'ErrorPage');
        foreach ($pages as $page) {
            try {
                $this->service->analyse($page);
                echo "{$page->Title}\n";
            } catch (\Exception $e) {
                echo "{$page->Title}: {$e->getMessage()}\n";
            }
        }
    }
}

Run:

vendor/bin/sake dev/tasks/AnalyseAllPagesTask

Security

Focus Keywords Validation

User-provided focus keywords are validated before use:

// Sanitized to prevent prompt injection
$focusKeywords = preg_replace('/[^a-zA-Z0-9, ]/', '', $focusKeywords);

Audit Trail

Every analysis call is logged to AILog with:

  • Page ID and title
  • Prompt content (for debugging)
  • AI response (for validation)
  • Model used
  • Provider slug
  • Caller context: page-analysis

Permissions

Page editor must have CMS access to:

  • View the AI Analysis tab
  • Click "Analyse with AI"
  • Click "Apply All AI Changes"

Permissions inherited from standard page edit checks.

Content Safety

  • AI recommendations are stored as-is in the database
  • Review recommendations before applying (compare tab)
  • AI response is sanitized via SilverStripe's HTMLText sanitizer when saved to Content field
  • Audit logs capture full response for compliance review

Troubleshooting

"No AI recommendations available" Error

Cause: No active AI Gateway provider configured.

Fix:

  1. Go to CMS → AI Gateway → Providers
  2. Create at least one provider
  3. Click Test Connection
  4. Check Set as Active Provider
  5. Save and retry analysis

Analysis Timeout

Cause: AI provider API is slow or unresponsive.

Fix:

  1. Check internet connection
  2. Verify provider API key is valid (click Test Connection in CMS)
  3. Try again (some providers are temporarily busy)
  4. Switch to a different provider for faster responses

Recommendations Not Showing

Cause: Page may not have PageAnalyzer extension applied.

Fix:

  1. Check YAML config includes extension for your page type
  2. Run dev/build flush=all
  3. Reload CMS page

Poor Quality Recommendations

Cause: Focus keywords not specific enough or page content too vague.

Fix:

  1. Add more detailed focus keywords (e.g., "B2B SaaS, technical content, enterprise solutions")
  2. Ensure page has substantial existing content for context
  3. Try a different AI provider (OpenAI GPT-4o often produces best results)
  4. Manually refine AI recommendations before applying

Token Limit Exceeded

Cause: Page content is extremely long (10,000+ words).

Fix:

  1. Break into multiple shorter pages
  2. Focus on key sections rather than entire page
  3. Check AILog for token usage; consider provider with higher limits

Integration with Other Modules

With SilverStripe Local SEO

Page Analyzer pairs well with silverstripe-local-seo:

# Both modules on same page
SilverStripe\CMS\Model\SiteTree:
  extensions:
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerExtension
    - Kalakotra\PageAnalyzer\Extensions\PageAnalyzerCMSExtension
    - Kalakotra\LocalSEO\Extensions\SeoAuditPageExtension
  • PageAnalyzer: AI-generated recommendations
  • LocalSEO: Audit & tracking of actual SEO metrics
  • Together: Recommendations + validation pipeline

Support & Contributing

For issues or questions:

  1. Check the AIGateway logs for diagnostic clues
  2. Verify AI provider is configured and active
  3. Try a different provider
  4. Check page content is substantial and relevant
  5. Contact your SilverStripe administrator

License

Proprietary. See LICENSE file.

Changelog

v1.0.0 (Initial Release)

  • One-click AI analysis for pages
  • Meta title & description optimization
  • Content suggestion generation
  • Side-by-side comparison UI
  • Single-click apply all recommendations
  • Focus keywords support
  • Analysis tracking & audit logging
  • CMS toolbar integration
  • Character count validation