PHPackages                             kalakotra/silverstripe-pageanalyzer - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. kalakotra/silverstripe-pageanalyzer

ActiveSilverstripe-vendormodule[Utility &amp; Helpers](/categories/utility)

kalakotra/silverstripe-pageanalyzer
===================================

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

5.x-dev(3mo ago)00proprietaryPHPPHP ^8.2

Since Apr 10Pushed 3mo agoCompare

[ Source](https://github.com/kalakotra/silverstripe-pageanalyzer)[ Packagist](https://packagist.org/packages/kalakotra/silverstripe-pageanalyzer)[ RSS](/packages/kalakotra-silverstripe-pageanalyzer/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (4)Versions (2)Used By (0)

Page Analyzer for SilverStripe 6
================================

[](#page-analyzer-for-silverstripe-6)

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
--------

[](#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
------------

[](#requirements)

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

Installation
------------

[](#installation)

Install via Composer:

```
composer require kalakotra/silverstripe-pageanalyzer
```

Run migrations:

```
vendor/bin/sake dev/build flush=all
```

Quick Start
-----------

[](#quick-start)

### 1. Configure AI Gateway

[](#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](../aigateway-complete/README.md#configuration) for detailed setup.

### 2. (Optional) Set Focus Keywords

[](#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 &amp; Review

[](#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

[](#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
-------------

[](#configuration)

### Basic Setup

[](#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

[](#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

[](#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
-----

[](#usage)

### Enable for a Page

[](#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

[](#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

[](#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

[](#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
-------------

[](#cms-interface)

### AI Analysis Tab

[](#ai-analysis-tab)

Accessible when viewing any page with PageAnalyzer enabled:

#### Status Banner

[](#status-banner)

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

#### Analysis Metadata

[](#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

[](#seo-meta-recommendations-table)

Three-column layout:

FieldCurrent ValueAI 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

[](#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

[](#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

[](#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
------------

[](#architecture)

### Components

[](#components)

#### PageAnalyzerExtension

[](#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

[](#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

[](#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

[](#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)

[](#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

[](#data-model)

#### SiteTree Extensions (DB fields)

[](#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

[](#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
--------

[](#examples)

### Example 1: Basic Analysis

[](#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

[](#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 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

[](#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
-----------

[](#performance)

### Token Usage

[](#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

[](#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)

[](#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
--------

[](#security)

### Focus Keywords Validation

[](#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

[](#audit-trail-1)

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

[](#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

[](#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
---------------

[](#troubleshooting)

### "No AI recommendations available" Error

[](#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

[](#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

[](#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

[](#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

[](#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
------------------------------

[](#integration-with-other-modules)

### With SilverStripe Local SEO

[](#with-silverstripe-local-seo)

Page Analyzer pairs well with [silverstripe-local-seo](https://github.com/kalakotra/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 &amp; tracking of actual SEO metrics
- Together: Recommendations + validation pipeline

Support &amp; Contributing
--------------------------

[](#support--contributing)

For issues or questions:

1. Check the [AIGateway logs](#audit-trail) 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
-------

[](#license)

Proprietary. See LICENSE file.

Changelog
---------

[](#changelog)

### v1.0.0 (Initial Release)

[](#v100-initial-release)

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

###  Health Score

31

—

LowBetter than 65% of packages

Maintenance81

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity32

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

101d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3845734?v=4)[Kalakotra](/maintainers/kalakotra)[@kalakotra](https://github.com/kalakotra)

---

Top Contributors

[![kalakotra](https://avatars.githubusercontent.com/u/3845734?v=4)](https://github.com/kalakotra "kalakotra (3 commits)")

### Embed Badge

![Health badge](/badges/kalakotra-silverstripe-pageanalyzer/health.svg)

```
[![Health](https://phpackages.com/badges/kalakotra-silverstripe-pageanalyzer/health.svg)](https://phpackages.com/packages/kalakotra-silverstripe-pageanalyzer)
```

###  Alternatives

[silverstripe/userforms

UserForms enables CMS users to create dynamic forms via a drag and drop interface and without getting involved in any PHP code

1321.1M86](/packages/silverstripe-userforms)[symbiote/silverstripe-advancedworkflow

Adds configurable workflow support to the CMS, with a GUI for creating custom workflow definitions.

46302.4k9](/packages/symbiote-silverstripe-advancedworkflow)[silverstripe/sharedraftcontent

Share draft page content with non-CMS users

21424.1k12](/packages/silverstripe-sharedraftcontent)[lekoala/silverstripe-softdelete

Soft delete extension for SilverStripe

11236.3k](/packages/lekoala-silverstripe-softdelete)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
