Installation:
composer require tresorkasenda/ballstack
Publish the package assets (if needed):
php artisan vendor:publish --provider="TresorKasenda\Ballstack\BallstackServiceProvider" --tag="ballstack-assets"
First Use Case:
Use the ballstack Blade directive to create a simple stack:
@ballstack
@stack('scripts')
@stack('styles')
@endballstack
Push content to the stack:
@push('scripts')
<script src="/path/to/script.js"></script>
@endpush
Livewire Integration:
For Livewire components, use the Ballstack trait:
use TresorKasenda\Ballstack\Traits\Ballstack;
class MyComponent extends Component {
use Ballstack;
}
Push content dynamically:
public function mount() {
$this->pushToStack('scripts', '<script>console.log("Hello!");</script>');
}
Organized Asset Management:
Use named stacks (scripts, styles, modals, etc.) to group assets logically:
@push('admin-scripts')
@vite(['resources/js/admin.js'])
@endpush
Conditional Stacks: Push content conditionally based on routes, user roles, or other logic:
@if(auth()->check())
@push('scripts')
@livewireScripts
@endpush
@endif
Dynamic Content Injection: Push content from Livewire components to stacks:
public function render() {
$this->pushToStack('scripts', '<script>alert("Dynamic content loaded!");</script>');
return view('livewire.my-component');
}
Stack Management in Livewire:
Use getStack() to retrieve stack content in Livewire:
public function someMethod() {
$scripts = $this->getStack('scripts');
// Process or modify scripts as needed
}
Reactive Stacks: Use Alpine.js to manipulate stacks dynamically:
<div x-data="{ showModal: false }">
@push('modals')
<div x-show="showModal" x-transition>
<!-- Modal content -->
</div>
@endpush
</div>
Stack-Based State Management: Push Alpine.js state or event listeners to stacks:
@push('scripts')
<script>
document.addEventListener('livewire:init', () => {
Alpine.store('global', { /* state */ });
});
</script>
@endpush
Asset Pipeline:
Modular Components:
admin-layout.blade.php) that include common stacks.Livewire + Stacks:
public function mount() {
if ($this->shouldLoadScripts()) {
$this->pushToStack('scripts', $this->getComponentScripts());
}
}
Stack Ordering:
@prependToStack for priority content:
@prependToStack('scripts')
<script src="/critical-path.js"></script>
@endprependToStack
Livewire Hydration:
@livewireScripts directly in the layout instead.Alpine.js Conflicts:
Caching Issues:
php artisan view:clear
Inspect Stacks: Dump stack content to debug:
dd($this->getStack('scripts')); // In Livewire
Or in Blade:
@dump($stacks) @enddump
Stack Isolation:
Avoid naming conflicts (e.g., scripts vs. admin-scripts). Use unique names for different contexts.
Custom Stacks:
Extend the package to add custom stack behaviors. Override the BallstackServiceProvider:
public function register() {
$this->app->singleton('ballstack', function () {
return new CustomBallstackManager();
});
}
Global vs. Local Stacks:
scripts) are shared across the app.component-scripts) are scoped to specific views/components.Stack Filters: Add filters to modify stack content before rendering:
Ballstack::filter('scripts', function ($content) {
return str_replace('old-script.js', 'new-script.js', $content);
});
Custom Directives: Extend Blade directives for domain-specific stacks:
Blade::directive('adminStack', function ($stackName) {
return "<?php echo TresorKasenda\Ballstack\Facades\Ballstack::stack('{$stackName}'); ?>";
});
Usage:
@adminStack('admin-scripts')
Livewire Stack Events: Listen for stack events in Livewire:
protected $listeners = ['stackUpdated' => 'handleStackUpdate'];
public function handleStackUpdate($stackName, $content) {
// React to stack changes
}
Alpine.js Stack Management: Use Alpine.js to toggle stacks dynamically:
<div x-data="{ activeStack: 'main' }">
<template x-if="activeStack === 'main'">
@stack('main-scripts')
</template>
<template x-if="activeStack === 'admin'">
@stack('admin-scripts')
</template>
</div>
How can I help you explore Laravel packages today?