contao-components/dropzone
Contao Dropzone integration component providing drag-and-drop file uploads for Contao CMS. Bundles Dropzone assets and configuration hooks to quickly add modern upload widgets to backend or frontend forms with minimal setup.
Installation
composer require contao-components/dropzone
Add the package to your config/app.php under providers:
ContaoComponents\Dropzone\DropzoneServiceProvider::class,
Basic Blade Usage
Include the package's CSS/JS in your layout file (e.g., resources/views/layouts/app.blade.php):
@dropzoneStyles
@dropzoneScripts
First Dropzone Field In your Blade template:
{!! Dropzone::create('file-upload', [
'url' => route('upload.handler'),
'maxFilesize' => 5, // MB
'acceptedFiles' => 'image/*',
]) !!}
Backend Handler Create a route and controller to handle uploads:
Route::post('/upload', [UploadController::class, 'handle'])->name('upload.handler');
// UploadController.php
public function handle(Request $request)
{
$file = $request->file('file');
$path = $file->store('uploads');
return response()->json(['success' => true, 'path' => $path]);
}
Chain file handling logic with middleware or observers:
// app/Observers/FileUploadObserver.php
use ContaoComponents\Dropzone\Events\FileUploaded;
FileUploaded::listen(function ($event) {
$file = $event->file;
// Process (resize, validate, etc.)
$event->processed = $file->storeAs('processed/' . $file->hashName());
});
Fetch Dropzone settings from a model or database:
@php
$settings = \App\Models\UploadConfig::first();
@endphp
{!! Dropzone::create('dynamic-upload', [
'url' => $settings->endpoint,
'maxFiles' => $settings->limit,
'headers' => ['X-CSRF-TOKEN' => csrf_token()],
]) !!}
Validate files before processing:
public function handle(Request $request)
{
$validated = $request->validate([
'file.*' => 'required|image|mimes:jpeg,png|max:2048',
]);
// Process validated files...
}
Enable chunked uploads in Dropzone config:
{!! Dropzone::create('large-file-upload', [
'url' => route('chunked.upload'),
'chunking' => true,
'chunkSize' => 5 * 1024 * 1024, // 5MB chunks
]) !!}
Use a package like intervention/image for reassembly.
Customize file previews in Blade:
@dropzonePreviewTemplate
<div class="dz-preview dz-file-preview">
<div class="dz-details">
<div class="dz-filename"><span data-dz-name></span></div>
<div class="dz-size" data-dz-size></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
@if($dropzone->getOption('acceptedFiles') === 'image/*')
<div class="dz-thumbnail">
<img data-dz-thumbnail />
</div>
@endif
</div>
@enddropzonePreviewTemplate
Add Dropzone CSS/JS via Mix:
// resources/js/app.js
require('dropzone/dist/dropzone');
In webpack.mix.js:
mix.postCss('resources/css/app.css', 'public/css', [
require('postcss-import'),
require('tailwindcss'),
]);
Use Laravel’s FormRequest for complex validation:
// app/Http/Requests/UploadRequest.php
public function rules()
{
return [
'file.*' => ['required', 'dimensions:max_width=2000,max_height=2000'],
];
}
Leverage Laravel’s filesystem:
$path = Storage::disk('s3')->putFile('uploads', $file);
Trigger custom events post-upload:
event(new \App\Events\FileUploaded($file, $user));
419 (CSRF token mismatch).{!! Dropzone::create('upload', [
'headers' => ['X-CSRF-TOKEN' => csrf_token()],
]) !!}
upload_max_filesize or post_max_size may throttle large files.php.ini or use chunked uploads:
upload_max_filesize = 64M
post_max_size = 64M
// app/Http/Middleware/Cors.php
$allowedMethods = ['POST', 'OPTIONS'];
dropzone.js and dropzone.css.php artisan vendor:publish --tag=dropzone-assets
dispatch(new ProcessUpload($file))->onQueue('uploads');
Enable Dropzone debug mode:
{!! Dropzone::create('debug-upload', [
'debug' => true,
]) !!}
Check browser console for errors.
Inspect $request->all() in your handler:
dd($request->input());
Ensure the target directory is writable:
chmod -R 775 storage/app/public/uploads
Manually test the upload endpoint:
curl -X POST -F "file=@/path/to/file.jpg" http://yoursite.test/upload
Extend the base Dropzone class:
// app/Extensions/CustomDropzone.php
namespace App\Extensions;
use ContaoComponents\Dropzone\Dropzone;
class CustomDropzone extends Dropzone
{
public function __construct($elementId, array $options = [])
{
$options['autoProcessQueue'] = false;
parent::__construct($elementId, $options);
}
public function getCustomOption()
{
return $this->options['custom_key'] ?? null;
}
}
Register the extension in DropzoneServiceProvider:
$this->app->bind('dropzone', function () {
return new \App\Extensions\CustomDropzone('custom-upload');
});
Override the upload URL dynamically:
@php
$dropzone = Dropzone::create('dynamic-url', [
'url' => function () {
return route('upload', ['folder' => 'user-' . auth()->id()]);
},
]);
@endphp
Listen for Dropzone events (e.g., addedfile, success):
Dropzone.options.myDropzone = {
init: function() {
this.on("addedfile", function(file) {
console.log("File added:", file.name);
});
}
};
Add Dropzone to Mix aliases for easier imports:
// webpack.mix.js
mix.webpackConfig({
resolve: {
alias: {
dropzone: path.resolve(__dirname, 'node_modules/dropzone/dist/d
How can I help you explore Laravel packages today?