wabisoft / craft-wabisoft-mimi
Log Twig pings to trace template and component usage across your site.
Installs: 11
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:craft-plugin
pkg:composer/wabisoft/craft-wabisoft-mimi
Requires
- php: >=8.2
- craftcms/cms: ^5.7.0
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
- marcocesarato/php-conventional-changelog: ^1.17
README
A comprehensive CraftCMS 5 plugin for tracking template and component usage. Track URL hits with optional tags, template paths, element context, and more. Perfect for understanding which pages, components, and templates are being used on your site.
Features
- Lightweight Twig function to track page/component usage
- Template path tracking - See which template files are rendering
- Element context tracking - Track which entries/elements are being viewed
- Multi-site support - Separate tracking for each site
- Tag system - Identify and track specific components
- Hit counting - Aggregate counts for each unique combination
- Session deduplication - Optional setting to prevent duplicate counts during development
- Dashboard widget - View statistics directly in the CP
- Console commands - Generate reports and manage data
- Performance optimized - Master on/off switch with zero-impact when disabled
Requirements
- PHP 8.2 or higher
- Craft CMS 5.7.0 or higher
Installation
-
Install the plugin via composer:
composer require wabisoft/craft-wabisoft-mimi
-
Install the plugin in Craft:
php craft plugin/install wabisoft-mimi
-
Run migrations to create/update the database table:
php craft migrate/all
Configuration
Navigate to Settings → Plugins → Wabisoft Mimi in the Craft control panel, or configure via environment variables.
Settings
Control Panel
- Enable Hit Tracking - Master switch to enable/disable all tracking. When disabled, the
mimi()function returns immediately without any database queries for optimal performance. - Deduplicate Session Hits - When enabled, hits will only be counted once per session. Useful for development/testing to avoid inflating counts during page refreshes.
Environment Variables
You can configure Mimi settings using environment variables in your .env file. This is especially useful for managing different settings across environments (local, staging, production).
Add these variables to your .env file:
# Enable or disable hit tracking (true/false, yes/no, 1/0) MIMI_TRACKING_ENABLED=true # Enable session-based deduplication (true/false, yes/no, 1/0) MIMI_DEDUPLICATE_SESSION=false
Then reference them in your plugin settings file (config/wabisoft-mimi.php):
<?php return [ 'trackingEnabled' => '$MIMI_TRACKING_ENABLED', 'deduplicateSession' => '$MIMI_DEDUPLICATE_SESSION', ];
Example use cases:
# Disable tracking in development MIMI_TRACKING_ENABLED=false # Enable tracking in production MIMI_TRACKING_ENABLED=true # Enable deduplication in development to avoid inflated counts MIMI_DEDUPLICATE_SESSION=true
Settings configured via environment variables will take precedence over Control Panel settings and will display a warning in the CP indicating the setting is environment-controlled.
Configuration Files:
The plugin includes example configuration files to get you started:
config.example.php- Copy to your Craftconfig/directory aswabisoft-mimi.php.env.example- Example environment variables to add to your project's.envfile
Usage
The mimi() Twig function supports both positional and named parameters for maximum flexibility:
Positional Parameters (Legacy)
mimi(tag, template, element)
Named Parameters (New)
mimi(tag, {element: block})
mimi(tag, {path: '/custom/path', element: block})
mimi(tag, {template: _self, element: entry})
Basic Usage
Track the current page without any additional context:
{% do mimi() %}
Track with Tags
Use tags to identify specific components or sections:
{# Track a hero component #} {% do mimi('hero-component') %} {# Track a sidebar widget #} {% do mimi('sidebar-widget') %} {# Track different variations #} {% do mimi('product-card-featured') %} {% do mimi('product-card-standard') %}
Track with Template Path
Positional (Legacy)
{# Track which template is rendering #} {% do mimi('hero-section', _self) %}
Named Parameters
{# Track with template object #} {% do mimi('hero-section', {template: _self}) %} {# Track with custom path #} {% do mimi('hero-section', {path: '/components/hero.twig'}) %}
This will record the actual template file path (e.g., _components/hero.twig), helping you:
- Find unused template files
- Understand template inheritance chains
- Debug which template version is actually rendering
Track with Element Context
Positional (Legacy)
{# Track with the current entry #} {% do mimi('product-detail', _self, entry) %} {# Track with a specific element #} {% for product in products %} {% do mimi('product-card', _self, product) %} {% endfor %}
Named Parameters
{# Track with element only #} {% do mimi('product-detail', {element: entry}) %} {# Track with element and custom path #} {% do mimi('product-detail', {path: '/products/detail.twig', element: entry}) %} {# Track with element and template #} {% do mimi('product-detail', {template: _self, element: entry}) %}
Flexible Content Block Tracking
The named parameter approach is especially useful for content blocks:
{% for block in entry.contentBlocks.all() %}
{# Clean, readable syntax #}
{% do mimi('block-' ~ block.type, {element: block}) %}
{# Or with custom path tracking #}
{% do mimi('block-' ~ block.type, {
path: '/blocks/' ~ block.type ~ '.twig',
element: block
}) %}
{{ block.render() }}
{% endfor %}
Complete Example
{% extends '_layouts/base' %}
{% block content %}
{# Track page load with template path #}
{% do mimi(null, {template: _self}) %}
<div class="hero">
{# Track hero component with template and entry context #}
{% do mimi('hero-section', {template: _self, element: entry}) %}
<h1>{{ entry.title }}</h1>
</div>
{% if entry.showSidebar %}
{# Track conditional sidebar rendering #}
{% do mimi('sidebar', {template: _self}) %}
<aside>
{{ entry.sidebarContent }}
</aside>
{% endif %}
{% for block in entry.contentBlocks.all() %}
{# Track each content block type with clean syntax #}
{% do mimi('block-' ~ block.type, {element: block}) %}
{{ block.render() }}
{% endfor %}
{% endblock %}
Component Templates
{# _components/card.twig #} {% do mimi('card-component', {template: _self, element: element ?? null}) %} <div class="card"> {# component markup #} </div>
Migration from Positional to Named Parameters
Both approaches work simultaneously, so you can migrate gradually:
{# Old way (still works) #} {% do mimi('block-' ~ block.type, _self, block) %} {# New way (more readable) #} {% do mimi('block-' ~ block.type, {element: block}) %} {# New way with custom path #} {% do mimi('block-' ~ block.type, { path: '/blocks/' ~ block.type ~ '.twig', element: block }) %}
Dashboard Widget
Add the Hit Statistics widget to your Craft CP dashboard to see:
- Total hits over a customizable time period
- Top pages by hit count
- Top components by tag
Configure the widget to show:
- Days to Look Back - Historical data range (default: 7 days)
- Number of Results - Maximum items to display (default: 10)
Console Commands
Report Commands
Generate reports about hit statistics:
# View top pages php craft wabisoft-mimi/report/top-pages --days=30 --limit=20 # View top components php craft wabisoft-mimi/report/components --days=7 --limit=10 # View top templates php craft wabisoft-mimi/report/templates --days=30 --limit=15 # View unused items (no hits in timeframe) php craft wabisoft-mimi/report/unused --days=60 # View summary statistics php craft wabisoft-mimi/report/summary --days=30
Cleanup Commands
Manage your hit tracking data:
# Delete records older than 90 days php craft wabisoft-mimi/cleanup/old --days=90 # Delete records older than 90 days without confirmation php craft wabisoft-mimi/cleanup/old --days=90 --force # Delete ALL records (with confirmation) php craft wabisoft-mimi/cleanup/all # Reset all hit counts to zero (keeps records) php craft wabisoft-mimi/cleanup/reset # Remove records with zero hits php craft wabisoft-mimi/cleanup/prune-zero # Consolidate duplicate records php craft wabisoft-mimi/cleanup/duplicates
Database Schema
The plugin creates a wabisoft_mimi_hits table with the following structure:
| Column | Type | Description |
|---|---|---|
id |
int | Primary key |
urlPath |
text | The URL path that was accessed |
tag |
string | Optional component/section identifier (nullable) |
templatePath |
text | Template file path (nullable) |
elementId |
int | ID of the element being viewed (nullable) |
elementType |
string | Class name of the element (nullable) |
siteId |
int | Site ID for multi-site tracking (nullable) |
hitCount |
int | Number of times this combination was hit |
dateCreated |
datetime | When the record was first created |
dateUpdated |
datetime | When the record was last updated |
Indexes
The table uses an index on urlPath, tag, templatePath, and siteId for efficient lookups.
Upsert Strategy
When you call mimi() with the same URL + tag + template + site combination, it increments the hitCount rather than creating a new record. This keeps the table lean and makes aggregation fast.
Performance
When Tracking is Enabled
- Efficient database queries with indexed lookups
- Upsert logic keeps the table lean (one row per unique combination)
- Errors are logged but won't break page rendering
- Site ID is automatically captured for multi-site installations
When Tracking is Disabled
- The
mimi()function returns immediately at the service layer - Zero database queries are executed
- Zero performance impact on template rendering
- Safe to leave
mimi()calls in your templates
Session Deduplication
When enabled, hits are only counted once per session. This is useful during:
- Development and testing
- Content editing and preview
- Avoiding inflated counts from page refreshes
Querying Hit Data
Direct SQL Queries
-- Most accessed pages SELECT urlPath, SUM(hitCount) as total_hits FROM wabisoft_mimi_hits GROUP BY urlPath ORDER BY total_hits DESC LIMIT 20; -- Component usage by tag SELECT tag, SUM(hitCount) as total_hits FROM wabisoft_mimi_hits WHERE tag IS NOT NULL GROUP BY tag ORDER BY total_hits DESC; -- Template usage SELECT templatePath, SUM(hitCount) as total_hits FROM wabisoft_mimi_hits WHERE templatePath IS NOT NULL GROUP BY templatePath ORDER BY total_hits DESC; -- Multi-site breakdown SELECT s.name as site, SUM(h.hitCount) as total_hits FROM wabisoft_mimi_hits h LEFT JOIN sites s ON h.siteId = s.id GROUP BY h.siteId, s.name ORDER BY total_hits DESC; -- Specific page with all components SELECT tag, templatePath, hitCount, dateUpdated FROM wabisoft_mimi_hits WHERE urlPath = '/products/my-product' ORDER BY hitCount DESC; -- Element-specific tracking SELECT elementType, elementId, SUM(hitCount) as total_hits FROM wabisoft_mimi_hits WHERE elementId IS NOT NULL GROUP BY elementType, elementId ORDER BY total_hits DESC LIMIT 20;
Use Cases
Content Strategy
- Track which pages are most frequently visited
- Identify popular vs. unused content
- Measure the impact of content changes over time
- Understand content consumption patterns across sites
Component Library Management
- Monitor component usage across your site
- Identify unused components for cleanup
- Track A/B test variations
- Understand which component patterns are most effective
Template Optimization
- Find which template files are actually rendering
- Identify unused template files for cleanup
- Debug template inheritance chains
- Track template usage across different entry types
Development & QA
- Verify components render during testing
- Debug template includes and embeds
- Track conditional content rendering
- Test multi-site template variations
Performance Analysis
- Identify hot paths through your templates
- Find frequently-rendered components for optimization
- Measure template rendering patterns
- Analyze site usage across different entry types
Upgrading from Earlier Versions
If you installed Mimi before template/element tracking was added:
- Pull the latest code
- Run migrations:
php craft migrate/all - The migration will add new fields without affecting existing data
- Start using the new parameters in your templates
Support
License
Proprietary