bale / core
Core for bale
Requires
- php: ^8.2
- illuminate/contracts: ^11.0||^12.0
- josiasmontag/laravel-recaptchav3: *
- laravel/fortify: *
- laravel/socialite: *
- league/flysystem-aws-s3-v3: *
- mallardduck/blade-lucide-icons: *
- mcamara/laravel-localization: *
- rtconner/laravel-tagging: *
- socialiteproviders/keycloak: *
- spatie/laravel-permission: *
- yadahan/laravel-authentication-log: *
Requires (Dev)
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
This package is auto-updated.
Last update: 2026-04-01 05:16:01 UTC
README
This package provides common logic for Bale CMS packages, including shared components, services, and tenant management.
Installation
composer require papa-ree/bale-core
You can publish and run the migrations with:
php artisan vendor:publish --tag="bale-core:migrations"
php artisan migrate
Migration Publisher (Recommended)
Alternatively, you can use the interactive migration publisher which provides more control:
php artisan core:publish-migration
This command allows you to:
- All: Publish all migrations.
- Auto (Only missing): Publish only migrations that don't exist yet in your application.
- Specific Migration: Select specific migrations from a list.
Error Views Publisher
You can publish the custom error views to your application:
php artisan core:publish-error
To overwrite existing files, use the --force flag:
php artisan core:publish-error --force
Analytics (Umami)
Bale Core provides a service and migration for integrating Umami Analytics (self-hosted).
Configuration
Add the following environment variables to your .env file:
UMAMI_URL=https://balystics.ponorogo.go.id UMAMI_API_KEY=your-api-key-here UMAMI_CACHE_TTL=300
Generate API Key: Dashboard Umami → Settings → API Keys → Create API Key
Table tenant_analytics
This table is located in the main database and defines which Umami website ID is linked to which Bale (tenant).
To connect a Bale to Umami, add a record to this table:
INSERT INTO tenant_analytics (id, bale_id, provider, website_id, domain, enabled) VALUES (UUID(), '<bale_uuid>', 'umami', '<umami_website_uuid>', 'domain.com', 1);
bale_id: The UUID of the tenant inbale_lists.website_id: The website UUID generated by your Umami instance.
UmamiService
This service handles authentication and fetches data from the Umami REST API.
- All API results are cached in the tenant's database for a duration specified by
UMAMI_CACHE_TTL. - Errors are logged automatically, returning
nullto ensure the application does not crash if the API is unreachable.
Shared Components
Chart Component
The x-core::chart component uses Chart.js to render various types of charts.
<x-core::chart type="line" :labels="['Jan', 'Feb', 'Mar']" :datasets="[ [ 'label' => 'Visitors', 'data' => [120, 150, 180], 'borderColor' => '#3b82f6', ] ]" />
Upload Zone Component
The x-core::upload-zone is a pure Alpine.js + Livewire drag-and-drop file upload component. It does not depend on FilePond and follows the Bale design system.
Features
- Drag-and-Drop: Visual feedback when dragging files over the zone.
- Multiple Upload: Support for selecting and uploading multiple files simultaneously.
- Client-side Validation: Instant checks for file type and size before uploading.
- Image Preview: Displays a thumbnail grid for image files.
- File Info: Shows filename, size, and upload progress status for each file.
- Livewire Integration: Built-in support for
$wire.upload()with individual progress bars. - Dark Mode: Fully styled for both light and dark themes.
Usage
In your Livewire component, ensure you use the WithFileUploads trait and define the property:
use Livewire\WithFileUploads; class MyComponent extends Component { use WithFileUploads; public $myFiles = []; // For multiple="true" // OR public $myFile; // For multiple="false" }
Then in your Blade view:
<x-core::upload-zone wire:model.live="myFiles" multiple accept="image/png,image/jpeg,application/pdf" maxSize="2048" :label="__('Drop files here or click to browse')" :hint="__('PNG, JPG, PDF up to 2MB')" class="mb-4" />
Supported Data Types
The component binds to your Livewire property using wire:model. The data type of the property depends on the multiple attribute:
| Mode | multiple |
Data Type in Livewire | Description |
|---|---|---|---|
| Single | false |
TemporaryUploadedFile |
A single file instance. |
| Multiple | true |
array<TemporaryUploadedFile> |
A collection of file instances. |
Note
All files are uploaded as instances of Livewire\Features\SupportFileUploads\TemporaryUploadedFile. You must handle the persistence logic in your component's updated hook or submit method.
Properties
| Property | Type | Default | Description |
|---|---|---|---|
wire:model |
string |
required | The Livewire property name to bind the upload. |
multiple |
boolean |
false |
Whether to allow multiple file selection and upload. |
accept |
string |
image/* |
Comma-separated list of allowed MIME types or wildcards. |
maxSize |
int |
512 |
Maximum file size allowed in Kilobytes (KB). |
label |
string |
null |
Main helper text displayed inside the drop zone. |
hint |
string |
null |
Sub-label text (e.g., "Max 512KB", "Formats: PNG, JPG"). |
class |
string |
'' |
Custom CSS classes for the component container. |
Credits
License
The MIT License (MIT).