Skip to content
CAI
Software that uses CAICheck a score

area17/twill

46.5

Weak · 19 September 2026

51.5k

lines of production code

PHP

with JavaScript

1

measurement over time

CAI band scale
CAI lens gauges

What this system is

This system is a Laravel-based content management framework, now branded as Twill, that provides a modular architecture for building admin interfaces and managing content. It enables developers to define content models with features like versioning, translations, and nested hierarchies, while offering a modern, Vue-driven frontend for block-based page building and media management. The platform supports granular permission controls, multi-subdomain routing, and cloud storage integration, serving as a comprehensive toolkit for creating custom CMS solutions.

How it got here

2016–2017 — Twill rebranding and Vue.js migration

74 changes.

The project underwent a comprehensive rebranding from CmsToolkit to Twill, restructuring the codebase architecture and configuration systems. This period focused on migrating the admin interface from legacy server-rendered Blade templates to a modern, component-driven Vue.js frontend with Vuex state management. Additionally, core backend services were refactored to support modular capsules, granular permissions, and multi-cloud storage backends.

2018–2022 — Twill 3.0 architecture and testing

85 changes.

This period focused on the comprehensive refactoring of the codebase to support the Twill 3.0 architecture, introducing a component-based block system, fluent form builders, and object-oriented listing filters. It also established a robust testing infrastructure with extensive PHPUnit integration and unit tests, while modernizing the frontend with Vue components and Tailwind CSS.

2023–2026 — Integration testing and form service refactoring

9 changes.

This period focused on expanding test coverage across the Capsule, User, Block, and Tag subsystems while introducing integration tests for exception handling. Concurrently, the codebase underwent structural improvements through the addition of block component stubs and the implementation of standardized traits for block rendering and subfield registration within the form services layer.

Features

Add AWS S3 and Glide cloud storage integration

The application now supports AWS S3 as a cloud storage source. A new \Aws\ service class in \src/Services/Cloud\ handles S3 client configuration and filesystem creation, reading credentials and settings from environment variables or config. The \Glide\ service has been updated to route image processing requests to this new AWS backend when the source is set to 's3' or 'aws'. An \Azure\ placeholder class is also added, though it currently throws an exception indicating it is not yet implemented.

src/Services/Cloud · high confidence

Add Azure Storage support and refactor S3 uploader configuration

The Uploader service now supports Azure Blob Storage in addition to S3. A new SignAzureUpload class handles Azure-specific SAS URL generation, while the existing SignS3Upload class has been refactored to accept a Config repository and use dynamic disk configuration (e.g., \filesystems.disks.{disk}.bucket\) instead of hardcoded S3-specific config keys. This allows the uploader to work with different storage disks defined in the application's filesystem configuration.

src/Services/Uploader · high confidence

Add Contact Page singleton module example

The tests-singleton example now includes a complete Contact Page singleton module, featuring a controller extending SingletonModuleController, a repository with behaviors for blocks, translations, slugs, media, files, and revisions, and a database migration creating the necessary tables. The module is configured in twill-navigation as a singleton, routed via the TwillRoutes facade, and includes a seeder to populate initial data. The form view integrates a custom Vue component (HelloWorld) to demonstrate custom frontend integration within the admin interface.

examples/tests-singleton · high confidence

Add Doctum-based API documentation generation setup

The docs-api directory now includes a complete setup for generating static API documentation using Doctum. This includes a configuration file that scans PHP files in the src directory, supports versioning for main, 2.x, and 3.x branches, and outputs built documentation to version-specific build directories. A README provides instructions for installing dependencies, building the documentation, and serving it locally, while a .gitignore file excludes generated cache, build, and vendor directories.

docs-api · high confidence

Add admin controllers and request handlers for Authors and Categories modules

This change introduces the HTTP layer for the new Authors and Categories modules within the test suite. It adds AuthorController and CategoryController classes extending ModuleController to define index options, table columns (including sorting and image variants for authors, and nested tree structures for categories), and routing prefixes. It also adds corresponding AuthorRequest and CategoryRequest classes to handle form validation rules for creating and updating these resources.

examples/tests-modules/app/Http · high confidence

Add block component stubs for form and view generation

New stub files have been added to the \src/Commands/stubs/blockComponent\ directory to support the generation of block components. The \component.php.stub\ provides a PHP class template that extends \TwillBlockComponent\, including a \render\ method and a \getForm\ method pre-configured with an \Input\ field for 'title' and a \Wysiwyg\ field for 'text'. The \view.blade.php.stub\ provides the corresponding Blade template, rendering the title in an \\<h2\>\ tag and the text content using the \$input\ helper.

src/Commands/stubs/blockComponent · high confidence

Add browser relationship example application

The examples/tests-browsers directory now contains a complete reference application demonstrating Twill's browser (relationship) features. It includes database migrations for Writers, Letters, Bios, and Books with revision support, along with the corresponding controllers, repositories, and form requests. The example showcases various browser configurations, such as single-select relationships (Bios linked to Writers) and multi-select relationships (Letters and Books linked to multiple Writers), using the new TwillRoutes facade for route registration.

examples/tests-browsers · high confidence

Add configuration files for translation, navigation, and Twill modules

Added three new configuration files to the examples/tests-modules area: translatable.php defines localization settings (locales, fallbacks, and property fallback behavior); twill-navigation.php configures the admin panel's primary navigation structure for Personnel and Categories; and twill.php sets up the dashboard modules for Authors and Categories, including their labels, route prefixes, and feature flags like search and drafts, alongside block editor and icon directory mappings.

examples/tests-modules/config · high confidence

Add deep-nested module example (Clients \> Projects \> Applications)

The \examples/tests-deep-nested\ location now includes a complete, deeply nested module structure demonstrating how to manage hierarchical data in Twill. This example adds three levels of modules—Clients, Projects, and Applications—each with their own controllers, repositories, form requests, database migrations, and site preview views. The controllers configure parent-child relationships using \getParentModuleForeignKey\ and \setModuleName\, while the navigation config registers the nested module paths (\clients\, \clients.projects\, \clients.projects.applications\) in the admin sidebar.

examples/tests-deep-nested · high confidence

Add example implementation for a Postings module with permissions and settings

This change introduces a complete, minimal example of a Twill-based application within the examples/tests-permissions directory. It adds a new 'Postings' content module, including the necessary controller, request validation, repository, database migration, and form view. The example is configured to use the new TwillRoutes facade for route registration and includes a settings page for SEO configuration. Additionally, the twill.php config file explicitly enables the 'postings' module and defines it in the permissions list, demonstrating how to restrict access to this new feature.

examples/tests-permissions · high confidence

Add nested 'nodes' module example with modern Twill conventions

The tests-nestedmodules example now includes a complete 'nodes' module demonstrating nested content management. This addition introduces a controller that enforces parent-only browsing in browsers, a repository utilizing the HandleNesting behavior, and a database migration defining the nodes table with nested set fields. The module is registered via the TwillRoutes facade instead of route macros, and the form view uses the modern x-twill::input component, reflecting an update to current framework conventions.

examples/tests-nestedmodules · high confidence

Add specific exception classes for filter configuration errors

Two new exception classes, FilterOptionsMissingException and MissingModelForFilterException, have been added to the listings filter service. These allow the application to throw distinct, typed errors when filter options are missing or when a model is not provided for a filter, improving error handling clarity for developers using the filtering system.

src/Services/Listings/Filters/Exceptions · high confidence

Added AppServiceProvider for the tests-modules example

A new AppServiceProvider has been added to the examples/tests-modules application. This file provides the standard Laravel service provider structure with empty register and boot methods, importing the TwillConfig facade, serving as the foundational service provider for this specific example module.

examples/tests-modules/app/Providers · high confidence

Added CapsuleSeeder class

A new CapsuleSeeder class has been introduced in the Capsules service, extending the Laravel Illuminate Seeder. This provides a dedicated entry point for seeding database data related to capsules.

src/Services/Capsules · high confidence

Added Twill form views for Authors and Categories

New Blade templates have been added to define the content entry forms for Authors and Categories within the Twill admin interface. The Author form now includes fields for an avatar, description, birthday, bio, and a block editor, while the Category form provides a single translated description field. These views extend the standard Twill form layout to structure how these specific content types are edited by administrators.

examples/tests-modules/resources · high confidence

Added background jobs for revision cleanup and nested item reordering

Two new queueable jobs have been introduced to handle asynchronous tasks. The CleanupRevisions job manages the deletion of old revisions for models implementing HasRevisions, respecting either a model-specific limit or a global configuration setting. The ReorderNestedModuleItems job handles the reordering of nested module items by saving the tree structure based on a provided list of IDs, ensuring these operations are performed within database transactions to maintain data integrity.

src/Jobs · high confidence

Added block builder template and icons listing page

The views/blocks area now includes a new builder template that renders block content with ESLint disabled for generated code, and a dedicated icons listing page that displays available icons in a responsive grid layout with their names and URLs.

views/blocks · high confidence

The basic page builder example now includes database migration files to set up the necessary schema. A new migration creates the 'pages' table along with associated 'page\_translations', 'page\_slugs', and 'page\_revisions' tables to support content management features like soft deletes, timestamps, and versioning. Another migration introduces the 'menu\_links' table, which utilizes a nested set structure to manage hierarchical menu items, along with fields for title, description, and position.

