Uploads
Learn how to handle uploads in your own fields, sections and panel views
k-upload component
All uploads in the panel are handled by the k-upload
Vue component. The component takes care of opening the OS file picker for you. It can even take dropped files. It will then send the uploads to the API you specify and show file upload progress indicators in a dialog.
Handling uploads in the API
Site files
You can upload global files for the entire site to the /api/site/files
endpoint:
Page files
Files for pages must be uploaded to the particular files endpoint for each page:
Make sure to replace / with + in page IDs
You can use our internal URL builder to take care of correct page endpoint URLs:
To be honest, the naming for the url
method is a bit misleading in this context. It actually only generats the relative path for the API. I.e. pages/projects+project-a/files
It takes the page ID as first argument and makes sure to encode all slashes correctly. It then appends the second argument to the path.
User files
Uploading files for users works in a very similar way as uploading files for pages.
If you want to use our internal helper method here as well, you can write the example like this:
Custom Route
In certain scenarios, you might want to parse or modify a file, once it has been uploaded – think of a CSV upload. This can be done in a custom plugin API route.
Plugin definition
Add the API route in the index.php
of your plugin like this:
It's recommended to use a unique API endpoint path for your plugin endpoints, to avoid collissions with other routes. In this case, the endpoint will be available at https://yourdomain.com/api/your-name/uploader
Let's break down what happens within the route action:
The upload helper
API routes provide a upload
helper method, which can be used like above. The upload method automatically checks for uploaded files from the k-upload
component. For each uploaded file, the callback will be executed and the callback receives the absolute path ($source
) of the uploaded tmp file as first argument and the filename as second argument.
The upload method takes care of a few important things.
- It will handle all upload errors for you and throw translated exceptions that will be displayed by the
k-upload
component in a human-readable way. - It will make sure to return proper filenames for all uploaded files
- It will automatically handle
post_max_size
andupload_max_filesize
configuration issues and throw errors accordingly.
It can also make sure that you can only upload a single file per API call. Use the second argument of the upload method and set it to true to avoid multiple uploads.
Once the file has been uploaded, you can move it to a final location, parse it, modify it or delete it.
In our example, we will copy it to an uploads
directory.
Be aware that the upload method does not help you with additional security precausions! It's your job in a custom upload route to validate the mime type and add additional checks to avoid malicious uploads.
MIME type checks & error handling
Here's a short example that uses the MIME class to add an additional MIME type check:
This example also demonstrates how you can handle errors in the callback. Exceptions will be automatically passed forward to the k-upload
component and displayed in a nice way.
Connect your component
As a final step, we need to tell the k-upload
component where to find our new endpoint:
The additional accept
parameter helps to run the MIME type check already on the client side. It's not enough to just rely on this though. Always make sure to combine it with additional backend checks.
With multiple: false
only a single file can be selected in the file picker. Again, this needs to be combined with the second argument in the upload helper to avoid multiple uploads in the backend.
Drag & drop uploads
The k-upload
component can also be used to send dropped files to the API in the same way. Combine this with our k-dropzone
component to get a very convenient setup for drag & drop uploads. Our example from above needs to be adjusted slightly:
Instead of this.$refs.upload.open
we use the this.$refs.upload.drop
method and pass the files from the k-dropzone
drop event as first argument.