kalakotra / silverstripe-pageanalyzer
AI-powered page content and SEO meta analyser for SilverStripe 6.1, powered by Kalakotra AIGateway.
Package info
github.com/kalakotra/silverstripe-pageanalyzer
Type:silverstripe-vendormodule
pkg:composer/kalakotra/silverstripe-pageanalyzer
Requires
- php: ^8.2
- kalakotra/silverstripe-aigateway: *
- silverstripe/cms: ^6.1
- silverstripe/framework: ^6.1
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:
- Go to CMS → AI Gateway → Providers
- Create and activate a provider (OpenAI, Gemini, or Anthropic)
- Test the connection
See Kalakotra AIGateway README for detailed setup.
2. (Optional) Set Focus Keywords
- Edit any page in the CMS
- Go to the SEO tab
- Enter comma-separated focus keywords (e.g.,
SEO, optimization, content) - These keywords guide the AI analysis prompt for more targeted recommendations
3. Analyze & Review
- Click the 🤖 Analyse with AI button in the toolbar
- Copy/paste current page content into the prompt if desired (PageAnalyzer uses page title, meta, and content)
- Wait for analysis to complete (typically 2–10 seconds depending on provider)
- 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
- Review the suggestions in the AI Analysis tab
- Click ✅ Apply All AI Changes to apply all three recommendations at once
- A new draft version is created; you can review the diff in version history
- 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:
-
🤖 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
-
✅ Apply All AI Changes (green button)
- Only visible when
HasAIRecommendationis true - Applies all three recommendations in one action
- Closes the form and returns to page list
- Creates new draft version for review in history
- Only visible when
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()anddoApplyAllAIChanges() - Computes virtual field
AIStatusLabelfor sidebar display
PageAnalyzerCMSExtension
SiteTree extension that:
- Hooks into
updateCMSActions()to add toolbar buttons - Creates CustomAction buttons for the CMS toolbar
- Pushes actions to the
MajorActionsfield 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
HasAIRecommendationflag andLastAnalysedAttimestamp - 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:
- Go to CMS → AI Gateway → Providers
- Create at least one provider
- Click Test Connection
- Check Set as Active Provider
- Save and retry analysis
Analysis Timeout
Cause: AI provider API is slow or unresponsive.
Fix:
- Check internet connection
- Verify provider API key is valid (click Test Connection in CMS)
- Try again (some providers are temporarily busy)
- Switch to a different provider for faster responses
Recommendations Not Showing
Cause: Page may not have PageAnalyzer extension applied.
Fix:
- Check YAML config includes extension for your page type
- Run
dev/build flush=all - Reload CMS page
Poor Quality Recommendations
Cause: Focus keywords not specific enough or page content too vague.
Fix:
- Add more detailed focus keywords (e.g., "B2B SaaS, technical content, enterprise solutions")
- Ensure page has substantial existing content for context
- Try a different AI provider (OpenAI GPT-4o often produces best results)
- Manually refine AI recommendations before applying
Token Limit Exceeded
Cause: Page content is extremely long (10,000+ words).
Fix:
- Break into multiple shorter pages
- Focus on key sections rather than entire page
- 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:
- Check the AIGateway logs for diagnostic clues
- Verify AI provider is configured and active
- Try a different provider
- Check page content is substantial and relevant
- 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