examples/basic-page-builder/database · high confidence

Added demo and test settings views for the Twill admin interface

The examples/tests-settings area now includes Blade templates for configuring demo and test settings within the Twill admin panel. Specifically, new views have been added for a 'Demo' setting (containing a single input field) and a 'Test' setting (containing translated and non-translated input fields alongside a block editor). Additionally, a site-level text block view and a corresponding Twill block configuration view for text content have been introduced to support rendering and editing these content types.

examples/tests-settings · high confidence

Added new block and repeater stubs for Twill content management

New stub files have been added to the \src/Commands/stubs/blocks\ and \src/Commands/stubs/repeaters\ directories to support the creation of specific content blocks. These include stubs for Carousel, Footnote, Gallery, Image, Quote, and Body text blocks, along with a corresponding Carousel item repeater. These stubs define the form fields and UI components (such as WYSIWYG editors, media pickers, and variation selectors) that developers can use as templates when generating new block types in the application.

src/Commands/stubs/blocks · high confidence

Added placeholder for customs components directory

A .keep file was added to the frontend/js/components/customs directory to ensure the folder is tracked by version control, establishing a location for future custom component implementations.

frontend/js/components/customs · high confidence

Basic page builder example adds route definitions

The basic-page-builder example now includes explicit route definitions in \routes/twill.php\ and \routes/web.php\. The Twill routes are registered for the 'pages' and 'menuLinks' modules using the \TwillRoutes\ facade, and web routes are added to handle frontend display for the home page and individual pages via the \PageDisplayController\.

examples/basic-page-builder/routes · high confidence

Expanded example models and new core setting/block models

The Twill package now includes a comprehensive set of new example models across multiple test scenarios (basic-page-builder, portfolio, tests-browsers, tests-capsules, tests-deep-nested, tests-modules, tests-nestedmodules, tests-permissions, tests-singleton, and tests-subdomain-routing), demonstrating advanced features such as nested blocks, capsules, subdomain routing, and custom presenters. Additionally, core models for AppSetting, Block, Feature, Group, and Permission have been introduced or significantly expanded to support new capabilities like settings block registration, granular permission scoping (global, module, item), and starred items in buckets.

area17/twill · high confidence

Expanded language support with new localization files

The application now includes new language files for Arabic (ar), Bosnian (bs), Czech (cs), and German (de), providing translated strings for authentication, dashboard, editor, and media library interfaces. Additionally, placeholder files have been added for numerous other languages (such as aa, ab, af, am, an, as, ay, az, ba, be, bg, bh, bi, bn, bo, br, ca, co, cy, da, dz, el, eo) to support future translation efforts, ensuring the localization infrastructure is ready for these regions.

lang · high confidence

Extended VSelect component with new props and logic

The VSelect component now includes an ExtendedVSelect variant that adds support for disabling the select field, enforcing required values, and toggling option selection via double-click. It also introduces logic to handle deletion of values when the search input is empty and ensures proper handling of selected options in multi-select scenarios.

frontend/js/components/VSelect · high confidence

Introduce Buckets component for managing content collections

Adds the core frontend components for the Buckets feature, allowing users to organize content into named collections. The new Bucket.vue component provides a dual-pane interface with a source list for selecting items and target panes for managing bucket contents, supporting drag-and-drop reordering, pagination, and filtering. Users can add items to buckets, move them between buckets (with support for restricted single-bucket or multi-bucket modes), and override bucket limits when configured. The implementation includes BucketItem.vue for individual item controls (including starring/featuring and dropdown selection) and BucketSourceItem.vue for source list display with language information.

frontend/js/components/buckets · high confidence

Introduce Vue-based table components with bulk editing and pagination

The table listing interface has been refactored into a suite of new Vue components (Datatable, TableRow, TableHead, Paginate, BulkEdit, TableFilters, Table) to replace the previous implementation. This change adds a BulkEdit toolbar that allows users to perform bulk actions such as publish, unpublish, feature, unfeature, delete, restore, and destroy on selected items, with actions dynamically enabled based on item status. The Datatable component now includes client-side pagination with configurable rows-per-page, column visibility toggling, and sorting. The UI supports sticky table headers, horizontal scrolling synchronization, and nested row rendering with drag-and-drop reordering capabilities.

frontend/js/components/table · high confidence

Introduce abstract TwillBlockComponent base class for block rendering

A new abstract \TwillBlockComponent\ class has been added to serve as the base for all block components. It provides a standardized factory method (\forRendering\) to instantiate blocks with context, and exposes helper methods for accessing block data such as \image\, \input\, \translatedInput\, and \repeater\ (including fallback logic for dynamic repeaters). The class also defines default behaviors for block identification (\getBlockIdentifier\), titles (\getBlockTitle\, \getBlockTitleField\), icons, validation rules, and form rendering, ensuring consistent structure across block implementations.

src/View/Components/Blocks · high confidence

Introduce nested hierarchical table listings

Adds new Vue components (NestedDatatable, NestedList, NestedItem) that enable users to view and interact with data in a hierarchical, nested structure. This feature supports multi-level indentation (up to a configurable max depth), visual hierarchy indicators (borders and connecting lines), and drag-and-drop reordering of rows within the nested tree.

frontend/js/components/table/nested · high confidence

Introduce traits and contracts for block rendering and subfield registration

This change introduces new contracts (\CanHaveSubfields\, \CanRenderForBlocks\) and corresponding traits (\HasSubFields\, \RenderForBlocks\) within the Forms service layer. These components provide a standardized mechanism for form fields to declare whether they should be rendered in block contexts and to recursively register dynamic repeaters across nested field structures, supporting the refactoring of form service code to reduce duplication.

src/Services/Forms/Traits · high confidence

Introduction of modular repository behavior traits

The repository layer has been refactored to use a set of distinct behavior traits (e.g., \HandleBlocks\, \HandleBrowsers\, \HandleRepeaters\, \HandleRevisions\, \HandlePermissions\) instead of monolithic implementations. This change introduces specific capabilities for managing nested block structures, JSON-based repeaters, browser field synchronization, and granular role/group/item-level permissions, while also adding support for OAuth user linking and nested module slugs.

src/Repositories/Behaviors · high confidence

Introduction of nested breadcrumbs service with route prefix support

A new breadcrumbs service has been added to the application, introducing \BreadcrumbItem\ and \Breadcrumbs\ classes to manage navigation items with specific display contexts (form vs. listing). The \NestedBreadcrumbs\ class extends this foundation to support hierarchical navigation for nested modules, automatically generating a breadcrumb trail that includes the parent module, the active parent record (resolved via a repository), and the current module's index and edit views. This implementation includes support for custom route prefixes, allowing nested breadcrumbs to correctly link to parent resources even when they reside under non-standard URL structures.

src/Services/Breadcrumbs · high confidence

Introduction of new foundational UI components

The frontend component library has been expanded with a suite of new, reusable Vue components to standardize the user interface. This includes an Accordion for collapsible content sections, an Avatar for user representation with fallback initials, and a comprehensive Browser system (Browser, BrowserField, BrowserItem) for selecting and managing media or content items with drag-and-drop support. Additionally, core interaction elements like Button, ButtonBar, Checkbox, CheckboxAccordion, and CheckboxGroup have been introduced to provide consistent styling and behavior across forms and listings.

frontend/js/components · high confidence

Introduction of new model contract interfaces

New PHP interfaces have been added to define specific capabilities for models: TwillLinkableModel for generating full URLs, TwillModelContract for core model behaviors like scoping published or accessible records, and TwillSchedulableModel for managing publish dates and visibility. These contracts standardize how models implement linking, querying, and scheduling features within the application.

src/Models/Contracts · high confidence

Media library image services migrated to Twill namespace with expanded capabilities

The Media Library image service implementations (Glide, Imgix, Local, and the new TwicPics service) have been moved from the \A17\\CmsToolkit\ namespace to \A17\\Twill\. This change introduces a new TwicPics image service with a parameter compatibility layer (\AbstractParamsProcessor\) to support standard image manipulation parameters like width, height, and format. The Glide service now supports signed URLs, configurable source/cache disks, and presets. The Imgix service has been refactored to use dependency injection for configuration, adds support for SVG parameter injection via a new config option, and improves dimension retrieval with fallback logic. The Local service now uses the configured storage disk for URL generation instead of a hardcoded path prefix.

src/Services/MediaLibrary · high confidence

New API store modules for content management operations

This change introduces a new set of API store modules (blocks, buckets, datatable, form, media-library, revision) that centralize HTTP requests for content management features. These modules handle operations such as listing, creating, updating, deleting, and bulk actions for content items, as well as managing media library assets, revisions, and block previews. All requests are routed through Axios and include standardized error handling via a global error utility.

frontend/js/store/api · high confidence

New Blade form field components

The form field rendering logic has been migrated to a new set of dedicated Blade components in the \src/View/Components/Fields\ directory. This introduces a \TwillFormComponent\ base class and specific components for fields such as Input, Select, Wysiwyg, Repeater, and Browser. Users can now utilize these components to render form fields, which support options like \direction\ for text inputs and \clearable\ for select fields, providing a more structured and type-safe approach to form building.

src/View/Components/Fields · high confidence

New CLI commands for block generation, capsule management, and asset building

