Releases: tallcms/tallcms
v3.10.5 - Site Settings Fixes
Bug Fixes
- Newsletter default removed — The Newsletter Signup URL field no longer defaults to
#newsletter. Empty when not configured. - Site logo can now be deleted — Added
deletable()to the logo upload field. Clearing a logo now saves correctly instead of being silently skipped.
Improvements
- Panel access no longer hardcodes role names — any user with a role can log in (Shield handles authorization)
- Updated multisite documentation with domain verification, settings page, and TLS eligibility
Tests
- 48 tests passing (domain verification, TLS endpoint, panel access)
v3.10.4 - Panel Access Fix & Multisite Docs
Improvements
- Panel access no longer hardcodes role names —
canAccessPanel()now allows any user with a role to log in, instead of requiring specific role names (super_admin, administrator, editor, author). Filament Shield handles authorization inside the panel.
Documentation
- Updated multisite management guide with domain verification workflow, Multisite Settings page, verification statuses, and TLS eligibility
- Updated multisite architecture docs with verification schema, state machine,
DomainVerificationService, re-verification batching, and backward compatibility notes - Fixed misleading
isGlobalOnly()documentation that implied a dynamic plugin registry
Tests
- Added 7 tests for
canAccessPanel()trust boundary covering active/inactive users, first-user bootstrap, and any-role access
v3.10.3 - Internal Route Support & TLS Verification
New Features
- Plugin internal routes — Plugins can now define
routes/internal.phpfor machine-to-machine endpoints with no web middleware (no session, CSRF, or cookies). Routes are scoped to/internal/*paths and validated by the same security scanner as other plugin route files. - TLS verification endpoint (
/internal/tls/verify) — The multisite plugin now provides an endpoint that reverse proxies like Caddy can query before issuing on-demand TLS certificates for tenant domains. Managed subdomains are auto-trusted; custom domains require explicit verification. domain_verifiedfield — New boolean on the sites table to control TLS certificate eligibility for custom domains. Managed subdomains of the configured base domain are auto-trusted without this flag.- Filament domain verified toggle — Live toggle in the site form, hidden for managed subdomains.
Configuration
New config keys in config/tallcms.php:
'multisite' => [
'base_domain' => env('TALLCMS_MULTISITE_BASE_DOMAIN'),
'tls_verify_token' => env('TALLCMS_TLS_VERIFY_TOKEN'),
],Caddy usage:
{
on_demand_tls {
ask http://localhost:8000/internal/tls/verify
}
}
Bug Fixes
- Fix SQLite compatibility in multisite menus location unique migration
Multisite Plugin
Multisite plugin version: 1.0.7 → 1.1.0 (requires core >=3.10.3)
v3.10.2 - Dependency Cleanup & README Update
Changes
- Remove redundant
paragonie/sodium_compatdependency — the nativeext-sodiumextension (bundled since PHP 7.2) is sufficient for PHP 8.2+ (thanks @brendt!) - Add
ext-sodiumas an explicit Composer requirement for clear error messaging on hosts where it's disabled - Update package README: add monorepo notice, align features/blocks/tables with current state
Contributors
- @brendt (Spatie) — tallcms/cms#1
v3.10.1 - Fix GEO migration discovery
Bug Fix
- Fix migration discovery — GEO Phase 1 migrations (author profile fields, review metadata) were not registered in
TallCmsServiceProvider::getMigrations(), sophp artisan migratenever ran them. The Attribution tab and author profile fields were invisible because the columns didn't exist.
v3.10.0 - GEO Phase 1: Attribution, Freshness & Structured Content
GEO Phase 1: Attribution & Freshness Trust Layer
The first step toward making TallCMS the CMS built for structured, attributable, maintainable content — not just SEO plugins bolted on.
New Features
- Author Profile in Admin — Job title, company, LinkedIn URL now editable alongside bio and social handles. Plugin-mode safe with
Schema::hasColumnguards - Content Review Metadata —
last_reviewed_at,reviewed_by, expert reviewer fields, and citation sources on posts and pages. New "Attribution" tab in editor - Mark as Reviewed — One-click header action on post/page edit to stamp review date and reviewer
- Enriched BlogPosting JSON-LD — Author
jobTitle,worksFor,sameAs(LinkedIn, X);reviewedByPerson;lastRevieweddate;citationarray of CreativeWork sources; fixedwordCountto use full content - Frontend Byline Enrichment — Author name linked to archive, credentials inline, review date, expert reviewer, and numbered sources list below article
- Content Health Dashboard Widget — Stats for published posts, stale content (not reviewed in 6+ months), missing meta descriptions, missing featured images
- HowToBlock — New block with step-by-step repeater, schema.org
HowTo/HowToStepstructured data, estimated time/cost, and search indexing - llms.txt — Auto-generated content index for AI systems with admin controls: preamble, include/exclude pages/posts, post limit, category-grouped sections. HTTPS-aware URLs
- SEO Settings — New llms.txt section with enable toggle, preamble field, content inclusion toggles, and post limit selector
Plugin Mode Safety
- Author profile fields conditionally rendered based on column existence
- Attribution tab hidden when review metadata migration hasn't run
- Content Health Widget gated behind
hasPostsflag - llms.txt route gated behind
tallcms.plugin_mode.llms_txt_route_enabledconfig - Review metadata migration uses configurable user table, not hardcoded
users
Tests
- 16 new tests (SeoService JSON-LD enrichment, HowTo block schema, llms.txt route/toggle/content)
- All 299 tests passing
Bug Fixes
- Post detail breadcrumbs now respect parent page's
show_breadcrumbssetting instead of being hardcoded to always show
v3.9.2
Bug Fix
- Fix license activation crash on installs without multisite migration —
PluginLicenseService::activate()now guardssite_idinsertion withhasSiteIdColumn()check, preventing crashes on installations that haven't run the multisite migration. This completes the v3.9.1 fix which only guarded read paths but missed the write path inactivate().
v3.9.1 - Fix Plugin Manager crash on non-multisite installs
Bug Fix
Fixed a critical crash on the Plugin Manager page for installations without the multisite plugin or that haven't run migrations yet. The per-site licensing code in v3.9.0 referenced the site_id column on tallcms_plugin_licenses without checking if it exists.
All site_id queries are now guarded by Schema::hasColumn() (cached per-process). Non-multisite installs work exactly as before.
If you deployed v3.9.0 and see a 500 error on the Plugins page, update to v3.9.1 immediately.
v3.9.0 - Per-Site Plugin Licensing & Ownership
New Features
- Per-site plugin licensing — Plugins can opt in to per-site licensing via
"license_scope": "site"in plugin.json. Each site in a multisite installation can have its own license activations. Default is"installation"(backward compatible). - Site ownership docs — Enforcement layers, quota guidance, and product overview added to multisite technical reference.
- Dashboard ownership fallback — Non-super-admins fall back to their first owned site on the dashboard.
- Master key deactivation — Master key licenses can now be deactivated locally without a proxy call.
Per-Site Licensing Details
- New
site_idcolumn ontallcms_plugin_licenses(nullable, composite unique withplugin_slug) PluginLicense::findForCurrentContext()auto-resolves site from plugin's license_scopePluginLicenseServicecomprehensive overhaul: site-aware domain resolution, cache keys, all lookup/activate/deactivate/status/update methodsPluginmodel parseslicense_scopefrom plugin.json- Plugin Manager shows site context subheading
checkForUpdatesAutomatically()skips site-scoped plugins (v1 rule)- Legacy global licenses (site_id=NULL) work everywhere until explicitly reactivated per-site
Migration
Run php artisan migrate after updating. The migration adds a nullable site_id column and changes the unique constraint. Existing licenses are preserved as installation-global.
Plugin Compatibility
All changes are backward compatible. Plugins without license_scope in plugin.json default to "installation" (current behavior).
v3.8.0 - Multisite Core Support & Navigation Restructure
New Features
- Multisite core support — Plugin-absence-safe foundation for the TallCMS Multisite plugin. Settings scope policy, site-aware theme/preset management, per-site slug uniqueness, dashboard widget, and Site column on Pages/Menus tables.
- Navigation restructure — Admin sidebar reorganized into 5 logical groups: Platform (multisite only), Content, Appearance, Configuration, System. Config-driven group names for easy customization.
- Settings scope policy —
SiteSettingnow supports global-only keys (i18n, audit metadata) and site-override keys with three-state model (inherit / override / explicit blank). - Embed Code — "Code Injection" renamed to "Embed Code" with multisite override indicators.
- Site-aware dashboard — Widget shows content counts scoped to the selected site with context heading.
Improvements
SiteSetting::getGlobal(),setGlobal(),resetToGlobal()methods addedThemeManager::resetViewPaths()now public (clears namespace hints properly)- Theme Manager page reads site context from session directly (no resolver dependency)
- Site Settings page shows override/inherited indicators per field with "Reset to global" actions
UniqueTranslatableSlugvalidation is site-scoped in admin context- Pages and Menus tables conditionally show Site column when multisite is active
- All navigation groups config-driven via
tallcms.navigation.groups
Documentation
- New: Multisite product guide (
docs/site-multisite.md) - New: Multisite architecture reference (
docs/dev-multisite.md) - Updated: Installation guide with admin panel URL clarity
Plugin Compatibility
All core changes are plugin-absence-safe. Without the multisite plugin installed, TallCMS behaves exactly as before. Guards include Schema::hasColumn(), app()->bound(), session() checks, and QueryException catches.