A CakePHP 5 Plugin with Bootstrap 5 theme, custom helpers, components, and bake templates for rapid application development.
- PHP 8.4 or higher
- CakePHP 5.3 or higher
- Bootstrap 5 (via FriendsOfCake/bootstrap-ui)
Install the plugin via Composer:
composer require queencitycodefactory/butter-creamLoad the plugin in your application's src/Application.php:
public function bootstrap(): void
{
parent::bootstrap();
$this->addPlugin('ButterCream');
}ButterCream\Controller\Controller- Extended base controller with:- Ajax pagination support with configurable limits
- Automatic ajax layout switching
- Enhanced pagination with page-out-of-bounds handling
- Auto-loaded Flash and Referer components
- PDF and Spreadsheet view support
ButterCream\Controller\Component\FlashComponent- Enhanced flash messaging with HTML support by default
- Methods:
success(),error(),set()
ButterCream\Controller\Component\RefererComponent- Smart referer tracking and redirection
- Configurable ignored URLs
- Normalizes URLs for consistent matching
- Methods:
setReferer()- Store referer for later usegetReferer()- Retrieve current refererredirect()- Redirect to referer or fallbackisMatch()- Check if referer matches a URLignore()- Add URL to ignore list
ButterCream\Controller\Component\ExportComponent- Export controller support for spreadsheet and PDF downloads
ButterCream\View\Helper\AjaxHelperrelatedData()- Create containers for AJAX-loaded content
ButterCream\View\Helper\AlertHelper- Bootstrap 5 alert and callout rendering
success(),error(),warning(),info()- Typed alerts with iconscallout()- Callout-style alerts- Dismissible and non-dismissible variants
ButterCream\View\Helper\BadgeHelper- Bootstrap 5 badge rendering with configurable color maps
badge()- Generic badge with any variantstatus()- Status badges with automatic color mappingpriority()- Priority badges with automatic color mappingboolean()- Yes/No badges for boolean values
ButterCream\View\Helper\CardHelper- Bootstrap 5 card rendering
card()- Standard card with header, body, footerstatsCard()- Stats/metric display cardlistGroupCard()- Card with list group body
ButterCream\View\Helper\FlashHelper- Enhanced flash message rendering with Bootstrap 5 styling
ButterCream\View\Helper\FiltersHelper- Bootstrap 5 dropdown-based filter drawer for index pages
setup()- Configure drawer ID, title, update selector, URLaddControl()- Register filter fields (passed through to FormHelper)render()- Output toggle button and drawer panel with GET form- Works in both standalone page and AJAX (relatedData) contexts
- Active filter count shown as badge on toggle button
ButterCream\View\Helper\FormHelper- Extended Bootstrap 5 form helper
create()- Automatic referer tracking in formspostLink()- Enhanced POST links with modal confirmationdeleteBtn()- Pre-configured delete buttonsaveButton()- Pre-configured save button with iconcancelButton()- Cancel with referer redirectbackButton()- Back navigation buttoncontinueButton()- Continue/next step buttonconfirmButton()- Modal-confirm enabled buttonresetButton()- Form reset button with iconswitch()- Bootstrap 5 form-switch togglecolorPicker()- Color picker input with Bootstrap stylingcontrol()- Enhanced withenhancedSelect(auto TomSelect), input groups (prepend/append), floating labels
ButterCream\View\Helper\FormatHelperssn()- Format US Social Security Numberszip()- Format US ZIP codes (5 or 9 digit)phone()- Format US phone numbersparsePhone()- Parse phone number partsformatString()- Apply custom formatting patternsmaskString()- Mask sensitive data
ButterCream\View\Helper\HtmlHelper- Extended Bootstrap 5 HTML helper
icon()- Font Awesome icon shorthandnullSafe()- Display em-dash for null valuesaccordion()- Bootstrap 5 accordion from array configviewBtn()/editBtn()/addBtn()- Pre-styled action buttonsactionDropdownMenu()- Bootstrap 5 dropdown action menu
ButterCream\View\Helper\PaginatorHelper- Bootstrap 5 styled pagination
ajaxTemplateOptions()- Configure AJAX pagination link templates withdata-updateattribute- Custom Font Awesome icons for prev/next
- Enhanced
prev(),next(),numbers()methods
ButterCream\View\Helper\ProgressHelper- Bootstrap 5 progress bar rendering
bar()- Single progress bar with variant, label, striped, animated optionsstacked()- Multiple stacked progress bars
ButterCream\View\Helper\TableHelperheader()- Generate sortable table column headers with sort direction indicators- Bootstrap 5 table styling
- AJAX-aware: generates
ajax-pagination-linkclass anddata-updateattributes when in AJAX context
ButterCream\View\Helper\TimeHelpersemantic()-<time>element with Bootstrap tooltip showing relative timerelativeTime()- Human-friendly relative time stringsuserFormat()- Configurable date/datetime formatting
ButterCream\View\Helper\UrlHelper- Extended URL helper
ButterCream\View\Helper\GravatarHelper- Generate Gravatar image URLs
ButterCream\View\Helper\FiltersHelper- Bootstrap 5 dropdown-based filter drawer for index pages
- Register filter controls in templates; the layout calls
render()for the toggle button and drawer panel - Works in both standalone page and AJAX (relatedData) contexts
ButterCream\View\Helper\NestedTreeHelper- Render nested tree structures
ButterCream\View\ButterCreamHelpersTrait- Reusable trait for loading the standard ButterCream helper stack in any View class
- Call
loadButterCreamHelpers()from your View'sinitialize()method
ButterCream\Model\Table\AppTable- Automatic data cleaning for weird character encodings (smart quotes, em dashes, etc.)
- Base table class with reusable callbacks
ButterCream\Model\TreeviewTraitfindTreeview()- Custom finder for nested tree data- Configurable key fields and nesting
ButterCream\Model\Validationphone()- Validate US phone numberspostal()- Validate US ZIP codesssn()- Validate US Social Security Numbersbirthdate()- Validate birthdate (not in future)
ButterCream\Model\Entity\File- File management entity with path and base64 getters
- Flysystem integration
ButterCream\Service\FileService- Service-layer class for file storage, retrieval, resizing, and deletion
- Uses Flysystem for filesystem abstraction
- Model/foreign key pattern to associate files with any table record
- Image resizing with Imagick support
- Replaces the deprecated
FileApi
ButterCream\Http\Exception\ButterCreamException- Base exception class for the plugin
ButterCream\Message\Exception\StatusMessageException- Exception for user-facing errors with flash message support
ButterCream\Routing\Middleware\SessionTimeoutMiddleware- Configurable session timeout management
- AJAX-aware session extension
- Automatic session destruction on timeout
ButterCream\Routing\Middleware\TrustProxyMiddleware- Configure proxy trust settings
ButterCream\Utility\Format- Static formatting methods for SSN, phone, ZIP codes
- Pattern-based string formatting and masking
ButterCream\Utility\Muddle- Array manipulation utilities
insert()- Insert values using path notationbuildDotNotationPath()- Build paths from arrays
ButterCream\Database\Type\JsonArrayType- Custom JSON array type with batch casting support
ButterCream\View\AppView- Pre-configured with all ButterCream helpers
ButterCream\View\PdfView- PDF generation support via CakePdf
- Pre-configured with ButterCream helpers
Custom bake templates for rapid development with Bootstrap 5 styling:
- Controllers - Pre-configured with Search component and ButterCream base
- Models/Tables - Enhanced table templates with callbacks
- Templates - Bootstrap 5 styled CRUD views
add.twig- Create formsedit.twig- Edit formsindex.twig- List views with tablesview.twig- Detail views
- Form Elements - Bootstrap 5 form styling
ButterCream\Error\ExceptionRenderer- Custom error rendering with ButterCream theme
- Safe error message handling
- Debug-aware error messages
namespace App\Controller;
use ButterCream\Controller\Controller;
class ArticlesController extends Controller
{
// Automatic Flash and Referer components loaded
// Ajax pagination configured
// PDF and Spreadsheet views available
}public function delete($id)
{
$article = $this->Articles->get($id);
if ($this->Articles->delete($article)) {
$this->Flash->success('Article deleted.');
}
// Redirect back to where user came from
return $this->Referer->redirect(['action' => 'index']);
}// In a template
echo $this->Format->phone('5551234567'); // (555) 123-4567
echo $this->Format->ssn('123456789'); // 123-45-6789
echo $this->Format->zip('12345'); // 12345
echo $this->Format->zip('123456789'); // 12345-6789// Create sortable table headers
<table class="table">
<thead>
<tr>
<?= $this->Table->header('id', 'ID') ?>
<?= $this->Table->header('title', 'Article Title') ?>
<?= $this->Table->header('created', 'Created') ?>
</tr>
</thead>
</table>// In a Table class
use ButterCream\Model\TreeviewTrait;
class CategoriesTable extends AppTable
{
use TreeviewTrait;
}
// In a controller
$categories = $this->Categories->find('treeview');use ButterCream\Service\FileService;
$fileService = new FileService();
// Get a file record (optionally with file contents)
$file = $fileService->get($id, contents: true);
// Upload a file associated with a record
$fileService->upload($uploadedFile, 'Articles', $articleId);
// Delete a file (removes from disk and database)
$fileService->delete($id);The plugin includes custom bake templates that generate Bootstrap 5 styled code:
bin/cake bake model Articles
bin/cake bake controller Articles
bin/cake bake template ArticlesGenerated code will include:
- Bootstrap 5 form styling
- Pre-configured Search component
- ButterCream helpers
- Responsive table layouts
- Modal confirmations for delete actions
Add to your Application.php:
$middlewareQueue->add(new \ButterCream\Routing\Middleware\SessionTimeoutMiddleware([
'timeout' => 30 // minutes
]));$middlewareQueue->add(new \ButterCream\Routing\Middleware\TrustProxyMiddleware(true));- friendsofcake/search - Search functionality
- friendsofcake/bootstrap-ui - Bootstrap 5 integration
- friendsofcake/cakepdf - PDF generation
- queencitycodefactory/cakespreadsheet - Spreadsheet generation
- league/flysystem - Required for
FileServicefile operations - cakephp/migrations - Required to run the optional files table migration
MIT License. See LICENSE file for details.
Butter Cream includes a comprehensive test suite powered by PHPUnit. The current test coverage includes:
- FlashComponent - Escape default, HTML flash messaging, exception handling
- RefererComponent - URL normalization, referer tracking, redirect logic, ignore list
- FormatHelper - US formatting (SSN, phone, ZIP)
- Format - String formatting and masking
- Muddle - Array manipulation utilities
- Validation - US data validation (phone, postal, SSN, birthdate)
- TreeviewTrait - Nested data structure nesting and custom keys
- AppTable - Data cleaning (smart quotes, whitespace, encoding)
- StatusMessage - Message registry getters and type coercion
- StatusMessageException - Exception with status message keys
- JsonArrayType - JSON parsing, error handling, batch casting
- SessionTimeoutMiddleware - Session management and timeout handling
- ButterCreamPlugin - Plugin bootstrap, command discovery
# Run all tests
composer test
# Run with coverage (requires Xdebug or pcov)
vendor/bin/phpunit --coverage-html coverage/
# Run specific test file
vendor/bin/phpunit tests/TestCase/Utility/FormatTest.phpWhen adding new features or fixing bugs, please include tests. Test files should:
- Be placed in
tests/TestCase/matching the source structure - Extend
Cake\TestSuite\TestCase - Follow PHPUnit best practices
- Test both success and failure scenarios
See CONTRIBUTING.md for more details on writing tests.
- Issues: GitHub Issues
- Documentation: GitHub Wiki
Contributions are welcome! Please see CONTRIBUTING.md for detailed guidelines on:
- Reporting bugs
- Suggesting enhancements
- Submitting pull requests
- Development setup
- Coding standards
- Testing requirements
Please ensure all tests pass and code follows CakePHP standards before submitting a PR.