This update introduces a suite of new Artisan commands to streamline development workflows. Developers can now create new block files with \twill:make:block\ and generate Vue components for blocks via \twill:make:componentBlock\. Module scaffolding is expanded with \twill:make:capsule\ and \twill:make:singleton\ to generate new capsules and singletons, while \twill:capsule:install\ allows installing external capsule packages. Asset management is enhanced with \twill:build\ (supporting \--hot\ and \--watch\ modes for development), \twill:dev\ for hot reloading, and \twill:blocks\ to generate single-file Vue components from Blade views. Additional utilities include \twill:refresh-crops\ for regenerating image crops, \twill:list:blocks\ and \twill:list:icons\ for inspecting available resources, and \twill:make:package\ for scaffolding new Twill extensions.

src/Commands · high confidence

New Media Library UI components

The media library interface has been rebuilt using new Vue components (MediaLibrary, MediaGrid, MediaSidebar, Uploader) to provide a unified modal experience for browsing, uploading, and managing media. Users can now filter by tags and unused status, select multiple items with shift-click, and edit metadata (tags, alt text, caption) in a sidebar that supports bulk editing. The uploader integrates with Fine Uploader to support S3, Azure, and traditional backends, featuring drag-and-drop, progress tracking, and error handling.

frontend/js/components/media-library · high confidence

A new \NavigationLink\ component has been introduced in the navigation view components to provide a structured, fluent API for defining navigation entries. This component supports linking to specific routes, module actions, or external URLs, and allows for conditional rendering via a closure. It also handles hierarchical navigation by automatically including the parent item as the first child when sub-items are present, and respects the \twill.admin\_route\_name\_prefix\ configuration for generating module-specific route names.

src/View/Components/Navigation · high confidence

New SCSS mixin library for UI components and layout

The frontend styling system now includes a comprehensive set of new SCSS mixins in the \frontend/scss/setup/mixins\ directory to standardize component styling and layout. These additions provide reusable styles for accordions (trigger and icon handling), buttons (reset styles), form fields (placeholders, resets, and state management), and typography (font sizes, smoothing, and feature settings). Additionally, new grid and breakpoint mixins enable responsive column spanning and media query generation, while utility mixins support drag-and-drop grid visuals, link coloring, and background/keyline fills.

frontend/scss/setup/mixins · high confidence

New SCSS styles for Block and Box components

Added new SCSS files for the 'Block' and 'Box' molecule components to define their visual structure and spacing. The Block styles manage margins for headers, paragraphs, and separators within content editor blocks, while the Box styles define the layout for container elements with headers, footers, and filter links.

frontend/scss/molecules · high confidence

New SettingsGroup class for structured settings management

A new \SettingsGroup\ class has been introduced in the Settings service to provide a structured, object-oriented way to define and manage application settings. This class handles the creation and persistence of \AppSetting\ models, automatically generates database blocks for form sections, and manages route generation using the configured admin route name prefix. It also supports conditional availability via closures and optional menu registration, serving as the foundational component for the refactored settings architecture.

src/Services/Settings · high confidence

New asset resolution service with dev-mode and manifest fallback support

A new \Twill\ service class has been introduced in \src/Services/Assets\ to manage asset path resolution. It prioritizes development mode assets by fetching a manifest from a configured dev server URL (defaulting to \http://localhost:8080\), falling back to the vendor-published \twill-manifest.json\ if the public directory manifest is missing, and finally defaulting to a static path based on the \twill.public\_directory\ configuration. The service caches the manifest reading logic and handles SSL verification settings for JSON reads.

src/Services/Assets · high confidence

New basic-page-builder example for Twill 3.0

The \examples/basic-page-builder\ directory now provides a complete, standalone example application demonstrating a page builder setup for Twill 3.0. This example includes a page module with block editor support, a navigation module with nested menu links, and a homepage setting configuration. It features a blade-based frontend styled with Tailwind CSS and compiled via Vite, along with the necessary controllers, repositories, and service providers to wire these components together. A README is included to guide users through the Laravel and Twill installation process.

examples/basic-page-builder · high confidence

New command traits for Twill CLI operations

Added four new command traits to the \src/Commands/Traits\ directory to support internal CLI logic: \ExecutesInTwillDir\ for running shell commands within the Twill directory, \HandlesPotentialBreakingChangesWarnings\ to detect and prompt users to add missing database migrations introduced in version 3.5.0, \HandlesPresets\ to manage the installation and updating of example presets, and \HandlesStubs\ to provide utilities for replacing variables and conditionals in code stubs.

src/Commands/Traits · high confidence

New dashboard widgets for activity, statistics, and content feeds

The dashboard now includes dedicated Vue components for displaying activity logs, statistical trends, and content lists. The Activity Feed allows users to filter and paginate recent actions, while the Stats Feed visualizes metrics with trendlines and period selectors (today, yesterday, week, month). Additionally, a Generic Feed displays content items with optional thumbnails and view counts, and a Shortcut Creator provides quick links to create new entities and view item counts.

frontend/js/components/dashboard · high confidence

New field configuration traits for form inputs

A suite of new traits has been added to the form field builder to provide granular control over input behavior and appearance. Users can now configure layout and display options such as column counts, grid unpacking, inline display, borders, and button placement. Input constraints including minimum/maximum item counts, character length limits, and read-only states are now available. Additional capabilities include setting placeholders, defining field direction (LTR/RTL), adding field notes, and attaching JavaScript change handlers. Options management has also been enhanced with support for closures and individual option addition.

src/Services/Forms/Fields/Traits · high confidence

New file selection field with drag-and-drop and extension-based icons

A new FileField component has been introduced for selecting and managing files within forms. It supports reordering items via drag-and-drop (enabled when multiple items are present) and displays specific icons for files based on their extension, utilizing a new Extensions mapping file. The field allows configuration of a maximum item count, optional placement of the 'Add' button at the top, and integrates with the existing media library store for state management.

frontend/js/components/files · high confidence

New file-type, block, and WYSIWYG editor icon sets

The icon system now includes dedicated SVG sprite files for file-type indicators (e.g., ae, ai, doc, pdf, xls), block editor components (e.g., b-accordion, b-button, b-carousel, b-table), and WYSIWYG editor actions (e.g., wysiwyg\_bold, wysiwyg\_link, wysiwyg\_table). These are aggregated into a single sprite via \svg-sprite.blade.php\, ensuring consistent styling and availability across the interface.

views/partials/icons · high confidence

New form builder service classes for structured layouts and components

This change introduces a new set of service classes in src/Services/Forms to support a more structured form definition API. Key additions include BladePartial for rendering custom Blade views with shared form context, Columns for defining multi-column field layouts, and Fieldset/Fieldsets for grouping fields into collapsible sections. The Form class now supports side forms and fieldset-based rendering, while InlineRepeater gains new configuration options like max items, button-as-link styling, and connected field support. Additionally, Option and Options classes provide a typed way to define select options with selectable states.

src/Services/Forms · high confidence

New form utility partials for blocks, connected fields, and layout

Added a suite of new Blade partials in the form utils directory to enhance form builder capabilities. These include \\_block\_editor\_store\ and \\_blocks\_templates\ for managing block editor state and inline templates, \\_connected\_fields\ for conditional field visibility based on other field values, \\_columns\ for multi-column layouts, \\_fieldset\ and \\_collapsed\_fields\ for grouping and toggling field sections, \\_inline\_checkboxes\ for compact checkbox groups, and \\_selector\_input\_store\/\\_translatable\_input\_store\ for improved handling of selector and translatable field data in the JavaScript store.

views/partials/form/utils · high confidence

New frontend mixins for form, block, and table management

This change introduces a comprehensive set of new Vue mixins in the frontend to standardize and simplify component logic. The \formStore\ mixin centralizes form field state management with the Vuex store, supporting both modal and standard form contexts. New \block\, \blockEditor\, and \blockEditorItem\ mixins provide shared methods for managing block lifecycle events (add, edit, save, cancel, delete, clone) and UI state within the visual editor. Table-related mixins (\datatable\, \datatableRow\, \tableCell\) handle bulk actions, row editing, and column rendering logic. Additional mixins like \buckets\, \checkboxes\, \confirmationMixin\, \cropper\, \draggable\, \locale\, \maxlength\, \mediaField\, \retrySubmit\, and \toggleVisibility\ offer reusable functionality for specific UI patterns, while \addAttributes\ and \formatPermalink\ handle dynamic option merging and URL slug generation.

frontend/js/mixins · high confidence

New frontend utility library for CMS editing features

The frontend utility module has been expanded with a comprehensive set of new helper functions and components to support the CMS editor. This includes a robust form data processor (\getFormData\) that correctly structures block, repeater, and media selections for backend submission, and a cropper utility that fixes rounding errors in square image crops. Date handling is improved with locale-aware formatting filters and 24-hour time detection, while a new global error handler provides specific user notifications for session expiration (401) and permission denied (403) states. Additional utilities include a sticky navigation controller, a tooltip system, SVG injection helpers, and local storage management that gracefully falls back to cookies when necessary.

frontend/js/utils · high confidence

New global UI component styles for navigation, forms, and layout

This update introduces a comprehensive set of new global SCSS files that define the visual structure and behavior of core interface elements. Users will see styled components for the main header and mobile navigation overlays, including responsive layouts and scrollable navigation lists. The update also adds styles for breadcrumb trails, secondary navigation tabs, and a new three-dot loader animation. Additionally, it establishes base styling for form inputs (including search and number fields), draggable list items with transition effects, and Vue.js-based transitions for modals, dropdowns, and search overlays.

frontend/scss/globals · high confidence

New navigation partial view components

Added a set of new Laravel view components in the navigation partials directory to render specific UI sections: Breadcrumbs, Overlay, Primary, Secondary, Tertiary, Title, and User. These components delegate rendering to their respective Blade templates (e.g., \_breadcrumb, \_overlay\_navigation, \_primary\_navigation) and, where applicable, fetch data from the TwillNavigation facade to populate the UI with link groups, active titles, and hierarchical link structures.

src/View/Components/Partials · high confidence

New package generator command with updated stubs

A new command has been added to generate Twill CMS packages, supported by new stub files for instructions, composer.json, and the service provider. The generated composer.json now targets Twill version ^3.4, and the instructions guide users on how to integrate the package via path repositories and create their first capsule using the twill:make:capsule command.

src/Commands/stubs/package · high confidence

New repository implementations for Author, Category, and RevisionLimited modules

Added new repository classes for the Author, Category, and RevisionLimited modules within the tests-modules example. The AuthorRepository explicitly orders the HandleSlugs trait before HandleTranslations to prevent errors, addressing issue \#94. The CategoryRepository includes a custom setNewOrder method to handle tree structure updates via database transactions. The RevisionLimitedRepository provides a basic implementation using the HandleRevisions behavior.

examples/tests-modules/app/Repositories · high confidence

New role editing interface with granular permission controls

A new form view for editing roles has been introduced, providing users with a structured interface to manage permissions. This includes general permissions such as managing users, user roles, user groups, and media library access (view and upload). Additionally, users can configure content-specific permissions for individual modules, allowing them to assign view, edit, or manage access levels, with the 'manage' option available for specific role group items. The form also includes a setting to include the role in the 'Everyone' group.

views/roles · high confidence

New service providers and facades for Capsules, Blocks, and Settings

This release introduces a set of new service providers and facades to better structure the Twill core. The \CapsulesServiceProvider\ now handles capsule configuration and loading, while \TwillCapsules\ provides the logic for registering and discovering project and package capsules. New facades (\TwillBlocks\, \TwillAppSettings\, \TwillNavigation\, \TwillConfig\, \TwillPermissions\, \TwillRoutes\, \TwillUtil\) are added to expose their respective services. The \PermissionAuthServiceProvider\ centralizes gate definitions for user and module permissions, and \TwillBlocks\ manages block and repeater discovery. Additionally, the abandoned \cartalyst/tags\ package is internalized via \TaggableInterface\, \TaggableTrait\, and \TagsServiceProvider\ to support Laravel 13 compatibility.

src · high confidence

New specialized column types for listings

The listings table now supports a set of new, specialized column types that simplify displaying common data patterns. You can use the Boolean column to show checkmarks or crosses, the Image column to render thumbnails with configurable roles, crops, and rounded corners, and the Link column to display custom URLs with optional new-window behavior. The Relation and Browser columns allow displaying related model data (such as associated tags or media) directly in the table, while the NestedData column automatically counts and displays the number of related items. Additional columns include Presenter for using model presenter methods, and dedicated status columns for Publish, Scheduled, and Featured states, which are rendered on the frontend.

src/Services/Listings/Columns · high confidence

Optional migrations for permissions, roles, 2FA, and OAuth

This change introduces a new set of optional database migrations that allow users to enable granular permissions management, role-based access control, two-factor authentication, and OAuth integration. The \permissions-management\ migration creates tables for permissions, roles, and groups, seeds default roles (Owner, Administrator, Team, Guest), and migrates legacy string-based user roles to the new relational structure. The \users-2fa\ migration adds two-factor authentication columns to the users table when the feature is enabled. The \users-oauth\ migration creates a table to store OAuth provider tokens and user associations when OAuth is enabled. These migrations are optional and can be enabled via configuration flags.

migrations/optional · high confidence

Redesigned admin interface with Vue-based layouts and components

The admin interface has been completely overhauled to use a modern Vue.js architecture. The previous static Blade-based layouts (including the old main, head, and flash partials) have been replaced with new, specialized layout files for the dashboard, forms, listings, buckets, settings, and custom pages. These new layouts integrate Vue components for core interactions such as the title editor, publisher, media library, search, and data tables, and they initialize a centralized Vuex store to manage application state. This change shifts the CMS from a server-rendered template model to a dynamic, component-driven single-page application experience for the admin area.

views/layouts · high confidence

Redesigned authentication UI with two-factor and OAuth support

The authentication views have been completely rewritten to use a new shared layout (\views/auth/layout.blade.php\) that displays the application name, environment label, and branding. The login page now supports two-factor authentication via a dedicated \2fa.blade.php\ view and integrates optional OAuth providers (such as Google) using inline SVG icons and configuration-driven links. The interface also includes improved accessibility with proper tab indices, localized strings via \twillTrans\, and a new OAuth linking flow (\oauth-link.blade.php\) for associating social accounts.

views/auth · high confidence

Visual block editor with drag-and-drop and live preview

The editor now supports a visual interface where users can drag blocks from the sidebar into a live preview area, reorder them via drag handles or dropdown menus, and edit block content in a side panel. The preview renders blocks in sandboxed iframes that automatically resize to fit their content, and the sidebar provides controls to clone, delete, and move blocks while showing a loading state during updates.

frontend/js/components/editor · high confidence

Removals

Removal of SPF request handling trait

The \HandleSpfRequests\ trait, previously located in \src/Http/Controllers/Front/Behaviors\, has been removed from the codebase. This deletion eliminates the built-in support for handling Server Page Fragment (SPF) requests, including the logic for detecting navigation/prefetch states and generating the corresponding JSON responses for partial page loads.

src/Http/Controllers/Front/Behaviors · high confidence

Removal of legacy Blade templates for the file library UI

The legacy Blade view files for the file library interface have been deleted. This includes the main index page, the file form, the list template, the insert template, and the helper link for opening the file library modal. These changes remove the old server-rendered UI components, likely as part of a migration to a new frontend architecture (such as Vue.js components) or a different rendering strategy.

views/files · high confidence

Removal of legacy PHP block implementations

The legacy PHP-based block rendering classes (BaseBlock, ImageBlock, SeparatorBlock, and TextBlock) have been removed from the BlockEditor service. This change eliminates the previous PHP-side logic for rendering block types such as images, text, and separators, indicating a shift away from this server-side rendering approach for these components.

src/Services/BlockEditor/Blocks · high confidence

Removal of legacy block rendering service

The \RenderBlocks\ class in the BlockEditor service has been removed. This class previously handled the conversion of block JSON data into HTML and metadata, including methods for processing full JSON structures, single blocks, and extracting images for sitemaps. Its removal indicates a shift in how block content is rendered, likely moving this logic to a different component or service within the application.

src/Services/BlockEditor · high confidence

Removal of legacy files and fileables database migrations

The migration file responsible for creating the 'files' and 'fileables' database tables has been removed from the codebase. This change eliminates the automatic creation of these specific schema structures during database setup, indicating that these tables are no longer part of the current application's data model or are managed through a different mechanism.

migrations · high confidence

Removal of legacy media library views

The legacy Blade templates for the media library interface have been removed. This includes the modal link opener, the main index/list views, the media form, the uploader component, and the crop and insert templates. These files are no longer part of the application, indicating a shift away from the previous server-rendered media management UI.

views/medias · high confidence

Removal of legacy navigation view partials

The legacy Blade view partials for the site's navigation structure have been removed. Specifically, the breadcrumb, global, primary, and secondary navigation components located in views/layouts/navigation are no longer present. This change eliminates the previous server-side rendering logic for these menu sections, indicating a shift away from the older navigation implementation.

views/layouts/navigation · high confidence

Architecture

Centralized SCSS import structure

The frontend styles are now consolidated through a new \\_imports.scss\ manifest file, which is included by \app.scss\. This single entry point organizes and loads all atomic, molecular, and organism-level styles, global layout and navigation components, vendor overrides, and utility classes, providing a unified and maintainable structure for the application's CSS.

frontend/scss · high confidence

Refactored frontend into modular Vue entry points with vendor component support

The frontend JavaScript structure has been reorganized from a monolithic entry point into distinct, purpose-specific Vue applications (main, dashboard, form, listing, buckets, free, and search). This change introduces a new \custom-components.js\ module that dynamically registers custom and vendor-provided Vue components, enabling third-party extensions to inject UI elements into the admin interface. Additionally, the global initialization script now integrates Alpine.js for lightweight DOM interactions alongside the existing Vue apps.

frontend/js · high confidence

Refactored frontend store into modular Vuex architecture

The frontend state management has been restructured from a monolithic store into a modular Vuex architecture, introducing dedicated modules for distinct content areas: blocks (visual editor), buckets (bulk management), browser (resource selection), form (submission and validation), media library, publication (publishing workflow), and revisions. This change centralizes state handling for these features, enabling better organization and reactivity for the content editor interface.

frontend/js/store/modules · high confidence

Store mutations are modularized into domain-specific files

The store mutation definitions have been reorganized from a single location into separate modules for each domain (attributes, blocks, browser, buckets, datatable, form, language, media-library, modal-edition, notification, parents, preview, publication, revision, and subscribers). This structure centralizes mutation constants and logic within their respective areas, improving maintainability and clarity for developers working on specific features like forms, media, or browser interactions.

frontend/js/store/mutations · high confidence

Behavioural changes

Added placeholder for twill-assets directory

A .gitkeep file was added to the twill-assets directory to ensure the folder is tracked by version control, preserving the directory structure even if it remains empty of other files.

twill-assets · medium confidence

Admin controllers refactored to use dependency injection and new service abstractions

The admin controllers (AppSettings, Dashboard, Featured, Group, Icons, Role, Setting, Singleton, and Blocks) have been rewritten to replace static facade calls (such as config(), request(), view(), and redirect()) with explicit constructor injection of their corresponding service interfaces (Config, Request, ViewFactory, Redirector, etc.). This change improves testability and aligns the controllers with modern Laravel service-container practices. Additionally, the BlocksController has been moved from the CmsToolkit namespace to the core Twill namespace and now uses the new BlockRenderer service for preview rendering.

src/Http/Controllers/Admin · high confidence

Admin password reset and welcome notifications now respect the admin route name prefix

The notification classes in src/Notifications (PasswordResetByAdmin, Reset, TemporaryPassword, and Welcome) have been updated to construct their email action URLs using the \twill.admin\_route\_name\_prefix\ configuration value. This ensures that password reset and welcome emails generated by administrators correctly link to the admin-specific login or reset forms when a custom route prefix is configured, rather than relying on default or public routes.

src/Notifications · high confidence

Automated upgrade rules for route and view namespace changes

New Rector rules have been added to automatically refactor code during upgrades: \RenameRoutes\ updates \route()\ calls from the \admin.\ prefix to \twill.\, and \RenameViews\ updates \view()\ calls from \admin.\ to \twill.\. These rules rely on a new \LaravelAwareRectorRule\ base class that bootstraps the Laravel application to dynamically load current route definitions, ensuring the refactoring targets the correct legacy-to-new mappings. A \LegacyTableConfig\ rule is also included to manage legacy table configuration entries.

src/Rector · high confidence

Backend authentication and routing behavior updates

The backend authentication flow now respects the \twill.admin\_route\_name\_prefix\ configuration for all internal routes, including login redirects and guest redirections. Unauthenticated or unpublished users are explicitly logged out and redirected to the login form instead of receiving errors. A new \ValidateBackHistory\ middleware prevents the browser back button from accessing authenticated pages after logout by adding cache-control headers. User language preferences are now applied via the \Localization\ middleware, and subdomain-based routing is supported through the \SupportSubdomainRouting\ middleware, which dynamically adjusts app configuration and navigation per subdomain. The \Permission\ middleware enforces subdomain access restrictions for non-super-admin users. Additionally, the \Impersonate\ and \RedirectIfAuthenticated\ middleware have been refactored to use dependency injection and the specific \twill\_users\ guard, replacing facade usage for better testability and consistency.

src/Http/Middleware · high confidence

Basic page builder example now uses Tailwind CSS and Quill editor

The basic page builder example has been updated to use Tailwind CSS for styling, with a new \app.css\ file importing Tailwind utilities and a responsive navigation menu component. The text block editor in the admin interface now uses the Quill WYSIWYG editor instead of the previous default, and the frontend page layout supports cover images and block rendering with improved typography and spacing.

examples/basic-page-builder/resources · high confidence

Centralized UI configuration and notification system

The frontend now registers a comprehensive set of UI components (such as text fields, media libraries, and date pickers) and directives globally via the new A17Config plugin, eliminating the need for individual imports in views. Additionally, a new A17Notif plugin introduces a global \notif\ method and an \a17-notif\ component, allowing any part of the application to trigger notifications by committing to the store.

frontend/js/plugins · high confidence

CloudFront cache invalidation now supports specific paths

The CloudFront cache service has been updated to allow invalidating specific URL paths rather than only the entire distribution. The \invalidate\ method now accepts an optional array of URLs (defaulting to \\['/\*'\]\), enabling users to clear only targeted content. Additionally, AWS SDK configuration (region and version) has been moved to the application config file (\services.cloudfront\), with hardcoded defaults retained for backwards compatibility, and the service now relies on dependency injection for configuration access.

src/Services/Cache · high confidence

Configuration system restructured and renamed from CmsToolkit to Twill

The package's configuration has been reorganized into a modular structure, replacing the legacy \config/cms-toolkit.php\ with a comprehensive set of dedicated configuration files (e.g., \config/twill.php\, \config/media\_library.php\, \config/oauth.php\, \config/glide.php\). This change introduces new configuration options for features such as the Block Editor, Capsules, and OAuth providers, while removing the previous \config/laravel-env-validator.php\ and renaming \config/cms-toolkit-publish.php\ to \config/twill-publish.php\. Users must update their configuration to align with the new file structure and keys.

config · high confidence

Custom HTML and Markdown email templates with environment labels

The CMS now ships with custom email view templates for both HTML and Markdown formats. The HTML templates feature a redesigned layout that includes a new header component displaying a colored environment label (e.g., green for local/dev, blue for staging, red for production) to help users identify the source of notifications. The templates also utilize the Inter font family and include standard components for buttons, panels, and footers, ensuring consistent styling across system-generated emails.

views/emails · high confidence

Default database migrations refactored for configurability and compatibility

The default database migrations have been restructured to support configurable table names via application config (e.g., \twill.users\_table\, \twill.blocks\_table\) rather than hardcoding table names like \users\ or \medias\. This includes renaming the original migration files into the \migrations/default\ directory to prevent conflicts with existing codebases. The schema definitions have been updated to use \bigIncrements\ for primary keys and \text\ columns for UUIDs and filenames to improve compatibility with larger datasets and MySQL. Additionally, new migrations have been added to introduce \editor\_name\ to blocks, \language\ to users, \position\ to mediables and fileables, and \event\/\batch\_uuid\ to the activity log, while also fixing foreign key constraints on password resets and ensuring safe migration resets.

migrations/default · high confidence

Deprecation of custom Exception Handler and addition of specific exception classes

The custom \src/Exceptions/Handler\ class is now deprecated (triggering a deprecation notice) and will be removed in v4, encouraging users to extend Laravel's default \ExceptionHandler\ instead. Additionally, new specific exception classes have been introduced to improve error handling granularity: \MediaCropNotFoundException\ for missing media crops, \ModuleNotFoundException\, \NoCapsuleFoundException\, \NoNavigationForSubdomainException\, and \ColumnMissingPropertyException\ (renamed from a previous S3 upload listener interface).

src/Exceptions · high confidence

FileLibrary service refactored to use dependency injection and updated namespace

The FileLibrary service has been moved from the CmsToolkit package to the Twill core namespace (A17\\Twill\\Services\\FileLibrary). The Disk class no longer relies on the global Storage facade or the config() helper; instead, it now accepts FilesystemManager and Config repository instances via constructor injection, using the configuration key twill.file\_library.disk instead of cms-toolkit.file\_library.disk. Additionally, PHPDoc blocks with type hints have been added to the Disk, FileService, and FileServiceInterface classes to improve static analysis support.

src/Services/FileLibrary · high confidence

Form field partials rewritten as Vue components with Vuex store integration

The form field partials in views/partials/form have been completely rewritten to use new Vue components (such as a17-textfield, a17-browserfield, a17-blocks, and a17-wysiwyg-tiptap) instead of previous implementations. These partials now pass configuration via props and attributes to the Vue components and push initial field values into the global Vuex store (window.TWILL.STORE) to ensure state consistency. The update introduces support for new field options including direction, mask, maxlength, and prefix for text inputs; activeCrop and videoUrl toggles for media fields; and connectedBrowserField for browser fields. It also adds a new block editor partial that registers available blocks and editor names in the store, and standardizes how default values, disabled states, and required indicators are handled across all form fields.

views/partials/form · high confidence

Interactive linked cells with edit capability in listings

Listings now render linked cells as interactive anchor tags that support an inline edit mode. When the edit link feature is enabled, clicking the link triggers a modal edit interface, allowing users to modify the linked content directly from the table view without navigating away.

views/listings · medium confidence

Introduce new block rendering infrastructure and component support

The block service layer has been refactored to support a new component-based architecture alongside the existing Blade-based approach. A new \BladeCompiler\ class now handles the compilation and rendering of Blade strings, while the \Block\ class has been expanded to include properties for component classes, icons, and title prefixes, enabling blocks to be defined via PHP classes rather than just view files. The \BlockCollection\ now provides specific methods to retrieve blocks, settings, and repeaters, and includes logic to filter duplicates and prioritize app-defined blocks over vendor ones. Additionally, a \RenderData\ DTO has been introduced to manage the context and children of blocks during rendering, facilitating better handling of nested blocks and editor previews.

src/Services/Blocks · high confidence

Introduces object-oriented filter classes for listings

The listing filter system has been refactored from a procedural or array-based approach to a structured, object-oriented API. New classes including BasicFilter, BelongsToFilter, BooleanFilter, FieldSelectFilter, FreeTextSearch, and QuickFilter provide a fluent interface for defining filter logic, options, and query application. This change allows developers to configure filters with greater type safety and reusability, supporting features like automatic label generation, query string handling, and specific database query scopes (e.g., filtering by related models or boolean fields).

src/Services/Listings/Filters · high confidence

Major refactor of model behaviors to Twill namespace and architecture

This change restructures the core model behaviors by moving them from the legacy \A17\\CmsToolkit\ namespace to \A17\\Twill\\Models\\Behaviors\. It introduces new traits for modular capabilities: \HasBlocks\ for content block rendering, \HasNesting\ for hierarchical content with nested slugs, \HasOauth\ for social login linking, \HasPermissions\ for granular role-based access control, \HasRelated\ for browser field associations, \HasRevisions\ for version control, and \IsTranslatable\ for translation checks. Existing traits like \HasFiles\, \HasMedias\, \HasPresenter\, \HasSlug\, and \HasTranslation\ are updated to use the new namespace, configuration-driven table names, and improved logic (e.g., \HasMedias\ now supports custom metadatas and crop parameters). The \Sorts\ trait is renamed to \HasPosition\ for consistency.

src/Models/Behaviors · high confidence

Migrate route definitions to TwillRoutes facade

Route definitions for the tests-modules example have been consolidated into a dedicated \twill.php\ file, replacing previous macro-based approaches with the \TwillRoutes\ facade. This change explicitly registers the 'authors' module under the 'personnel' prefix and the 'categories' module, providing a standardized way to define module routes within the Twill ecosystem.

examples/tests-modules/routes · high confidence

Namespace migration and PHP 8.1+ constant visibility update for UserRole enum

The UserRole enum has been moved from the A17\\CmsToolkit namespace to A17\\Twill, reflecting a rebranding or structural consolidation of the toolkit into the main Twill package. Additionally, the enum constants (VIEWONLY, PUBLISHER, ADMIN) have been updated to use the explicit public const syntax, ensuring compatibility with modern PHP versions (8.1+) and aligning with current coding standards.

src/Models/Enums · high confidence

New SCSS state modules for UI interactions

Added new SCSS partials in the frontend state directory to manage specific UI states: a loader with fade-in animation for page loads, an environment bar that slides in on scroll, and styles to prevent body scrolling when modals or overlays are active. Additionally, mobile navigation styles were updated to handle the hamburger menu state at medium breakpoints and above.

frontend/scss/state · high confidence

New SCSS styles for login and dashboard search components

Added new SCSS files to the organisms directory to style the login interface and the dashboard search area. The login styles define the layout, input fields, buttons, and social login links, while the dashboard search styles set the background and minimum height for the search bar.

frontend/scss/organisms · high confidence

New SCSS utility classes for accessibility and layout

A new \\_utilities.scss\ file has been added to the frontend styles, introducing two utility classes. The \.visually-hidden\ class provides an accessible method to hide content visually while keeping it available for screen readers, and \.create-fieldset-margin\ applies a specific top margin to support the layout of fieldsets within the create modal.

frontend/scss/utilities · high confidence

New admin UI partials for layout, creation forms, and notifications

The admin interface now uses a set of new Blade partials to render core layout and interaction elements. The head partial enforces noindex/nofollow on CMS pages, configures the Inter font family, and manages CSS/JS preloading. The create partial introduces a customizable title input (supporting custom keys and labels) and an optional permalink field with prefix support. The footer partial displays a version number pulled from configuration and a 'Made with Twill' link. Finally, the toaster partial handles the display of validation errors, status messages, and restore notifications.

views/partials · high confidence

New atomic design styles for UI components

The frontend styling system now includes a new set of atomic SCSS modules in the \frontend/scss/atoms\ directory. These changes introduce dedicated styles for environment labels (\\_envlabel.scss\), external link indicators (\\_external.scss\), and responsive typography (\\_fonts-styles.scss\). Additionally, new styles are added for the mobile hamburger navigation (\\_ham.scss\), self-destructing notifications (\\_notif.scss\), tags (\\_tag.scss\), tooltips (\\_tooltip.scss\), and underlined text variants (\\_underlined.scss\). Utility classes for hiding elements at specific breakpoints (\\_hide.scss\) and general resets (\\_general-styles.scss\) are also included to support the new component structure.

frontend/scss/atoms · high confidence

New fluent field builder API for form fields

The form field definitions in src/Services/Forms/Fields have been refactored to use a new fluent builder pattern. Each field (such as Input, Select, Medias, and Wysiwyg) now extends a new BaseFormField class, which standardizes how field properties like name, label, and default values are set and how they render to view components. This change introduces new capabilities including connected fields support (allowing one field to conditionally show based on another), explicit configuration for the BlockEditor and Browser fields, and specific options like clearable selects, searchable multi-selects, and 24-hour time formats for date pickers.

src/Services/Forms/Fields · high confidence

New frontend SCSS design system foundation

The frontend styling foundation has been restructured into a modular SCSS setup under \frontend/scss/setup\. This introduces a comprehensive color palette with semantic variables for UI states (buttons, forms, tags, notifications), a responsive grid system with configurable breakpoints and gutters, and a unified typography setup using the Inter font family with \font-display: swap\ for improved loading performance. Additionally, a design-grid overlay tool is now available for visual layout debugging, and global resets and mixins are standardized to support consistent component styling across the application.

frontend/scss/setup · high confidence

New frontend behavior modules for navigation, logout, media library, and environment indicators

This change introduces four new JavaScript behavior modules in the frontend to handle specific UI interactions. The logout button now uses a POST request via a hidden form for security, replacing previous methods. A new mobile navigation toggle manages the opening and closing of the menu with scroll-position awareness. Users can now open the media library directly from the header in free mode via a dedicated button. Additionally, a colored environment indicator line is shown or hidden based on scroll position to provide visual context. These behaviors are implemented as reusable, exported functions that attach event listeners to specific DOM elements.

frontend/js/behaviors · high confidence

New layout system with column utilities and form styling

The layout styling has been restructured into modular SCSS files, introducing a new grid system with specific column span configurations for primary, aside, and even layouts across breakpoints. New utility classes like .col--double and .col--third allow for flexible two- and three-column arrangements in forms and dashboards, while dedicated styles for .field-rows enable 2-column and 3-column layouts for form inputs and selectors. Additionally, new styles define the appearance of the main application container, error pages, and custom admin pages, ensuring consistent spacing and background colors across different view types.

frontend/scss/layout · high confidence

The admin interface now features a multi-level navigation system. A new breadcrumb trail is displayed above content, while secondary and tertiary navigation bars support request-specific links injected by controllers. The mobile experience uses an overlay menu that includes user profile and logout options, with the user dropdown menu conditionally hidden if user management is disabled. The header title now displays a shorthand environment label (e.g., 'prod') for production sites.

views/partials/navigation · high confidence

New specialized table cell components for listings

The table listing UI now uses dedicated Vue components for specific column types, replacing the previous monolithic implementation. This change introduces specialized cells for actions (dropdown menu with edit, publish, feature, duplicate, delete, and destroy options), bulk selection checkboxes, publication dates (with expired/scheduled status logic), draggable row handles, featured status toggles, language tags (showing the first 4 with a 'more' link), nested list indentation, publish state indicators, and thumbnails (supporting rounded avatars). These components are registered in the table cell index and rely on a shared mixin for common row data and event handling.

frontend/js/components/table/tableCell · high confidence

New table column configuration and model browser data formatting

This change introduces the \TableColumn\ class, allowing columns to be configured with specific properties such as \shrink\, \sortKey\, and \linkToEdit\, alongside a new \TableColumns\ collection that formats model data for the CMS. Specifically, the model browser now retrieves the \adminEditUrl\ and \titleInBrowser\ accessors from models to populate edit links and display names, ensuring the browser UI correctly reflects these model-level attributes.

src/Services/Listings · high confidence

Portfolio example updated to use modern Twill APIs and Blade components

The portfolio example has been refactored to align with current Twill best practices. Controllers now extend the base ModuleController and use the TwillRoutes facade for registration instead of route macros. Repository logic has been updated to use the new HandleRepeater behaviors (updateRepeaterMorphMany, updateRepeaterWithPivot) and form field getters, replacing older manual morph handling. Additionally, admin form views have been migrated from the legacy @formField directive to modern Blade components (e.g., \<x-twill::input\>), and database migrations now utilize anonymous class syntax.

examples/portfolio · high confidence

Quill editor configuration and customization

The Quill editor library has been reconfigured to support new formatting options and improved link handling. Users can now insert horizontal dividers (hr) and use Shift+Enter for soft line breaks within the editor. Link behavior has been updated so that relative URLs and those starting with the application's base URL no longer open in a new tab, while external links continue to open in a new tab by default. Additionally, the editor now supports custom anchor formatting and uses custom SVG icons for toolbar buttons.

frontend/js/libs/Quill · high confidence

Redesign password reset and choose-password forms to use Twill's auth layout

The password reset (email.blade.php) and choose-password (reset.blade.php) views have been rewritten to extend the standard Twill authentication layout instead of using a standalone HTML structure. This change updates the UI to match the rest of the Twill admin interface, applies consistent styling classes (e.g., login\_\fieldset, login\\_input), and ensures the form submission routes respect the configured admin route name prefix. Additionally, the choose-password form now automatically pre-fills the user's email address and dynamically sets the screen title and submit button text based on whether the user is resetting a forgotten password or setting a password for the first time (welcome flow).

views/auth/passwords · high confidence

Redesigned block editor with drag-and-drop, cloning, and new default block types

The block editing interface has been overhauled to support drag-and-drop reordering, block duplication (cloning), and inline expansion/collapse. The new \Blocks.vue\ component integrates \vuedraggable\ for visual reordering and provides action menus for cloning, deleting, and opening blocks in a dedicated editor. Several default block types are now available out-of-the-box, including Image, Table, Title, and Wysiwyg, all utilizing a shared \BlockMixin\. The underlying data management has been refactored into \BlockEditorModel\ and \BlocksList\ components, which handle state mutations for adding, moving, and removing blocks via Vuex, while \BlockEditorItem\ manages the individual block UI and title sanitization.

frontend/js/components/blocks · high confidence

Redesigned user and group management forms with new UI components

The user management interface has been completely rewritten to use the modern Twill component system (e.g., \x-twill::input\, \x-twill::browser\) instead of the legacy form helpers. This update introduces several new capabilities: users can now select their preferred language from available locales, and administrators can manage two-factor authentication settings, including the ability to force-disable 2FA for stuck users. Additionally, a new 'Groups' feature allows admins to assign users to groups and configure granular content permissions per module. The user listing view has been removed in favor of the standard resource index layout, and user profile images are now disabled by default.

views/users · high confidence

Refactor frontend controllers to use explicit service injection and update namespace

The frontend controller layer has been refactored to replace global helper functions (such as \config()\, \app()\, \Str::endsWith()\) with explicit dependency injection of their corresponding service classes (e.g., \Illuminate\\Config\\Repository\, \Illuminate\\Foundation\\Application\, \Illuminate\\Support\\Str\). This change is applied across the new \GlideController\ and \ShowWithPreview\ trait, as well as the base \Controller\ class, which also updates its namespace from \A17\\CmsToolkit\ to \A17\\Twill\ and uses the injected \Config\ repository for SEO settings. Users benefit from more testable and decoupled controller logic, while the \ShowWithPreview\ trait now explicitly handles preview routing and view rendering through injected services.

src/Http/Controllers/Front · high confidence

Refactor view composers to support multi-cloud storage and modernize Laravel dependencies

The view composers in the Http layer have been restructured to support Azure and S3 storage backends for both file and media libraries, in addition to local storage. New composers (FilesUploaderConfig, MediasUploaderConfig, Localization) inject configuration and session data to expose storage endpoints, access keys, and localization strings to the frontend, while the existing CurrentUser composer now uses the AuthFactory instead of the auth() helper. The old ActiveNavigation composer was removed, and namespaces were updated from CmsToolkit to Twill.

src/Http/ViewComposers · high confidence

Refactored Vue directives for tooltips, SVGs, and sticky positioning

The frontend directive system has been updated to improve stability and consistency. The tooltip directive now explicitly disposes and recreates the tooltip instance on component updates, preventing issues with duplicated or stale tooltips. The SVG directive has been rewritten to handle element creation and removal via utility functions during updates. Additionally, a new sticky directive has been introduced to manage sticky positioning behavior for elements.

frontend/js/directives · high confidence

Refactored block rendering, capsule loading, and migration helpers

The \src/Helpers\ area has been significantly restructured to support new architectural capabilities. A new \BlockRenderer\ class now handles the rendering of nested block components, replacing previous inline logic. The \Capsule\ helper class has been introduced to manage the bootstrapping of isolated modules (capsules), including their service providers, views, migrations, and routes. Migration helpers (\migrations\_helpers.php\) have been updated to use \bigIncrements\ by default and now include new functions for creating relationship and revision tables. Additionally, frontend asset helpers (\frontend\_helpers.php\) have been refactored to support configurable asset paths and capsule-specific view names, while the \FlashNotifier\ class was removed and \FlashLevel\ constants were updated.

src/Helpers · high confidence

Refactored form request validation and added Azure storage support

The form request classes in src/Http/Requests/Admin have been migrated from the CmsToolkit namespace to Twill and refactored to support separate validation rules for create and update operations via new rulesForCreate and rulesForUpdate methods. Validation for translated fields now uses dot-notation keys (e.g., field.locale) instead of underscores, and correctly handles locale activation status by removing required constraints when a locale is inactive. File and media upload requests now explicitly support Azure Blob storage in addition to local and S3 endpoints, requiring a 'blob' field for Azure uploads. User validation has been enhanced to include password strength checks, two-factor authentication (2FA) verification for enabling/disabling 2FA, and privilege checks for super admins forcing 2FA disable on other users.

src/Http/Requests · high confidence

Refactored media library logic into reusable mixins

The media library functionality has been restructured by extracting common logic into two new mixins: \mediaItems\ and \mediaLibrary\. The \mediaItems\ mixin centralizes item selection, usage tracking, and replacement state management, while the \mediaLibrary\ mixin standardizes how the media connector is opened and configured via Vuex store mutations. This change improves code maintainability and ensures consistent behavior across components that interact with the media library.

frontend/js/mixins/mediaLibrary · high confidence

Refactored modal creation and validation components

The modal creation workflow has been refactored to improve reliability and user experience. A new ModalAdd component handles simple additions, while ModalCreate now manages both creation and updates with proper state management for publication toggles and form fields. The ModalValidationButtons component has been rewritten to dynamically enable/disable submit buttons based on required field validation, preventing accidental submissions. Additionally, a retrySubmitMixin has been introduced to prevent multiple simultaneous submit events, fixing issues where users could accidentally trigger duplicate submissions, particularly in Safari and Firefox.

frontend/js/components/modals · high confidence

Removal of custom paginator presenter and button renderer trait

The custom \PaginatorPresenter\ and its associated \PaginatorNextPreviousButtonRendererTrait\ have been removed from the admin presenters. This eliminates the application's custom implementation for rendering pagination links (including previous/next buttons and page wrappers) that previously extended Laravel's \BootstrapThreePresenter\, effectively reverting pagination rendering to the framework's default behavior or a different mechanism not present in this scope.

src/Presenters · high confidence

Removal of legacy A17 CMS stylesheet

The \assets/a17cms.css\ file, which contained the global styles for the A17 CMS (version 1.7.8), has been deleted. This removes the legacy CSS rules for the CMS interface, including the datetime picker, color swatches, and markItUp editor, from the application assets.

assets · high confidence

Removal of legacy Blade view templates for CMS resource listings

The legacy Blade view files for CMS resource management have been removed from the codebase. This includes the main layout templates for index listings (index.blade.php), forms (form.blade.php), and media browsers (browser.blade.php), as well as the partials used to render table columns, action buttons (edit, delete, publish, sort), and pagination. Users relying on these specific view paths for customizing the CMS interface will need to update their overrides to use the new view structure.

views/layouts/resources · high confidence

Removal of legacy form field partials

The legacy Blade view partials for form fields (including \_block\_editor, \_date\_picker, \_files, \_input, \_medias, \_publish\_status, \_rich\_textarea, \_select, \_slug\_input, \_textarea, and language/locale variants) have been removed from the views/layouts/form\_partials directory. This cleanup eliminates the old SirTrevor-based block editor implementation and the previous multi-locale input rendering logic, indicating a migration to a new form rendering system or Vue-based components.

_views/layouts/form\partials · high confidence

Repository layer migrated from CmsToolkit to Twill with new settings and block handling

The repository classes in src/Repositories have been moved from the A17\\CmsToolkit namespace to A17\\Twill, reflecting a broader platform rebranding. New repositories have been introduced for AppSettings, Blocks, Groups, Roles, and Settings, providing dedicated data access for these core CMS entities. The existing File and Media repositories now use the Twill namespace and configuration keys (e.g., twill.file\_library instead of cms-toolkit.file\_library), and the Media repository adds a configuration option to disable automatic alt-text generation from filenames. The ModuleRepository has been significantly expanded with new behaviors (browsers, repeaters, permissions, fields groups) and methods (firstOrCreate, cmsSearch, getCountByStatusSlug), while the UserRepository now integrates OAuth, 2FA management, and permission-based filtering.

src/Repositories · high confidence

Restored fonts directory placeholder

The frontend/fonts directory has been restored by adding a .keep file, ensuring the folder persists in the repository structure.

frontend/fonts · high confidence

Rewritten module generator stubs and simplified route registration

The module generator stubs have been completely rewritten to align with the new Twill architecture, replacing the legacy CmsToolkit-based templates with modern equivalents. Controllers now extend a configurable base class and utilize the new TableColumns and Form services instead of legacy blade-based layouts. Route registration has been simplified to use the \TwillRoutes\ facade, and migrations now leverage anonymous classes. Additionally, the generator now supports optional features such as module nesting, revisions, and slugs, and automatically configures translated attributes for models.

src/Commands/Stubs · high confidence

Route definitions are now feature-gated and restructured

The admin and auth route files have been refactored to wrap specific capabilities in feature flags (e.g., \twill.enabled.media-library\, \twill.enabled.buckets\, \twill.enabled.users-2fa\). This means routes for media/file libraries, buckets, two-factor authentication, and OAuth login are only registered when their respective features are enabled in the configuration. Additionally, the media and file library routes now support Azure storage signing alongside S3, and the user management routes are conditionally loaded based on the \users-management\ and \permissions-management\ flags.

routes · high confidence

SEO helper now preserves default values when setters receive empty input

The Seo helper class in the front-end controllers now includes setter methods for title and description that only update the property if a non-empty value is provided. This change ensures that existing default values are retained when these setters are called with empty strings, preventing accidental overwrites of SEO metadata.

src/Http/Controllers/Front/Helpers · high confidence

Standardized development tooling and configuration files

The project now includes explicit configuration files for its build and code quality toolchain, replacing implicit or missing setups. This introduces ESLint and Prettier for JavaScript/Vue formatting, PHP-CS-Fixer and PHP\_CodeSniffer for PHP standards, and Babel for transpilation. It also adds a PHPUnit 11 configuration, PHPStan static analysis setup, and Rector scripts to automate code upgrades and namespace migrations (e.g., Admin to Twill). Additionally, a Code of Conduct, Security policy, and Upgrade guide are provided to standardize community interaction and migration paths.

(repo-wide) · high confidence

Standardized error page views and layout inheritance

The error page views in the \views/errors\ directory have been updated to inherit from the \twill::layouts.errors\ layout instead of the previous \cms-toolkit::layouts.errors\ layout. Several new error pages have been added for HTTP 403 (Forbidden), 419 (Page Expired), and 429 (Too Many Requests) statuses, providing specific user-facing messages for these conditions. Existing error pages (401, 404, 500, 503) have been refactored to use consistent paragraph-based content structures and include links back to the homepage where appropriate. Additionally, new views have been introduced to handle developer-facing errors for missing block previews, block layouts, and module previews, offering clear instructions on how to resolve these issues in development environments.

views/errors · high confidence

Styled and interactive HTML table cells

A new component for rendering raw HTML content within table cells now applies consistent link styling (using the defined link color) and ensures links appear as clickable pointers without underlines. Additionally, any links within the cell content that carry the data-edit attribute are now handled to prevent in-place editing when clicked.

frontend/js/components/table/tableCell/generic · high confidence

Support for fieldsets and block-specific form rendering

The form rendering pipeline now supports grouping fields into fieldsets and handling block-specific forms. In the base form view, content fields are optionally wrapped in a fieldset, and additional fieldsets defined in $renderFieldsets are rendered with configurable open states and margins in create mode. A new block\_form view ensures fields are correctly flagged for block rendering when applicable, allowing mixed fieldset and block content to be displayed correctly in forms.

views/partials/form/renderer · high confidence

Support for multi-subdomain admin routing in Twill

The example application now supports managing content across multiple subdomains (e.g., 'subdomain1' and 'subdomain2') within a single Twill installation. This is enabled by setting \support\_subdomain\_admin\_routing\ to true in the Twill configuration and defining distinct navigation menus and app names for each subdomain. The routing layer has been updated to use the \TwillRoutes\ facade instead of route macros, allowing the 'pages' module to be accessible and configured independently per subdomain.

examples/tests-subdomain-routing · high confidence

Updated compiled frontend assets for release 3.5.3

This release updates the compiled CSS assets in the \twill-assets\ directory, including the new \chunk-common.eea3635b.css\ file. The changes reflect the latest frontend build, incorporating styles for the design grid toggle, navigation, form fields, and various UI components, consistent with the version bump to 3.5.3.

twill-assets/assets · high confidence

Updated database migrations to use anonymous classes

The database migration files in the tests-modules example have been refactored to use PHP anonymous classes (e.g., \return new class extends Migration\) instead of named classes. This change modernizes the migration syntax while preserving the existing schema definitions for categories, authors, and revision-limited contents.

examples/tests-modules/database · high confidence

Updated example capsules to use modern Twill conventions

The example application's Posts and Homepages capsules have been rewritten to align with current Twill best practices. The Homepage singleton now uses the \TwillRoutes\ facade for routing, disables permalinks, and defines its form fields and table columns programmatically via the controller instead of relying on Blade templates. The Posts module has been updated to use anonymous class syntax for its database migrations and includes a dedicated capsule service provider. These changes ensure the example code reflects the latest architectural patterns for module and singleton configuration.

examples/tests-capsules · high confidence

User model refactored for role-based permissions and two-factor authentication

The User model has been significantly updated to support role-based access control and enhanced security features. It now includes behaviors for OAuth login, two-factor authentication (Google 2FA), and translatable attributes, while switching from a string-based role field to a \role\_id\ foreign key when permissions management is enabled. The model introduces new scopes (\accessible\, \activated\, \pending\, \draft\, \onlyTrashed\) to filter users based on their status and permissions, and adds casts for boolean and datetime fields to ensure correct data handling. Additionally, the model now implements \TwillModelContract\ and uses a configurable table name, improving extensibility and integration with the CMS.

src/Models · high confidence

Vendor style overrides for image cropping, date picking, and selection components

This change introduces dedicated SCSS files in the vendor folder to customize the appearance and behavior of third-party UI libraries. For the image cropper, hit areas for cropping points are increased to improve touch usability. The flatpickr date picker is styled to match the application's design system, including specific height and font adjustments. Vue-select components receive extensive styling updates, such as expanding dropdown menus to fit content, adjusting spinner and clear button positions, and refining single-select and multi-select layouts.

frontend/scss/vendor · high confidence

Fixes

Added placeholder to preserve customs blocks directory

A .keep file was added to the frontend/js/components/blocks/customs directory to ensure the folder persists in the repository and build process, preventing missing folder errors during CI builds.

frontend/js/components/blocks/customs · high confidence

Test coverage

Added TestPresenter for testing model presentation; Added browser tests for Twill's block editor, media handling, and date/time features; Added integration test helper traits for file and block operations; Added integration tests for Capsule system; Added integration tests for Twill Artisan commands; Added integration tests for block browser clearing and nested block sorting; Added integration tests for controller index option setters; Added integration tests for core Twill features; Added integration tests for exception handling; Added integration tests for media/file deletion and module repository slugs; Added integration tests for navigation and settings visibility; Added integration tests for repository duplication, repeaters, and tag slugs; Added integration tests for revisions and draft revisions; Added integration tests for table filters and search functionality; Added integration tests for the Admin Dashboard activity feed; Added integration tests for the AnonymousModule testing utility; Added integration tests for the Cartalyst Tags package; Added integration tests for the Settings system; Added integration tests for translated model queries; Added integration tests for user management and email functionality; Added unit tests for MediaLibrary parameter processors; Added unit tests for form field components; Added unit tests for form services and translation utilities; Added unit tests for helper and model functions; Added unit tests for validation rules; Initial PHPUnit test infrastructure and helpers; Integration tests added for table listing columns and sorting.

Dependencies

Twill 3.6.0 release with updated dependencies and new build tooling

This release updates the core frontend dependencies, including Alpine.js to 3.15.11, TipTap to 2.2.1, and Vue to 2.7.16, while also introducing a new Vite-based build configuration for the basic page builder example. The package metadata has been updated to version 3.6.0, and the documentation API now uses Doctum 5.4 for generating API docs.

(dependencies) · high confidence

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

How this codebase got here

Baseline

  • First survey — no prior run to compare against. CAI 46.

Lenses

  • Code Health 62
  • Architecture 59
  • Maturity 62
  • Readiness 50
  • Security 66
  • Accessibility 36

Changes since last survey

  • 300 commits — 209 feature/other, 91 fixes

By area

  • (root) — 69 commits
  • .github/workflows — 34 commits
  • frontend/js — 25 commits
  • docs/content — 22 commits
  • src/Repositories — 17 commits
  • src/Http — 16 commits
  • src/Services — 16 commits
  • tests/Browser — 13 commits
  • src/Models — 11 commits
  • tests/integration — 11 commits
  • twill-assets/assets — 11 commits
  • src/Commands — 9 commits
  • src/Helpers — 7 commits
  • (repo) — 3 commits
  • frontend/scss — 3 commits
  • migrations/default — 3 commits
  • src/DuskServiceProvider.php — 3 commits
  • tests/unit — 3 commits
  • config/twill.php — 2 commits
  • src/TwillBlocks.php — 2 commits

Notable commits

  • fix: Add @mixin to facades to fix phpstan issue
  • fix: Add empty customs folder for blocks to fix build in CI
  • fix: CS fix
  • fix: Disable heading extension if it's not in the toolbar Fix #2489
  • fix: Fix #2674
  • fix: Fix BlockRepository setting relation of an object and improve amount of queries during saves
  • fix: Fix CI release messages
  • fix: Fix GitHub Actions upload artefact v4 usage
  • fix: Fix GitHub Actions upload artefact v4 usage
  • fix: Fix GitHub Actions upload artefact v4 usage
  • fix: Fix L9 tests due to Dusk 7 not supporting Chrome > 126
  • fix: Fix L9 tests due to Dusk 7 not supporting Chrome > 126
  • fix: Fix L9 tests due to Dusk 7 not supporting Chrome > 126
  • fix: Fix L9 tests due to Dusk 7 not supporting Chrome > 126
  • fix: Fix alt text stripping accents and single quotes (#2514)
  • fix: Fix avoid recursive reference in relation
  • fix: Fix build in release workflow
  • fix: Fix created at is null in slug table (#2588)
  • fix: Fix dbal 4 conflict (#2596)
  • fix: Fix deleted users causes error 500
  • …and 280 more

Architecture

  • 0 containers · 1 bounded contexts · 0 dependency edges (baseline)

Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.

Survey your own repository

area17/twill was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.

About this page

  • The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
  • Measured at commit d763dee5b60109ee38f83806e478e9c4a2ac36d5 — the exact code this score is about.
  • Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
  • Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.