diff --git a/docs/handling-uploads-with-media-library-pro/_index.md b/docs/handling-uploads-with-media-library-pro/_index.md deleted file mode 100644 index eab8e8c63..000000000 --- a/docs/handling-uploads-with-media-library-pro/_index.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: Media Library Pro -weight: 4 ---- diff --git a/docs/handling-uploads-with-media-library-pro/creating-custom-react-components.md b/docs/handling-uploads-with-media-library-pro/creating-custom-react-components.md deleted file mode 100644 index 45dfa6077..000000000 --- a/docs/handling-uploads-with-media-library-pro/creating-custom-react-components.md +++ /dev/null @@ -1,263 +0,0 @@ ---- -title: Creating custom React components -weight: 8 ---- - -Both the Vue and React UI components are built on top of the same core, with a language-specific abstraction layer in between that exposes some helper functions. You can extend the core that the UI components are built on. This allows you to customize the UI. This page will go into detail about these abstraction layers. - -To create your own UI components that hook into the Media Library Pro JS core, you can use the `useMediaLibrary` hook in a functional component. If you are building a class component, there are several tutorials available online on how to wrap a custom hook in a higher-order component for use in class components. - -For more extensive examples, [see the pre-built UI components on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js) - -## Getting started - -```jsx -import * as React from "react"; -import { useMediaLibrary } from "media-library-pro/media-library-pro-react"; - -export default function MediaLibraryAttachment() { - const { - state, - getImgProps, - getFileInputProps, - getDropZoneProps, - removeMedia, - setOrder, - replaceMedia, - getErrors, - clearObjectErrors, - clearInvalidMedia, - isReadyToSubmit, - } = useMediaLibrary({ - initialMedia: initialValue, - validationErrors, - routePrefix, - validationRules, - multiple, - beforeUpload, - afterUpload, - onChange, - }); - - return ( -
- - - {state.media.map((object) => ( - - ))} -
- ); -} -``` - -You can find a full list of available parameters and exposed variables for the hook [at the bottom of this page](#parameters). - -## Examples - -For extensive examples you can have a look at the source of the pre-built UI components: - -- [React attachment component](https://github.com/spatie/laravel-medialibrary-pro/tree/master/resources/js/media-library-pro-react-attachment) -- [React collection component](https://github.com/spatie/laravel-medialibrary-pro/tree/master/resources/js/media-library-pro-react-collection) - -## Helper components - -When building your own UI component using the Media Library Pro, you can also make use of these helper components. These are the same components that are used in the UI components. - -### DropZone - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/DropZone.tsx) - -Renderless component that exposes some props needed to render a file dropzone. - -**props** - -```ts -{ - validationAccept?: MediaLibrary.Config["validationRules"]["accept"]; - children: ({ - hasDragObject, - isDropTarget, - }: { - hasDragObject: boolean; - isDropTarget: boolean; - isValid: boolean; - }) => React.ReactNode; - onDrop: (event: React.DragEvent) => void; -} & React.DetailedHTMLProps, HTMLDivElement>; -``` - -### HiddenFields - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/HiddenFields.tsx) - -Component that renders hidden input fields with the values of the entire MediaLibrary instance's media state. Only needed if you're planning on submitting forms traditionally (not with AJAX). - -**props** - -```ts -{ - name: string; - mediaState: MediaLibrary.State["media"]; -} -``` - -### ItemErrors - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/ItemErrors.tsx) - -Component that renders the errors for one media object. - -**props** - -```ts -{ - objectErrors: string[]; - onBack?: (e: React.MouseEvent) => void; -} -``` - -### ListErrors - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/ListErrors.tsx) - -Component that can render the MediaLibrary instance's invalid media (`mediaLibrary.state.invalidMedia`). - -**props** - -```ts -{ - invalidMedia: MediaLibrary.State["invalidMedia"]; - topLevelErrors?: Array; - onClear: () => void; -} -``` - -### Thumb - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/Thumb.tsx) - -Component to display a file's thumbnail. If no preview for the file exists, it will attempt to display its extension. Also implements the [Uploader](#uploader) component to replace files. - -**props** - -```ts -{ - uploadInfo: MediaLibrary.MediaObject["upload"]; - validationRules?: Partial; - imgProps: { - src: string | undefined; - alt: string; - extension: string | undefined; - }; - onReplace: (file: File) => void; -} -``` - -### Uploader - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/Uploader.tsx) - -Component used to upload new media objects, or to replace an existing object's file. Is used by the [Thumb](#thumb) component. - -**props** - -```ts -{ - add?: boolean; - uploadInfo?: MediaLibrary.MediaObject["upload"]; - multiple: boolean; - validationRules?: Partial; - maxItems?: number; - fileTypeHelpText?: string; - onDrop: (event: React.DragEvent) => void; - onChange: (event: React.ChangeEvent) => void; -} -``` - -### Icons - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/components/Icons.tsx) - -Component that sets svg values for the packaged icons, required if you're planning on using the [icon](#icon) component. - -### Icon - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/components/Icon.tsx) - -Renders an icon. Requires [icons](#icons) to be rendered on the page. - -**Props** - -```ts -{ - icon: string; - className?: string; -} -``` - -### IconButton - -[See code on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-react/src/components/IconButton.tsx) - -Renders a button with an icon. Requires [icons](#icons) to be rendered on the page. - -**Props** - -```ts -{ - icon: string; - className?: string; -} -``` - -**Parameters** - -```ts -handleClass?: string -``` - -## Parameters - -| parameter name | Default value | Description | -| ------------------------ | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| name | | | -| initialValue | `[]` | | -| routePrefix | `"media-library-pro"` | | -| uploadDomain | | Use this if you're uploading your files to a separate (sub)domain, e.g. `files.mydomain.com` (leave out the trailing slash) | -| validationRules | | Refer to the ["validation"](./handling-uploads-with-react#validation-rules) section | -| validationErrors | | The standard Laravel validation error object | -| maxItems | | | -| maxSizeForPreviewInBytes | | | -| translations | | Refer to the ["Translations"](./handling-uploads-with-react#translations) section | -| vapor | `false` | Set to true if you will deploy your application to Vapor, this enables uploading of the files to S3. [Read more](./handling-uploads-with-react#usage-with-laravel-vapor) | -| vaporSignedStorageUrl | `"vapor/signed-storage-url"` | | -| multiple | `true` | | -| beforeUpload | | A method that is run right before a temporary upload is started. You can throw an `Error` from this function with a custom validation message | -| afterUpload | | A method that is run right after a temporary upload has completed, `{ success: true, uuid }` | -| onChange | | | - -## Returned variables - -| variable name | Description | -| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| mediaLibrary | Ref to the MediaLibrary instance | -| state | The state of the MediaLibrary instance. Includes `media` (an array of currently added files), `invalidMedia` (files that encountered a frontend validation error) and `validationErrors` (backend validation errors mapped to uuids) | -| isReadyToSubmit | Boolean that tells whether the MediaLibrary instance is ready to submit (has no uploads in progress and has no frontend validation errors) | -| hasUploadsInProgress | Boolean that tells whether the MediaLibrary instance currently has uploads in progress | -| getImgProps | Method that expects a media object, and returns an object with props needed for an `img` tag | -| getNameInputProps | Method that expects a media object, and returns an object with props needed for an `input type=text` tag that controls an object's name attribute | -| getNameInputErrors | Method that expects a media object, and returns an array of backend validation errors for the `name` attribute | -| getCustomPropertyInputProps | Method that expects a media object, and a custom property name, and returns an object with props needed for an `input` tag that controls that custom property | -| getCustomPropertyInputErrors | Method that expects a media object, and a custom property name, and returns an array of backend validation errors for that custom property | -| getFileInputProps | Method that expects a media object, and returns an object with props needed for an `input type=file` tag that controls an object's name attribute | -| getDropZoneProps | Method that expects a media object, and returns an object with props needed for a file dropzone (`onDrop`) | -| addFile | Method that allows a user to pass in a File to be added to the MediaLibrary instance's media state | -| removeMedia | Method that expects a media object, and removes it from the MediaLibrary instance's media state | -| setOrder | Method that expects an array of uuids, and sets the `order` attribute of the media objects in the media state | -| setProperty | Method that expects a media object, a key (`client_preview`, `attributes.preview_url`, `attributes.size`, `attributes.extension` …), and a value, and sets this property on the media object. This method usually shouldn't be used outside of the core | -| setCustomProperty | Method that expects a media object, a custom property key (`tags`, `caption`, `alt` …), and a value, and sets this property on the media object | -| replaceMedia | Method that expects a media object and a File, and uploads this file and replaces it on the media object | -| getErrors | Method that expects a media object, and returns an array of errors that it may have encountered | -| clearObjectErrors | Method that expects a media object, and clears its errors | -| clearInvalidMedia | Method that clears the MediaLibrary instance's invalidMedia state | diff --git a/docs/handling-uploads-with-media-library-pro/creating-custom-vue-components.md b/docs/handling-uploads-with-media-library-pro/creating-custom-vue-components.md deleted file mode 100644 index 58a070c84..000000000 --- a/docs/handling-uploads-with-media-library-pro/creating-custom-vue-components.md +++ /dev/null @@ -1,270 +0,0 @@ ---- -title: Creating custom Vue components -weight: 7 ---- - -Both the Vue and UI components are built on top of the same core, with a language-specific abstraction layer in between that exposes some helper functions. You can extend the core that the UI components are built on. This allows you to customize the UI. This page will go into detail about these abstraction layers. - -The Vue implementation uses a renderless component that exposes all the functions and values through a slot scope. - -For more extensive examples, [see the pre-built UI components on GitHub](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js) - -## Getting started - -```html - - - -``` - -In Vue 3, you would use the new `v-slot` attribute instead of `slot-scope`: - -```html -v-slot="{ state, getImgProps, … }" -``` - -You can find a full list of available props for the renderless component [at the bottom of this page](#props). - -## Examples - -For extensive examples you can have a look at the source of the pre-built UI components: - -- [Vue 3 attachment component](https://github.com/spatie/laravel-medialibrary-pro/tree/master/resources/js/media-library-pro-vue3-attachment) -- [Vue 3 collection component](https://github.com/spatie/laravel-medialibrary-pro/tree/master/resources/js/media-library-pro-vue3-collection) - -## Helper components - -When building your own UI component using the Media Library Pro, you can also make use of these helper components. These are the same components that are used in the UI components. - -### DropZone - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/DropZone.vue) - -Renderless component that exposes some props needed to render a file dropzone. Has a scoped slot that exposes `hasDragObject`, `isDropTarget` and `isValid`. - -Emits `@clicked` and `@dropped`. - -**props** - -```js -props: { - validationAccept: { default: () => [], type: Array }, -}, -``` - -### HiddenFields - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/HiddenFields.vue) - -Component that renders hidden input fields with the values of the entire MediaLibrary instance's media state. Only needed if you're planning on submitting forms traditionally (not with AJAX). - -**props** - -```js -props: { - name: { required: true, type: String }, - mediaState: { default: () => [], type: Array }, -}, -``` - -### ItemErrors - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/ItemErrors.vue) - -Component that renders the errors for one media object. - -Emits `@back`. - -**props** - -```js -props: { - objectErrors: { required: true, type: Array }, -}, -``` - -### ListErrors - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/listErrors/ListErrors.vue) - -Component that can render the MediaLibrary instance's invalid media (`mediaLibrary.state.invalidMedia`). - -Emits `@cleared`. - -**props** - -```js -props: { - invalidMedia: { default: () => ({}), type: Array }, - topLevelErrors: { default: () => [], type: Array }, -}, -``` - -### Thumb - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/Thumb.vue) - -Component to display a file's thumbnail. If no preview for the file exists, it will attempt to display its extension. Also implements the [Uploader](#uploader) component to replace files. - -Emits `@replaced`. - -**props** - -```js -props: { - uploadInfo: { required: true, type: Object }, - validationRules: { required: false, type: Object }, - imgProps: { required: true, type: Object }, -}, -``` - -### Uploader - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/Uploader.vue) - -Component used to upload new media objects, or to replace an existing object's file. Is used by the [Thumb](#thumb) component. - -Emits `@changed` and `@dropped`. - -**props** - -```js -props: { - add: { default: true, type: Boolean }, - uploadInfo: { required: false, type: Object }, - multiple: { default: false, type: Boolean }, - validationRules: { required: false, type: Object }, - maxItems: { required: false, type: Number }, - fileTypeHelpText: { required: false, type: String }, -}, -``` - -### Icons - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/components/Icons.vue) - -Component that sets svg values for the packaged icons, required if you're planning on using the [icon](#icon) component. - -### Icon - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/components/Icon.vue) - -Renders an icon. Requires [icons](#icons) to be rendered on the page. - -**Props** - -```js -props: { - icon: { required: true, type: String }, -}, -``` - -### IconButton - -See code on GitHub: [Vue 3](https://github.com/spatie/laravel-medialibrary-pro/blob/master/resources/js/media-library-pro-vue3/src/components/IconButton.vue) - -Renders a button with an icon. Requires [icons](#icons) to be rendered on the page. - -**Props** - -```js -props: { - icon: { required: true, type: String }, -}, -``` - -**Parameters** - -```js -handleClass?: string -``` - -## Props - -| prop name | Default value | Description | -| ------------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | | | -| initial-value | `[]` | | -| route-prefix | `"media-library-pro"` | | -| upload-domain | | Use this if you're uploading your files to a separate (sub)domain, e.g. `files.mydomain.com` (leave out the trailing slash) | -| validation-rules | | Refer to the ["validation"](./handling-uploads-with-vue#validation-rules) section | -| validation-errors | | The standard Laravel validation error object | -| max-items | | | -| max-size-for-preview-in-bytes | | | -| translations | | Refer to the ["Translations"](./handling-uploads-with-vue#translations) section | -| vapor | `false` | Set to true if you will deploy your application to Vapor, this enables uploading of the files to S3. [Read more](./handling-uploads-with-vue#usage-with-laravel-vapor) | -| vapor-signed-storage-url | `"vapor/signed-storage-url"` | | -| multiple | `true` | | -| before-upload | | A method that is run right before a temporary upload is started. You can throw an `Error` from this function with a custom validation message | -| after-upload | | A method that is run right after a temporary upload has completed, `{ success: true, uuid }` | -| @change | | | -| @is-ready-to-submit-change | | Emits a boolean that tells whether the MediaLibrary instance is ready to submit (has no uploads in progress and has no frontend validation errors) | -| @has-uploads-in-progress-change | | Emits a boolean that tells whether the MediaLibrary instance currently has uploads in progress | - -## Returned parameters in scoped slot - -| variable name | Description | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| mediaLibrary | Ref to the MediaLibrary instance | -| state | The state of the MediaLibrary instance. Includes `media` (an array of currently added files), `invalidMedia` (files that encountered a frontend validation error) and `validationErrors` (backend validation errors mapped to uuids) | -| isReadyToSubmit | Boolean that tells whether the MediaLibrary instance is ready to submit (has no uploads in progress and has no frontend validation errors) | -| hasUploadsInProgress | Boolean that tells whether the MediaLibrary instance currently has uploads in progress | -| getImgProps | Method that expects a media object, and returns an object with props needed for an `img` tag | -| getNameInputProps | Method that expects a media object, and returns an object with props needed for an `input type=text` tag that controls an object's name attribute | -| getNameInputListeners | Method that expects a media object, and returns an object with listeners needed for an `input type=text` tag that controls an object's name attribute | -| getNameInputErrors | Method that expects a media object, and returns an array of backend validation errors for the `name` attribute | -| getCustomPropertyInputProps | Method that expects a media object and a custom property name, and returns an object with props needed for an `input` tag that controls that custom property | -| getCustomPropertyInputListeners | Method that expects a media object and a custom property name, and returns an object with listeners needed for an `input` tag that controls that custom property | -| getCustomPropertyInputErrors | Method that expects a media object and a custom property name, and returns an array of backend validation errors for that custom property | -| getFileInputProps | Method that expects a media object, and returns an object with props needed for an `input type=file` tag that controls an object's name attribute | -| getFileInputListeners | Method that expects a media object, and returns an object with listeners needed for an `input type=file` tag that controls an object's name attribute | -| getDropZoneProps | Method that expects a media object, and returns an object with props needed for a file dropzone (`validationRules` and `maxItems`) | -| getDropZoneListeners | Method that expects a media object, and returns an object with listeners needed for a file dropzone (`@drop`) | -| addFile | Method that allows a user to pass in an array of files to be added to the MediaLibrary instance's media state | -| addFile | Method that allows a user to pass in a File to be added to the MediaLibrary instance's media state | -| removeMedia | Method that expects a media object, and removes it from the MediaLibrary instance's media state | -| setOrder | Method that expects an array of uuids, and sets the `order` attribute of the media objects in the media state | -| setProperty | Method that expects a media object, a key (`client_preview`, `attributes.preview_url`, `attributes.size`, `attributes.extension` …), and a value, and sets this property on the media object. This method usually shouldn't be used outside of the core | -| setCustomProperty | Method that expects a media object, a custom property key (`tags`, `caption`, `alt` …), and a value, and sets this property on the media object | -| replaceMedia | Method that expects a media object and a File, and uploads this file and replaces it on the media object | -| getErrors | Method that expects a media object, and returns an array of errors that it may have encountered | -| clearObjectErrors | Method that expects a media object, and clears its errors | -| clearInvalidMedia | Method that clears the MediaLibrary instance's invalidMedia state | diff --git a/docs/handling-uploads-with-media-library-pro/customise.md b/docs/handling-uploads-with-media-library-pro/customise.md deleted file mode 100644 index 8dcfeab9b..000000000 --- a/docs/handling-uploads-with-media-library-pro/customise.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Customise -weight: 2 ---- - -## Only allow authenticated users to upload files - -If in your project, you only want authenticated users to upload files, you can put the macro in a group that applies authentication middleware. - -```php -Route::middleware('auth')->group(function() { - Route::mediaLibrary(); -}); -``` - -We highly encourage you to do this, if you only need authenticated users to upload files. - -## Configure allowed mime types - -For security purposes, only files that pass [Laravel's `mimes` validation](https://laravel.com/docs/master/validation#rule-mimetypes) with the extensions [mentioned in this class](https://github.com/spatie/laravel-medialibrary-pro/blob/ba6eedd5b2a7f743909b441c0b6fd111d1a73794/src/Support/DefaultAllowedExtensions.php#L5) are allowed by the temporary upload controllers. - -If you want your components to accept other mimetypes, add a key `temporary_uploads_allowed_extensions` in the `media-library.php` config file. - -```php -// in config/medialibrary.php - -return [ - // ... - - 'temporary_uploads_allowed_extensions' => [ - // your extensions - ... \Spatie\MediaLibraryPro\Support\DefaultAllowedExtensions::all(), // add this if you want to allow the default ones too - ], -], -] -``` - -## Rate limiting - -To protect you from users that upload too many files, the temporary uploads controllers are rate limited. By default, only 10 files can be upload per minute per ip iddress. - -To customize rate limiting, add [a rate limiter](https://laravel.com/docs/master/rate-limiting#introduction) named `medialibrary-pro-uploads`. Typically, this would be done in a service provider. - -Here's an example where's we'll allow 15 files: - -```php -// in a service provider - -use Illuminate\Support\Facades\RateLimiter; - -RateLimiter::for('medialibrary-pro-uploads', function (Request $request) { - return [ - Limit::perMinute(10)->by($request->ip()), - ]; -}); -``` - diff --git a/docs/handling-uploads-with-media-library-pro/customizing-css.md b/docs/handling-uploads-with-media-library-pro/customizing-css.md deleted file mode 100644 index c95957244..000000000 --- a/docs/handling-uploads-with-media-library-pro/customizing-css.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Customizing CSS -weight: 9 ---- - -If you want to change the look of the Media Library Pro components to match the style of your own app, you have multiple options. - -## Are you a visual learner? - -In this video, you'll see the various option on how to customize the look and feel of the components. - - - -Want to see more videos like this? Check out our [free video course on how to use Laravel Media Library](https://spatie.be/courses/discovering-laravel-media-library). - -### Option 1: Use your own Tailwind CSS configuration - -Instead of importing/linking the pre-built `dist/styles.css` from the package, you can import the `src/styles.css` and run every `@apply` rule through your own `tailwind.config.js`. - -```css -/* app.css */ - -@import "tailwindcss/base"; -@import "tailwindcss/components"; -@import "tailwindcss/utilities"; - -@import "../../vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-styles/src/styles.css"; -… -``` - -This is exactly what happens in the header of the homepage at [medialibrary.pro](https://medialibrary.pro): the shown component has a slightly blue-ish look, using the color palette of this site. - -### Option 2: Override only portions in your CSS - -If you only want to tinker with certain aspects of the component but like to keep the CSS in sync with future package updates, nothing stops you from overriding only certain CSS rules with your own tweaks. Every DOM-element of the component has a class with prefix `media-library`. - -Let's say your thumbs aren't square and you want to show them in their original aspect ratio. -Inspect the component in your browser to find out that the thumbnail is rendered in the DOM element with class `media-library-thumb-img`. Next, write some extra CSS for this class: - -```css -/* app.css */ - -… - -@import "src/styles.css"; - -.media-library-thumb-img { - @apply object-contain; -} - -``` - -### Option 3: Copy the CSS to your own project - -If you want to go full-option, you can always copy `src/styles.css` to your own project and go wild. -In this example we renamed the file to `custom/media-library.css`. -Beware: you will have to manually keep this CSS in sync with changes in future package updates. - -```css -/* app.css */ - -… - -@import "custom/media-library.css"; -``` - -One of the many changes we like to do, is detaching the error list at the top and give it rounded corners: - -```css -/* custom/media-library.css */ - -… - -.media-library-listerrors { - … - @apply mb-6; - @apply rounded-lg; - … -} -``` - -This is what we've done on the Customized Collection demo on [medialibrary.pro/demo-customized-collection](http://medialibrary.pro/demo-customized-collection). Pick a file that is too big to see the error list in effect. - -## PurgeCSS - -If you're using PurgeCSS, you might have to add a rule to your whitelist patterns. - -```js -mix.purgeCss({ whitelistPatterns: [/^media-library/] }); -``` - -## Changing the order of the sections - -The components have three major sections that are rendered in this order: the validation errors, the items and the uploader. - -![Screenshot of component](/docs/laravel-medialibrary/v11/images/pro/sections.png) - -You can change the order of these sections to be more consistent with your app, without having to create a custom component from scratch. - -Add the following lines to your CSS, and switch the order of the sections around to your liking. - -```css -.media-library { - grid-template-areas: - "uploader" - "items" - "errors"; -} -``` - -![Screenshot of component with sections in different order](/docs/laravel-medialibrary/v11/images/pro/sections-order-switched.png) diff --git a/docs/handling-uploads-with-media-library-pro/getting-started.md b/docs/handling-uploads-with-media-library-pro/getting-started.md deleted file mode 100644 index 9de51fc6b..000000000 --- a/docs/handling-uploads-with-media-library-pro/getting-started.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Getting started -weight: 2 ---- - -Things to do to get started: - -- Get a license -- Install the package -- Configure your frontend diff --git a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-2.md b/docs/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-2.md deleted file mode 100644 index 13cf2e65a..000000000 --- a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-2.md +++ /dev/null @@ -1,375 +0,0 @@ ---- -title: Handling uploads with Livewire 2 -weight: 4 ---- - -Media Library Pro v2 is compatible with Livewire v2. - -You can make use of the `x-media-library-attachment` and `x-media-library-collection` inside of the views of your own Livewire components. - -## Getting started - -Make sure to have followed [Livewire's installation instructions](https://livewire.laravel.com). - -Make sure Alpine is available on the page as well. The easiest way is to include it from a CDN: - -```html - -``` - -Visit [the Alpine repo](https://github.com/alpinejs/alpine) for more installation options. - -## Demo application - -In [the v2 btranch of this repo on GitHub](https://github.com/spatie/laravel-medialibrary-pro-app/tree/v2), you'll find a demo Laravel application in which you'll find examples of how to use Media Library Pro inside your Livewire components. - -If you are having troubles using the components, take a look in that app to see how we've done it. - -## Handling a single upload - -You can use `x-media-library-attachment` component to upload a single file. - -![Screenshot of the attachment component](/docs/laravel-medialibrary/v11/images/pro/attachment.png) - -Here's how that might look like in the view of your Livewire component: - -```html -
- - - - - - - -``` - -In your Livewire component you must: -- use the `Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia` trait -- add a public property `$mediaComponentNames` array that contains all the names of media library pro components that you are going to use. -- for each component that you are going to use you should add a public property with the name you use in the view for that component (in the example above: `myUpload`) - -Here is an example component: - -```php -namespace App\Http\Livewire; - -use App\Models\YourModel; -use Livewire\Component; -use Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia; - -class MyForm extends Component -{ - use WithMedia; - - public $name; - - public $message = ''; - - public $mediaComponentNames = ['myUpload']; - - public $myUpload; - - public function submit() - { - $formSubmission = YourModel::create([ - 'name' => $this->name, - ]); - - $formSubmission - ->addFromMediaLibraryRequest($this->myUpload) - ->toMediaCollection('images'); - - $this->message = 'Your form has been submitted'; - - $this->name = ''; - $this->clearMedia(); - } - - public function render() - { - return view('livewire.my-form'); - } -} -``` - -Immediately after a file has been uploaded it will be stored as a temporary upload. In the method that handles the form submission you must use the `addFromMediaLibraryRequest` method to move the uploaded file to the model you want. - -To clear out an uploaded file from being displayed, you can call `clearMedia()`. This method will only clear the uploaded file from view, uploaded files will not be deleted. - -If you are using multiple attachment components and only want to clear out specific ones, pass the name of the component to `clearMedia`. - -```php -$this->clearMedia('myUpload') -``` - -### Validating a single upload - -You can pass any Laravel validation rule to the rules prop of the `x-media-library-attachment` component. Here's an example where only `jpeg` and `png` will be accepted. - -```html - -``` - -You can make the upload required by validating it in your Livewire component: - -```php -// in the method that handles the form submission inside your livewire component - -public function submit() -{ - $this->validate([ - 'myUpload' => 'required', - ]); - - // process the form submission -} -``` - -## Handling multiple uploads - -Uploading multiple files is very similar to uploading a single file. The only thing you need to add to the `x-medialibrary-attachment` in the view is `multiple`. - -```html -
- - - - - - - -``` - -![Screenshot of the attachment component](/docs/laravel-medialibrary/v11/images/pro/multiple.png) - -In your Livewire component you must: -- use the `Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia` trait -- add a public property `$mediaComponentNames` that contains all the names of media library pro components that you are going to use. -- for each component that you are going to use you should add a public property with the name you use in the view for that component (in the example above: `myUpload`) - -Here is an example component: - -```php -namespace App\Http\Livewire; - -use App\Models\YourModel; -use Livewire\Component; -use Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia; - -class MyForm extends Component -{ - use WithMedia; - - public $name; - - public $message = ''; - - public $mediaComponentNames = ['images']; - - public $images; - - public function submit() - { - $formSubmission = YourModel::create([ - 'name' => $this->name, - ]); - - $formSubmission - ->addFromMediaLibraryRequest($this->images) - ->toMediaCollection('images'); - - $this->message = 'Your form has been submitted'; - - $this->name = ''; - - $this->clearMedia(); - } - - public function render() - { - return view('livewire.my-form'); - } -} -``` - -### Validating multiple uploads - -You can pass any Laravel validation rule to the rules prop of the `x-media-library-attachment` component. Here's an example where only `jpeg` and `png` will be accepted. - -```html - -``` - -You can make the upload required by validating it in your Livewire component. Here's an example where at least one upload is required, but more than three uploads are not allowed. - -```php -// in the method that handles the form submission inside your livewire component - -public function submit() -{ - $this->validate([ - 'images' => 'required|max:3', - ]); - - // process the form submission -} -``` - -## Administer the contents of a media library collection - -You can manage the entire contents of a media library collection with `x-media-library-collection` component. This -component is intended for use in admin sections. - -Here is an example where we are going to administer an `images` collection of a `$blogPost` model. We assume that you -already [prepared the model](/docs/laravel-medialibrary/v11/basic-usage/preparing-your-model) to handle uploads. - -```html -
- - - - - - - -``` - -In your Livewire component you must: -- use the `Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia` trait -- add a public property `$mediaComponentNames` array that contains all the names of media library pro components that you are going to use. -- for each component that you are going to use you should add a public property with the name you use in the view for that component (in the example above: `myUpload`) - -Here is an example component: - -```php -namespace App\Http\Livewire; - -use App\Models\BlogPost; -use Livewire\Component; -use Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia; - -class MyForm extends Component -{ - use WithMedia; - - public $name; - - public $message = ''; - - public $mediaComponentNames = ['images']; - - public $images; - - public function submit() - { - $formSubmission = BlogPost::create([ - 'name' => $this->name, - ]); - - $formSubmission - ->addFromMediaLibraryRequest($this->images) - ->toMediaCollection('images'); - - $this->message = 'Your form has been submitted'; - } - - public function render() - { - return view('livewire.my-form'); - } -} -``` - -### Validating the collection - -You can pass any Laravel validation rule to the rules prop of the `x-media-library-collection` component. Here's an example where only `jpeg` and `png` will be accepted. - -```html - -``` - -You can make the upload required by validating it in your Livewire component. Here's an example where at least one upload is required, but more than three uploads are not allowed. - -```php -// in the method that handles the form submission inside your livewire component - -public function submit() -{ - $this->validate([ - 'images' => 'required|max:3', - ]); - - // process the form submission -} -``` - -### Using custom properties - -Media library supports [custom properties](/docs/laravel-medialibrary/v11/advanced-usage/using-custom-properties) to be saved on a media item. By -default, the `x-media-library-collection` component doesn't show the custom properties. To add them you should create a -blade view that will be used to display all form elements on a row in the component. - -In this example we're going to add a custom property form field called `extra_field`. - -```html -@include('medialibrary::livewire.partials.collection.fields') - -
- - livewireCustomPropertyAttributes('extra_field') }} - /> - - @error($mediaItem->customPropertyErrorName('extra_field')) - - {{ $message }} - - @enderror -
-``` - -You should then pass the path to that view to the `fields-view` prop of the `x-media-library-collection` component. - -```html - -``` - -This is how that will look like. - -![Screenshot of custom property](/docs/laravel-medialibrary/v11/images/pro/extra.png) - -In your Livewire component, you can validate the custom properties like this. This example assumes that you have set the `name` attribute of `x-media-library-collection` to `images`. - -```php -// inside the method in your Livewire component that handles the form submission -public function submit() -{ - $this->validate([ - 'images.*.custom_properties.extra_field' => 'required', - ], ['required' => 'This field is required']); - - // process the form submission -} -``` - -## Uploading directly to S3 - -Currently, Livewire does not support uploading multiple files to S3. That's why only the `attachment` component can be used to upload files to S3. - -To get started with uploading files to `s3`, make sure to follow Livewire's instructions on [how to upload directly to S3](https://laravel-livewire.com/docs/2.x/file-uploads#upload-to-s3). - -Next, make sure you have configured the media disk that uses the S3 driver. - -With that configuration in place, the `attachment` component will now upload directly to S3. diff --git a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-3.md b/docs/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-3.md deleted file mode 100644 index ffce46948..000000000 --- a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-3.md +++ /dev/null @@ -1,362 +0,0 @@ ---- -title: Handling uploads with Livewire 3 -weight: 5 ---- - -Media Library Pro v3 is compatible with Livewire v3. - -You can make use of the `livewire:media-library` Livewire component inside of the views of your own Livewire components. - -## Getting started - -Make sure to have followed [Livewire's installation instructions](https://livewire.laravel.com). - -You must add `@mediaLibraryStyles` before the closing `` tag of your layout file. - -## Demo application - -In [this repo on GitHub](https://github.com/spatie/laravel-medialibrary-pro-app), you'll find a demo Laravel application in which you'll find examples of how to use Media Library Pro inside your Livewire components. - -If you are having trouble using the components, take a look in that app to see how we've done it. - -## Handling a single upload - -You can use `livewire:media-library` component to upload a single file. - -![Screenshot of the attachment component](/docs/laravel-medialibrary/v11/images/pro/attachment.png) - -Here's how that might look like in the view of your Livewire component: - -```html -
- - - - - - - -``` - -In your Livewire component you must: -- use the `Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia` trait -- add a public property that defaults to an empty array for binding the media library component to (in the example above: `myUpload`, of course you can use any name you want) -- for each component that you are going to use you should add a public property with the name you use in the view for that component (in the example above: `myUpload`) - -Here is an example component: - -```php -namespace App\Http\Livewire; - -use App\Models\YourModel; -use Livewire\Component; -use Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia; - -class MyForm extends Component -{ - use WithMedia; - - public $name; - - public $message = ''; - - public $myUpload = []; - - public function submit() - { - $formSubmission = YourModel::create([ - 'name' => $this->name, - ]); - - $formSubmission - ->addFromMediaLibraryRequest($this->myUpload) - ->toMediaCollection('images'); - - $this->message = 'Your form has been submitted'; - - $this->name = ''; - $this->myUpload = null; - } - - public function render() - { - return view('livewire.my-form'); - } -} -``` - -Immediately after a file has been uploaded it will be stored as a temporary upload. In the method that handles the form submission you must use the `addFromMediaLibraryRequest` method to move the uploaded file to the model you want. - -To clear out an uploaded file from being displayed, you can set bound property `myUpload` to `null`. This will only clear the uploaded file from view, uploaded files will not be deleted. - -### Validating a single upload - -You can pass any Laravel validation rule to the rules prop of the `livewire:media-library` component. Here's an example where only `jpeg` and `png` will be accepted. - -```html - -``` - -You can make the upload required by validating it in your Livewire component: - -```php -// in the method that handles the form submission inside your livewire component - -public function submit() -{ - $this->validate([ - 'myUpload' => 'required', - ]); - - // process the form submission -} -``` - -## Handling multiple uploads - -Uploading multiple files is very similar to uploading a single file. The only thing you need to add is a `multiple` property - -```html -
- - - - - - - -``` - -![Screenshot of the attachment component](/docs/laravel-medialibrary/v11/images/pro/multiple.png) - -In your Livewire component you must: -- use the `Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia` trait -- add a public property `$images` that we can bind the uploads to - - -Here is an example component: - -```php -namespace App\Http\Livewire; - -use App\Models\YourModel; -use Livewire\Component; -use Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia; - -class MyForm extends Component -{ - use WithMedia; - - public $name; - - public $message = ''; - - public $images = []; - - public function submit() - { - $formSubmission = YourModel::create([ - 'name' => $this->name, - ]); - - $formSubmission - ->addFromMediaLibraryRequest($this->images) - ->toMediaCollection('images'); - - $this->message = 'Your form has been submitted'; - - $this->name = ''; - - $this->images = []; - } - - public function render() - { - return view('livewire.my-form'); - } -} -``` - -### Validating multiple uploads - -You can pass any Laravel validation rule to the rules prop of the `livewire:media-library` component. Here's an example where only `jpeg` and `png` will be accepted. - -```html - -``` - -You can make the upload required by validating it in your Livewire component. Here's an example where at least one upload is required, but more than three uploads are not allowed. - -```php -// in the method that handles the form submission inside your Livewire component - -public function submit() -{ - $this->validate([ - 'images' => 'required|max:3', - ]); - - // process the form submission -} -``` - -## Administer the contents of a media library collection - -You can manage the entire contents of a media library collection with `livewire:media-library` component. This -component is intended for use in admin sections. - -Here is an example where we are going to administer an `images` collection of a `$blogPost` model. We assume that you -already [prepared the model](/docs/laravel-medialibrary/v11/basic-usage/preparing-your-model) to handle uploads. - -```html -
- - - - - - - -``` - -In your Livewire component you must: -- use the `Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia` trait -- add a public property `$images` that we can bind to upload to (you can use any name you want) -- pass the Eloquent model that the collection is saved on to the component, in this case `$blogPost` - -Here is an example component: - -```php -namespace App\Http\Livewire; - -use App\Models\BlogPost; -use Livewire\Component; -use Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia; - -class MyForm extends Component -{ - use WithMedia; - - public $name; - - public $message = ''; - - public $images; - - public $blogPost; - - public function mount() - { - $this->blogPost = BlogPost::first(); - } - - public function submit() - { - $this->blogPost->update(['name' => $this->name]); - - $this->blogPost - ->addFromMediaLibraryRequest($this->images) - ->toMediaCollection('images'); - - $this->message = 'Your form has been submitted'; - } - - public function render() - { - return view('livewire.my-form'); - } -} -``` - -### Validating the collection - -You can pass any Laravel validation rule to the rules prop of the `livewire:media-library` component. Here's an example where only `jpeg` and `png` will be accepted. - -```html - -``` - -You can make the upload required by validating it in your Livewire component. Here's an example where at least one upload is required, but more than three uploads are not allowed. - -```php -// in the method that handles the form submission inside your livewire component - -public function submit() -{ - $this->validate([ - 'images' => 'required|max:3', - ]); - - // process the form submission -} -``` - -### Using custom properties - -Media library supports [custom properties](/docs/laravel-medialibrary/v11/advanced-usage/using-custom-properties) to be saved on a media item. By -default, the `livewire:media-library` component doesn't show the custom properties. To add them you should create a -blade view that will be used to display all form elements on a row in the component. - -In this example we're going to add a custom property form field called `extra_field`. - -```html -@include('medialibrary::livewire.partials.collection.fields') - -
- - livewireCustomPropertyAttributes('extra_field') }} - /> - - @error($mediaItem->customPropertyErrorName('extra_field')) - - {{ $message }} - - @enderror -
-``` - -You should then pass the path to that view to the `fields-view` prop of the `livewire:media-library` component. - -```html - -``` - -This is how that will look like. - -![Screenshot of custom property](/docs/laravel-medialibrary/v11/images/pro/extra.png) - -In your Livewire component, you can validate the custom properties like this. This example assumes that you have set the `name` attribute of `livewire:media-library` to `images`. - -```php -// inside the method in your Livewire component that handles the form submission -public function submit() -{ - $this->validate([ - 'images.*.custom_properties.extra_field' => 'required', - ], ['required' => 'This field is required']); - - // process the form submission -} -``` - -## Uploading directly to S3 - -Currently, Livewire does not support uploading multiple files to S3. That's why only the `attachment` component can be used to upload files to S3. - -To get started with uploading files to `s3`, make sure to follow Livewire's instructions on [how to upload directly to S3](https://livewire.laravel.com/docs/uploads#storing-uploaded-files). - -Next, make sure you have configured the media disk that uses the S3 driver. - -With that configuration in place, the `livewire:media-library` component will now upload directly to S3. diff --git a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-react.md b/docs/handling-uploads-with-media-library-pro/handling-uploads-with-react.md deleted file mode 100644 index abf6b1c89..000000000 --- a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-react.md +++ /dev/null @@ -1,484 +0,0 @@ ---- -title: Handling uploads with React -weight: 7 ---- - -Media Library Pro provides beautiful UI components for React. They pack a lot of features: temporary uploads, custom property inputs, frontend validation, and robust error handling. - -The `MediaLibraryAttachment` component can upload one or more files with little or no extra information. The attachment component is a lightweight solution for small bits of UI like avatar fields. - -![Screenshot of the MediaLibraryAttachment React component](/docs/laravel-medialibrary/v11/images/pro/attachment.png) - -The `MediaLibraryCollection` component can upload multiple files with custom properties. The collection component shines when you need to manage media, like in backoffices. - -![Screenshot of the MediaLibraryCollection React component](/docs/laravel-medialibrary/v11/images/pro/collection.png) - -If neither of these fit the bill, we've exposed a set of APIs for you to be bold and [roll your own components](./creating-custom-react-components). - -## Demo application - -In [this repo on GitHub](https://github.com/spatie/laravel-medialibrary-pro-app), you'll find a demo Laravel application in which you'll find examples of how to use Media Library Pro with React. - -If you are having troubles using the components, take a look in that app to see how we've done it. - -## Basic setup - -First, the server needs to be able to catch your incoming uploads. Use the `mediaLibrary` macro in your routes file. - -```php -// Probably routes/web.php -Route::mediaLibrary(); -``` - -The macro will register a route on `/media-library-pro/uploads`, which is used by the Vue components by default. You can change the prefix by passing it to the macro: - -```php -// Probably routes/web.php -Route::mediaLibrary('my-custom-url'); -``` - -This will register a route at `/my-custom-url/uploads` instead. - -### Customizing the upload endpoint - -The React components post data to `/media-library-pro/uploads` by default. If you registered the controller on a different URL, pass it to the `routePrefix` prop of your React components. - -```jsx - -``` - -### Importing the components - -_If you're developing a project where you don't have access to composer, you can download the package through GitHub Packages: [installation steps](./installation#usage-in-a-frontend-repository). [Read this for usage in Next.js](#usage-in-nextjs)_ - -The components are located in `vendor/spatie/laravel-medialibrary-pro/resources/js` when you install the package through Composer. This makes for very long import statements, which you can clean up by adding some configuration to your Webpack/Laravel Mix configuration. - -## Setup Vite -If you are using Vite, your `vite.config.js` look something like this: - -```js -import { defineConfig } from 'vite'; -import laravel from 'laravel-vite-plugin'; -import vue from '@vitejs/plugin-vue'; - -export default defineConfig({ - resolve: { - alias: { - 'media-library-pro-react-attachment': '/vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-react-attachment', - 'media-library-pro-react-collection': '/vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-react-collection', - } - }, - plugins: [ - laravel([ - 'resources/js/app.js', - ]), - vue({ - template: { - transformAssetUrls: { - base: null, - includeAbsolute: false, - }, - }, - }), - ], -}); - -``` - -If you're using TypeScript, you will also have have to add this to your tsconfig: - -```json -// tsconfig.json - -{ - "compilerOptions": { - "paths": { - "*": ["*", "vendor/spatie/laravel-medialibrary-pro/resources/js/*"] - } - } -} -``` - -## Your first components - -The most basic components have a `name` prop. This name will be used to identify the media when it's uploaded to the server. - -```jsx -// MyImageUploader.jsx - -import { MediaLibraryAttachment } from "media-library-pro-react-attachment"; -import { MediaLibraryCollection } from "media-library-pro-react-collection"; - -export default function MyImageUploader() { - return ( -
- - - - - - ); -} -``` - -### Passing an initial value - -If your form modifies an existing set of media, you may pass it through in the `initialValue` prop. - -You can retrieve your initial values in Laravel using `$yourModel->getMedia($collectionName);`, this will also take care of any `old` values after an invalid form submit. - -```jsx -
- - - - - -``` - -Under the hood, these components create hidden `` fields to keep track of the form values on submit. If you would like to submit your values asynchronously, refer to the [Asynchronously submit data](#asynchronously-submit-data) section. - -### Setting validation rules - -You'll probably want to validate what gets uploaded. Use the `validationRules` prop, and don't forget to pass Laravel's validation errors too. The validation errors returned from the server will find errors under the key used in your `name` prop. - -```jsx -
- - - - - - -``` - -You can also set the maximum amount of images that users can be uploaded using the `max-items` prop. Don't forget to set the `multiple` prop for the attachment component. - -```jsx -
- - - - - -``` - -See the [Validation rules section](#validation-rules) for a complete list of all possible validation rules. - -### Checking the upload state - -The components keep track of whether they're ready to be submitted, you can use this to disable a submit button while a file is still uploading or when there are frontend validation errors. This value can be tracked by passing a listener method to the `onIsReadyToSubmitChange` prop. If you submit a form while a file is uploading, Laravel will return a HTTP 500 error with an `invalid uuid` message. - -```jsx -import { MediaLibraryAttachment } from "media-library-pro-react-attachment"; - -function AvatarComponent() { - const [isReadyToSubmit, setIsReadyToSubmit] = useState(true); - - return( - - - - ) -} -``` - -### Using custom properties - -The Media Library supports [custom properties](/docs/laravel-medialibrary/v11/advanced-usage/using-custom-properties) to be saved on a media item. The values for these can be chosen by your users. By default, the `MediaLibraryAttachment` component doesn't show any input fields, and the `MediaLibraryCollection` component only shows a `name` field, with the option to add more fields. - -Use the `fieldsView` render prop to add some fields: - -```jsx - ( -
-
- - - - {getNameInputErrors().map((error) => ( -

- {error} -

- ))} -
- -
- - - - {getCustomPropertyInputErrors("extra_field").map((error) => ( -

- {error} -

- ))} -
-
- )} -/> -``` - -When you add an image to your collection, it will look like this. - -![Screenshot of custom property](/docs/laravel-medialibrary/v11/images/pro/extra.png) - -### Customizing the file properties - -When uploading a file, some properties appear by default: its extension, filesize and a remove or download button (respectively for the attachment or collection component). - -You can customize what is displayed here by using the `propertiesView` scoped slot: - -```jsx - ( -
{object.attributes.name}
- )} -/> -``` - -### Asynchronously submit data - -If you don't want to use traditional form submits to send your data to the backend, you will have to keep track of the current value of the component using the `onChange` handler. The syntax is the same for all UI components. - -```jsx -import Axios from 'axios'; - -export function AvatarForm({ values }) { - const [media, setMedia] = React.useState(values.media); - const [validationErrors, setValidationErrors] = React.useState({}); - - function submitForm() { - Axios - .post('endpoint', { media }) - .catch(error => setValidationErrors(error.data.errors)); - } - - return ( - <> - - - - - ); -} -``` - -### Usage with Laravel Vapor - -If you are planning on deploying your application to AWS using [Laravel Vapor](https://vapor.laravel.com/), you will need to do some extra configuration to make sure files are uploaded properly to an S3 bucket. - -First off, make sure you have [enabled Vapor support in Laravel](./processing-uploads-on-the-server#enabling-vapor-support). - -You will also need to set the `vapor` prop in your components. - -```jsx - -``` - -If you edited Vapor's signed storage URL in Laravel, you will need to pass the new endpoint to your components in `vaporSignedStorageUrl`. It will use `/vapor/signed-storage-url` by default. - -```jsx - -``` - -### Usage with Inertia - -When using the components in repository that uses Inertia, the setup is very similar to the asynchronous setup. - -```jsx -import React, { useState } from "react"; -import { MediaLibraryAttachment } from "media-library-pro-react-attachment"; -import { usePage } from "@inertiajs/inertia-react"; -import { Inertia } from "@inertiajs/inertia"; - -export default function AccountPage() { - const { props } = usePage(); - const [avatar, setAvatar] = useState(props.values.avatar); - - function handleSubmit() { - Inertia.post("", { avatar }); - } - - return ( -
- - - -
- ); -} -``` - -## Validation rules - -There are a couple of different ways to validate files on the frontend. These props are available to you: `validationRules`, `maxItems` and `beforeUpload`. - -**validationRules** - -In the `validationRules` object, we've got the `accept` property, which expects an array of MIME types as strings. Leave it empty to accept all types of files, set its value to `['image/*']` to accept any type of image, or choose your own set of rules using [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types). Remember, the only valid MIME type of a JPEG/JPG is `image/jpeg`! - -The `minSizeInKB` and `maxSizeInKB` properties set the minimum and maximum size of any individual file. - -```jsx - -``` - -**maxItems** - -Set the maximum amount of items in the collection/attachment component at any time. - -```jsx - -``` - -**beforeUpload** - -Pass a method to `beforeUpload` that accepts a [file](https://developer.mozilla.org/en-US/docs/Web/API/File) parameter. Return any value (or resolve a Promise with any value) from this function to upload the file. Throw an Error in this function to cause the file not to be uploaded, and display your error message. - -```jsx -function checkFileValidity(file) { - return new Promise((resolve) => { - if (file.size < 1000) { - return resolve(); - } - - throw new Error("The uploaded file is too big"); - }); -} - -return ( - -); -``` - -## Translations - -If you would like to use the components in your own language, you can pass a `translations` prop to the component. - -```jsx -translations = { - fileTypeNotAllowed: "You must upload a file of type", - tooLarge: "File too large, max", - tooSmall: "File too small, min", - tryAgain: "please try uploading this file again", - somethingWentWrong: "Something went wrong while uploading this file", - selectOrDrag: "Select or drag files", - selectOrDragMax: "Select or drag max {maxItems} {file}", - file: { singular: "file", plural: "files" }, - anyImage: "any image", - anyVideo: "any video", - goBack: "Go back", - dropFile: "Drop file to upload", - dragHere: "Drag file here", - remove: "Remove", - download: "Download", -}; - -return ; -``` - -The values mentioned here are the defaults. Feel free to only pass in a couple of keys, as your object will be merged onto the default. - -If you use the component in different parts of your app, you might want to set the translations globally. - -```js -window.mediaLibraryTranslations = { - somethingWentWrong: "whoops", - remove: "delete", -}; -``` - -## Usage in Next.js - -Because the components need references `document` and `window`, Server Side Rendering won't work. This means you'll have to use [dynamic imports](https://nextjs.org/docs/advanced-features/dynamic-import) to get the UI components to work. - -```js -import dynamic from "next/dynamic"; -const MediaLibraryCollection = dynamic( - () => import("@spatie/media-library-pro-react-collection"), - { ssr: false } -); -``` - -## Props - -These props are available on both the `attachment` and the `collection` component. - -| prop name | Default value | Description | -| ------------------------ | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | | | -| initialValue | `[]` | | -| routePrefix | `"media-library-pro"` | | -| uploadDomain | | Use this if you're uploading your files to a separate (sub)domain, e.g. `files.mydomain.com` (leave out the trailing slash) | -| validationRules | | Refer to the ["validation rules"](#content-validation-rules) section | -| validationErrors | | The standard Laravel validation error object | -| multiple | `false` (always `true` in the `collection` component) | Only exists on the `attachment` components | -| maxItems | `1` when `multiple` = `false`, otherwise `undefined | | -| vapor | | Set to true if you will deploy your application to Vapor, this enables uploading of the files to S3. [Read more](#content-usage-with-laravel-vapor) | -| vaporSignedStorageUrl | `"vapor/signed-storage-url"` | | -| maxSizeForPreviewInBytes | `5242880` (5 MB) | When an image is added, the component will try to generate a local preview for it. This is done on the main thread, and can freeze the component and/or page for very large files | -| sortable | `true` | Only exists on the `collection` components. Allows the user to drag images to change their order, this will be reflected by a zero-based `order` attribute in the value | -| translations | | Refer to the ["Translations"](#content-translations) section | -| fileTypeHelpText | | Override the automatically generated helptext from `validationRules.accept` | -| setMediaLibrary | | Used to set a reference to the MediaLibrary instance, so you can change the internal state of the component. | -| beforeUpload | | A method that is run right before a temporary upload is started. You can throw an `Error` from this function with a custom validation message | -| afterUpload | | A method that is run right after a temporary upload has completed, `{ success: true, uuid }` | -| onChange | | | -| onIsReadyToSubmitChange | | Refer to the ["Checking the upload state"](#content-checking-the-upload-state) section | diff --git a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-vue.md b/docs/handling-uploads-with-media-library-pro/handling-uploads-with-vue.md deleted file mode 100644 index cbb47f0f3..000000000 --- a/docs/handling-uploads-with-media-library-pro/handling-uploads-with-vue.md +++ /dev/null @@ -1,604 +0,0 @@ ---- -title: Handling uploads with Vue -weight: 6 ---- - -Media Library Pro provides beautiful UI components for Vue 3. They pack a lot of features: temporary uploads, custom property inputs, frontend validation, and robust error handling. - -The `MediaLibraryAttachment` component can upload one or more files with little or no extra information. The attachment component is a lightweight solution for small bits of UI like avatar fields. - -![Screenshot of the MediaLibraryAttachment Vue component](/docs/laravel-medialibrary/v11/images/pro/attachment.png) - -The `MediaLibraryCollection` component can upload multiple files with custom properties. The collection component shines when you need to manage media, like in backoffices. - -![Screenshot of the MediaLibraryCollection Vue component](/docs/laravel-medialibrary/v11/images/pro/collection.png) - -If neither of these fit the bill, we've exposed a set of APIs for you to be bold and [roll your own components](./creating-custom-vue-components). - -## Demo application - -In [this repo on GitHub](https://github.com/spatie/laravel-medialibrary-pro-app), you'll find a demo Laravel application in which you'll find examples of how to use Media Library Pro with Vue. - -If you are having troubles using the components, take a look in that app to see how we've done it. - -## Setup Vite -If you are using Vite, your `vite.config.js` look something like this: - -```js -import { defineConfig } from 'vite'; -import laravel from 'laravel-vite-plugin'; -import vue from '@vitejs/plugin-vue'; - -export default defineConfig({ - resolve: { - alias: { - 'media-library-pro-vue3-attachment': '/vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-vue3-attachment', - 'media-library-pro-vue3-collection': '/vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-vue3-collection', - 'vue': 'vue/dist/vue.esm-bundler.js', - } - }, - plugins: [ - laravel([ - 'resources/js/app.js', - ]), - vue({ - template: { - transformAssetUrls: { - base: null, - includeAbsolute: false, - }, - }, - }), - ], -}); - -``` - -## Basic setup - -First, the server needs to be able to catch your incoming uploads. Use the `mediaLibrary` macro in your routes file. - -```php -// Probably routes/web.php -Route::mediaLibrary(); -``` - -The macro will register a route on `/media-library-pro/uploads`, which is used by the Vue components by default. You can change the prefix by passing it to the macro: - -```php -// Probably routes/web.php -Route::mediaLibrary('my-custom-url'); -``` - -This will register a route at `/my-custom-url/uploads` instead. - -### Customizing the upload endpoint - -The Vue components post data to `/media-library-pro/uploads` by default. If you changed the prefix in the route macro, pass it to the `route-prefix` prop of your Vue components. - -```html - -``` - -### Importing the components - -The components aren't available through npm, but are located in `vendor/spatie/laravel-medialibrary-pro/resources/js` when you install the package through Composer. This makes for very long import statements, which you can clean up by adding some configuration to your Webpack/Laravel Mix configuration. - -_If you're developing a project where you don't have access to composer, you can download the package through GitHub Packages: [installation steps](./usage-in-a-frontend-repository)_ - -To use a component in your Blade templates, import the components you plan to use in your `app.js` file, and add them to your main Vue app's `components` object. - -```js -import { createApp } from "vue"; -import { MediaLibraryAttachment } from "media-library-pro-vue3-attachment"; -import { MediaLibraryCollection } from "media-library-pro-vue3-collection"; - -createApp({ - components: { - MediaLibraryAttachment, - MediaLibraryCollection, - }, -}).mount("#app"); -``` - -You can now use them in any `.blade.php` file in your application. - -```html - - -
-
- - - - -
-``` - -You may also choose to import the components on the fly in a `.vue` file. - -```html - - - - - -``` - -**CSS Import for SPA use** - -If you are using a SPA you can import the CSS into `app.js` like this: - -```diff -// resources/js/app.js -import './bootstrap'; -import '../css/app.css'; -+import 'media-library-pro/media-library-pro-styles/src/styles.css'; -... -``` - -If you want to import the CSS into `app.css` you can still use the import mentioned in [Customizing CSS](./customizing-css). - - -## Your first components - -The most basic components have a `name` prop. This name will be used to identify the media when it's uploaded to the server. - -```html - - - - - -``` - -### Passing an initial value - -If your form modifies an existing set of media, you may pass it through in the `initial-value` prop. - -You can retrieve your initial values in Laravel using `$yourModel->getMedia($collectionName)`. This will also take care of any `old` values after an invalid form submit. You can also use this straight in your blade file: - -```html -
- - - - - - -``` - -Under the hood, these components create hidden `` fields to keep track of the form values on submit. If you would like to submit your values asynchronously, refer to [the `Asynchronously submit data` section](#asynchronously-submit-data). - -### Setting validation rules - -You'll probably want to validate what gets uploaded. Use the `validation-rules` prop, and don't forget to pass Laravel's validation errors too. The validation errors returned from the server will find errors under the key used in your `name` prop. - -```html -
- - - - - - -``` - -You can also set the maximum amount of images that users can be uploaded using the `max-items` prop. Don't forget to set the `multiple` prop for the attachment component. - -```html -
- - - - - - -``` - -See the [Validation rules section](#validation-rules) for a complete list of all possible validation rules. - -### Checking the upload state - -The components keep track of whether they're ready to be submitted, you can use this to disable a submit button while a file is still uploading or when there are frontend validation errors. This value can be tracked by listening to a `is-ready-to-submit-change` event on the components. If you submit a form while a file is uploading, Laravel will return a HTTP 500 error with an `invalid uuid` message. - -```html - - - -``` - -### Using custom properties - -The Media Library supports [custom properties](/docs/laravel-medialibrary/v11/advanced-usage/using-custom-properties) to be saved on a media item. The values for these can be chosen by your users. By default, the `MediaLibraryAttachment` component doesn't show any input fields, and the `MediaLibraryCollection` component only shows a `name` field, with the option to add more fields. - -Use the `fields` scoped slot to add some fields: - -```html - - - -``` - -When you add an image to your collection, it will look like this. - -![Screenshot of custom property](/docs/laravel-medialibrary/v11/images/pro/extra.png) - -### Customizing the file properties - -When uploading a file, some properties appear by default: its extension, filesize and a remove or download button (respectively for the attachment or collection component). - -You can customize what is displayed here by using the `properties` scoped slot: - -```html - - - -``` - -### Asynchronously submit data - -If you don't want to use traditional form submits to send your data to the backend, you will have to keep track of the current value of the component using the `onChange` handler. The syntax is the same for all UI components: - -```html - - - -``` - -### Usage with Laravel Vapor - -If you are planning on deploying your application to AWS using [Laravel Vapor](https://vapor.laravel.com/), you will need to do some extra configuration to make sure files are uploaded properly to an S3 bucket. - -First off, make sure you have [enabled Vapor support in Laravel](./processing-uploads-on-the-server#enabling-vapor-support). - -You will also need to set the `vapor` prop in your components. - -```html - -``` - -If you edited Vapor's signed storage URL in Laravel, you will need to pass the new endpoint to your components in `vapor-signed-storage-url`. It will use `/vapor/signed-storage-url` by default. - -```html - -``` - -### Usage with Inertia - -When using the components in repository that uses Inertia, the setup is very similar to the asynchronous setup. - -```html - - - -``` - -## Validation rules - -There are a couple of different ways to validate files on the frontend. These props are available to you: `validationRules`, `maxItems` and `beforeUpload`. - -**validationRules** - -In the `validationRules` object, we've got the `accept` property, which expects an array of MIME types as strings. Leave it empty to accept all types of files, set its value to `['image/*']` to accept any type of image, or choose your own set of rules using [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types). Remember, the only valid MIME type of a JPEG/JPG is `image/jpeg`! - -The `minSizeInKB` and `maxSizeInKB` properties set the minimum and maximum size of any individual file. - -```html - -``` - -**maxItems** - -Set the maximum amount of items in the collection/attachment component at any time. - -```html - -``` - -**beforeUpload** - -Pass a method to `before-upload` that accepts a [file](https://developer.mozilla.org/en-US/docs/Web/API/File) parameter. Return any value (or resolve a Promise with any value) from this function to upload the file. Throw an Error in this function to cause the file not to be uploaded, and display your error message. - -```html - - - -``` - -## Translations - -If you would like to use the components in your own language, you can pass a `translations` prop to the component. - -```html - -``` - -The values mentioned here are the defaults. Feel free to only pass in a couple of keys, as your object will be merged onto the default. - -If you use the component in different parts of your app, you might want to set the translations globally. - -```js -window.mediaLibraryTranslations = { - somethingWentWrong: "whoops", - remove: "delete", -}; -``` - -If you use the [vue-i18n](https://vue-i18n.intlify.dev/) package from intlify, you can also pass the keys from a translation file like `lang/media-library.php` by using the [`$tm`-function](https://vue-i18n.intlify.dev/api/composition.html#tm-key). - -```js - -``` - -## Props - -These props are available on both the `attachment` and the `collection` component. - -| prop name | Default value | Description | -| ----------------------------- | ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| name | | | -| initial-value | `[]` | | -| route-prefix | `"media-library-pro"` | | -| upload-domain | | Use this if you're uploading your files to a separate (sub)domain, e.g. `files.mydomain.com` (leave out the trailing slash) | -| validation-rules | | Refer to the ["validation rules"](#validation-rules) section | -| validation-errors | | The standard Laravel validation error object | -| multiple | `false` (always `true` in the `collection` component) | Only exists on the `attachment` components | -| max-items | `1` when `multiple` = `false`, otherwise `undefined | | -| vapor | | Set to true if you will deploy your application to Vapor. This enables uploading of the files to S3. | -| vapor-signed-storage-url | `"vapor/signed-storage-url"` | | -| max-size-for-preview-in-bytes | `5242880` (5 MB) | When an image is added, the component will try to generate a local preview for it. This is done on the main thread, and can freeze the component and/or page for very large files | -| sortable | `true` | Only exists on the `collection` components. Allows the user to drag images to change their order, this will be reflected by a zero-based `order` attribute in the value | -| translations | | Refer to the ["Translations"](#translations) section | -| file-type-help-text | | Override the automatically generated helptext from `validation-rules.accept` | -| ref | | Used to set a reference to the MediaLibrary instance, so you can change the internal state of the component. | -| before-upload | | A method that is run right before a temporary upload is started. You can throw an `Error` from this function with a custom validation message | -| after-upload | | A method that is run right after a temporary upload has completed, `{ success: true, uuid }` | -| @changed | | | -| @is-ready-to-submit-change | | Refer to [Checking the upload state](#checking-the-upload-state) section | diff --git a/docs/handling-uploads-with-media-library-pro/installation.md b/docs/handling-uploads-with-media-library-pro/installation.md deleted file mode 100644 index 8ec92342b..000000000 --- a/docs/handling-uploads-with-media-library-pro/installation.md +++ /dev/null @@ -1,170 +0,0 @@ ---- -title: Installation -weight: 2 ---- - -[Media Library Pro](medialibrary.pro) is a paid add-on package for Laravel Media Library. In order to use it, you must have the base version of media library installed in your project. Here are [the installation instructions for the base version](/docs/laravel-medialibrary/v11/installation-setup). - -## Installing the base package - -If you haven't installed the base Media Library package, make sure to do so by running: - -```bash -composer require "spatie/laravel-medialibrary:^11.0.0" -``` - -## Getting a license - -You must buy a license on [the Media Library Pro product page](https://spatie.be/products/media-library-pro) at spatie.be - -Single application licenses maybe installed in a single Laravel app. In case you bought the unlimited application license, there are no restrictions. A license comes with one year of upgrades. If a license expires, you are still allowed to use Media Library Pro, but you won't get any updates anymore. - -## Current version - -The current version of Media Library Pro is v5. - -You will find upgrade instructions [here](/docs/laravel-medialibrary/v11/handling-uploads-with-media-library-pro/upgrading). - -## Requiring Media Library Pro - -After you've purchased a license, add the `satis.spatie.be` repository in your `composer.json`. - -```php -"repositories": [ - { - "type": "composer", - "url": "https://satis.spatie.be" - } -], -``` - -Next, you need to create a file called `auth.json` and place it either next to the `composer.json` file in your project, or in the Composer home directory. You can determine the Composer home directory on \*nix machines by using this command. - -```bash -composer config --list --global | grep home -``` - -This is the content you should put in `auth.json`: - -```php -{ - "http-basic": { - "satis.spatie.be": { - "username": "", - "password": "" - } - } -} -``` - - -To be sure you can reach `satis.spatie.be`, clean your autoloaders before using this command: - -```bash -composer dump-autoload -``` - -To validate if Composer can read your auth.json you can run this command: - -```bash -composer config --list --global | grep satis.spatie.be -``` - -If you are using [Laravel Forge](https://forge.laravel.com), you don't need to create the `auth.json` file manually. Instead, you can set the credentials on the Composer Package Authentication screen of your server. Fill out the fields with these values: - -- Repository URL: `satis.spatie.be` -- Username: Fill this field with your spatie.be account email address -- Password: Fill this field with your Media Library Pro license key - -![screenshot](/docs/laravel-medialibrary/v11/images/forge.png) - -With the configuration above in place, you'll be able to install the Media Library Pro into your project using this command: - -```bash -composer require "spatie/laravel-medialibrary-pro:^5.1.0" -``` - -## Prepare the database - -Media Library Pro tracks all temporary uploads in a table called `temporary_uploads`. - -To create the table you need to publish and run the migration: - -```bash -php artisan vendor:publish --provider="Spatie\MediaLibraryPro\MediaLibraryProServiceProvider" --tag="media-library-pro-migrations" -php artisan migrate -``` - -## Automatically removing temporary uploads - -If you are using Media Library Pro, you must schedule this artisan command in `app/Console/Kernel` to automatically delete temporary uploads - -### Laravel >= 11 -```php -// in bootstrap/app.php - -->withSchedule(function (Schedule $schedule) { - $schedule->command('media-library:delete-old-temporary-uploads')->daily(); -}) -``` - -### Laravel < 11 -```php -// in app/Console/Kernel.php - -protected function schedule(Schedule $schedule) -{ - $schedule->command('media-library:delete-old-temporary-uploads')->daily(); -} -``` - -## Add the route macro - -To accept temporary uploads via React and Vue, you must add this macro to your routes file. -You do not need to register this endpoint when using the Blade/Livewire components. - -```php -// Probably routes/web.php - -Route::mediaLibrary(); -``` - -This macro will add the routes to controllers that accept file uploads for all components. - -## Front-end setup - -You have a couple of options for how you can use the UI components' CSS, depending on your and your project's needs: - -### Using Vite -In your vite.config.js file you can add an alias to the Medialibrary Pro css file: - -```javascript -export default defineConfig({ - resolve: { - alias: { - 'media-library-pro-styles': __dirname + '/vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-styles/src/styles.css', - } - } -}); -``` - -This will allow you to import the file in your own css file like this: -```css -@import "media-library-pro-styles"; -``` - - -### Directly in Blade/HTML - -You should copy the built CSS from `vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-styles/dist/styles.css` into your `public` folder, and then use a `link` tag in your blade/html to get it: ``. - -If you would like to customize the CSS we provide, head over to [the section on Customizing CSS](/docs/laravel-medialibrary/v11/handling-uploads-with-media-library-pro/customizing-css). - - -## What happens when your license expires? - -A few days before a license expires, we'll send you a reminder mail to renew your license. - -Should you decide not to renew your license, you won't be able to use composer anymore to install this package. You won't get any new features or bug fixes. - -Instead, you can download a zip containing the latest version that your license covered. This can be done on [your purchases page on spatie.be](https://spatie.be/profile/purchases). You are allowed to host this version in a private repo of your own. diff --git a/docs/handling-uploads-with-media-library-pro/introduction.md b/docs/handling-uploads-with-media-library-pro/introduction.md deleted file mode 100644 index b727758a5..000000000 --- a/docs/handling-uploads-with-media-library-pro/introduction.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: Introduction -weight: 1 ---- - -[Media Library Pro](http://medialibrary.pro) is a paid add-on package that offers Blade, Livewire, Vue, and React components to upload files to your application. - -Media Library Pro ships with two components for every environment: an attachment component, and a collection component. - -The attachment component can upload one or more files with little or no extra information. It's a lightweight solution for small bits of UI like avatar fields or message attachments. - -![Screenshot of the attachment component](/docs/laravel-medialibrary/v11/images/pro/attachment.png) - -The collection component can upload multiple files with custom properties. The collection component shines when you need to manage media, for example in admin panels. - -![Screenshot of the attachment component](/docs/laravel-medialibrary/v11/images/pro/collection.png) - -If none of those fit the bill, Media Library Pro supplies you with a number of helpers to build your own components. - -## Are you a visual learner? - -In this video, you'll see a quick overview of the package. - - - -Want to see more videos like this? Check out our [free video course on how to use Laravel Media Library](https://spatie.be/courses/discovering-laravel-media-library). - -## Dive in - -All components upload media to the server with the same API. Before you dive into the frontend, read [our server guide](processing-uploads-on-the-server). - -Next, choose your own journey. We have written extensive guides for all four flavours. Be sure to first follow [the base installation instructions](/docs/laravel-medialibrary/v11/installation-setup) and [pro installation instructions](/docs/laravel-medialibrary/v11/handling-uploads-with-media-library-pro/installation). - -### Blade - -You can use the attachment and collection components in regular forms. Behind the scenes these components use Livewire, but no Livewire knowledge is needed to use them. -See the links below for handling uploads with Livewire. - -### Livewire - -If you are creating Livewire components to display and handle forms, this is your path. The attachment and collection components can be used from within your Livewire components - -- [Handling uploads with Livewire 2](/docs/laravel-medialibrary/v11/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-2) -- [Handling uploads with Livewire 3](/docs/laravel-medialibrary/v11/handling-uploads-with-media-library-pro/handling-uploads-with-livewire-3) - -### Vue - -- [Handling uploads with Vue](handling-uploads-with-vue) -- [Creating custom Vue components](creating-custom-vue-components) - -### React - -- [Handling uploads with React](handling-uploads-with-react)
-- [Creating custom React components](creating-custom-react-components) - -## Demo application - -We've created a demo application in which all components are installed. This way you'll have a full example on how to use components in your project. - -You'll find the code of the demo application in [this repository on GitHub](https://github.com/spatie/laravel-medialibrary-pro-app). In order to `composer install` on that project, you'll need to have [a license]([/docs/laravel-medialibrary/v11/handling-uploads-with-media-library-pro/installation#content-getting-a-license). diff --git a/docs/handling-uploads-with-media-library-pro/laravel-mix.md b/docs/handling-uploads-with-media-library-pro/laravel-mix.md deleted file mode 100644 index acff825a4..000000000 --- a/docs/handling-uploads-with-media-library-pro/laravel-mix.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Laravel Mix -weight: 9 ---- - -## Using Laravel Mix or Webpack with css-loader - -You can import the built CSS in your own CSS files using `@import "vendor/spatie/laravel-medialibrary-pro/resources/js/media-library-pro-styles";`. - -This isn't a very pretty import, but you can make it cleaner by adding this configuration to your Webpack config: - -**laravel-mix >6** - -```js -mix.override((webpackConfig) => { - webpackConfig.resolve.modules = [ - "node_modules", - __dirname + "/vendor/spatie/laravel-medialibrary-pro/resources/js", - ]; -}); -``` - -**laravel-mix <6** - -```js -mix.webpackConfig({ - resolve: { - modules: [ - "node_modules", - __dirname + "/vendor/spatie/laravel-medialibrary-pro/resources/js", - ], - }, -}); -``` - -This will force Webpack to look in `vendor/spatie/laravel-medialibrary-pro/resources/js` when resolving imports, and allows you to shorten your import to this: - -```css -@import "media-library-pro-styles"; -``` - -If you're using PurgeCSS, you might have to add a rule to your whitelist patterns. - -```js -mix.purgeCss({ whitelistPatterns: [/^media-library/] }); -``` - -## Vue specific configuration - -**laravel-mix >6** - -```js -// webpack.mix.js - -mix.override((webpackConfig) => { - webpackConfig.resolve.modules = [ - "node_modules", - __dirname + "/vendor/spatie/laravel-medialibrary-pro/resources/js", - ]; -}); -``` - -**laravel-mix <6** - -```js -// webpack.mix.js - -mix.webpackConfig({ - resolve: { - modules: [ - "node_modules", - __dirname + "/vendor/spatie/laravel-medialibrary-pro/resources/js", - ], - }, -}); -``` - -This will force Webpack to look in `vendor/spatie/laravel-medialibrary-pro/resources/js` when resolving imports, and allows you to shorten your import. - -```js -import { MediaLibraryAttachment } from "media-library-pro-vue3-attachment"; -``` - -If you're using TypeScript, you will also have to add this to your tsconfig: - -```json -// tsconfig.json - -{ - "compilerOptions": { - "paths": { - "*": ["*", "vendor/spatie/laravel-medialibrary-pro/resources/js/*"] - } - } -} -``` diff --git a/docs/handling-uploads-with-media-library-pro/processing-uploads-on-the-server.md b/docs/handling-uploads-with-media-library-pro/processing-uploads-on-the-server.md deleted file mode 100644 index 0a62f549c..000000000 --- a/docs/handling-uploads-with-media-library-pro/processing-uploads-on-the-server.md +++ /dev/null @@ -1,406 +0,0 @@ ---- -title: Processing uploads on the server -weight: 3 ---- - -All Blade, Vue and React components communicate with the server in the same way. After a user selects one or more files, they're immediately sent to the server and stored as temporary uploads. When the parent form is submitted, the media items can be attached to a model. - -## Are you a visual learner? - -This video shows you how Media Library Pro uses temporary uploads under the hood. - - - -Want to see more videos like this? Check out our [free video course on how to use Laravel Media Library](https://spatie.be/courses/discovering-laravel-media-library). - -## Enabling temporary uploads - -Plain HTML file ``s have two major shortcomings: they only upload the file when the form is submitted, and they're unable to remember the file when a form fails to submit. Temporary uploads solve both these problems. - -When a user selects or drops a file in one of the Media Library components, it gets uploaded to the server immediately. Problem number 1 solved! - -If the form submission fails later on, Media Library will pass down the previously added temporary upload objects so it can prefill the component with the previously uploaded files. Problem number 2 solved too! - -To set up temporary uploads, register the temporary uploads route with our handy macro. - -```php -// Probably routes/web.php - -Route::mediaLibrary(); -``` - -This will register a route at `/media-library-pro/uploads`. - - -### Enabling Vapor support - -If use React or Vue components to handle uploads you must set the `enable_vapor_uploads` key in the `media-library` config file to `true`. When enabling this option, a route will be registered that will enable -the Media Library Pro Vue and React components to move uploaded files in an S3 bucket to their right place. - -With the config option enabled, the `Route::mediaLibrary();` will register a route at `/media-library-pro/post-s3` - instead of `/media-library-pro/uploads`. - -### Customizing the upload URL - -You can customize the upload url by passing a base url to the macro. - -```php -// Probably routes/web.php - -Route::mediaLibrary('my-custom-url'); -``` - -This will register a route at `/my-custom-url/uploads` - -## Setting up the view & controller - -After a user has added files and they've been stored as temporary uploads, the user will submit the form. At this point the form request will hit one of your application's controllers. This is where you can permanently attach the file to your models. - -To illustrate, we'll set up a little profile screen where a user may upload their avatar. - -```php -// Back in routes/web.php -use App\Http\Controllers\ProfileController; - -Route::get('profile', [ProfileController::class, 'edit']); -Route::post('profile', [ProfileController::class, 'store']); - -Route::mediaLibrary(); -``` - -The profile controller has a simple form that uses the Blade attachment component. - -```blade -{{-- resources/views/profile.blade.php --}} - - -``` - -And, assuming you're familiar with the [basic usage](../basic-usage) of the Media Library, this is how we'd store the uploaded avatar on the user. - -```php -namespace App\Http\Controllers; - -use Illuminate\Http\Request; -use Illuminate\Support\Facades\Auth; - -class ProfileController -{ - public function edit() - { - return view('profile', [$user => Auth::user()]); - } - - public function store(Request $request) - { - $user = Auth::user(); - - $user - ->addFromMediaLibraryRequest($request->avatar) - ->toMediaCollection('avatar'); - } -} -``` - -## Validation - -The `ProfileController` we built assumes users will only upload the exact file types we're looking for. Of course they won't! We need to validate the incoming media before attaching them to our models. - -The Media Library components provide instant client-side validation. You'll read more about that in the component docs. First, we'll set up server-side validation. - -To validate uploaded media, we'll use a custom form request. - -```diff -- public function store(Request $request) -+ public function store(ProfileRequest $request) -``` -```php -namespace App\Http\Requests; - -use Illuminate\Foundation\Http\FormRequest; -use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia; - -class ProfileRequest extends FormRequest -{ - use ValidatesMedia; - - public function rules() - { - return [ - 'images' => $this - ->validateMultipleMedia() - ->minItems(1) - ->maxItems(5) - ->extension('png') - ->maxItemSizeInKb(1024) - ->attribute('name', 'required') - ]; - } -} -``` - ---- - -Every component will pass data in a key of a request. The name of that key is the name you passed to the `name` prop of any of the components. - -```html -// data will get passed via the `avatar` key of the request. - - -``` - -The content of that request key will be an array. For each file uploaded that array will hold an array with these keys. - -- `name`: the name of the uploaded file -- `uuid`: the UUID of a `Media` model. For newly uploaded files that have not been associated to a model yet, the `Media` model will be associated with a `TemporaryUpload` model -- `order`: the order in which this item should be stored in a media collection. - -## Validating requests - -Even though the upload components do some client-side validation, we highly recommend always validating requests on the server as well. - -You should handle validation in a form request. On the form request you should use the `Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia` trait. This will give you access to the `validateSingleMedia` and `validateMultipleMedia` methods. - -In this example we assume that a component was configured to use the `images` key of the request. We validate that there was at least one item uploaded, but no more than 5. Only `png`s that are up to 1MB in size are allowed. All images should have a name. - -```php -namespace App\Http\Requests; - -use Illuminate\Foundation\Http\FormRequest; -use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia; - -class MyRequest extends FormRequest -{ - use ValidatesMedia; - - public function rules() - { - return [ - 'images' => $this - ->validateMultipleMedia() - ->minItems(1) - ->maxItems(5) - ->extension('png') - ->maxItemSizeInKb(1024) - ->attribute('name', 'required') - ]; - } -} -``` - -If you are only allowing one uploaded file, you can use the `validateSingleMedia` in much the same way. - -```php -namespace App\Http\Requests; - -use Illuminate\Foundation\Http\FormRequest; -use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia; - -class MyRequest extends FormRequest -{ - use ValidatesMedia; - - public function rules() - { - return [ - 'avatar' => $this - ->validateSingleMedia() - ->extension('png') - ->maxItemSizeInKb(1024) - ]; - } -} -``` - -These are the available validation methods on `validateSingleMedia() ` and `validateMultipleMedia` - -- `minSizeInKb($minSizeInKb)`: validates that a single upload is not smaller than the `$minSizeInKb` given. -- `maxSizeInKb($maxSizeInKb)`: validates that a single upload is not greater than the `$minSizeInKb` given. -- `extension($extension)`: this rule expects a single extension as a string or multiple extensions as an array. Under the hood, the rule will validate if the value has the mime type that corresponds with the given extension. -- `mime($mime)`: this rule expects a single mime type as a string or multiple mime types as an array. -- `itemName($rules)`: this rule accepts rules that should be used to validate the name of a media item. -- `customProperty($name, $rules)`: this rule accepts a custom property name and rules that should be used to validate the attribute. -- `dimensions($width, $height)`: validates that the image has a specific width and height (in pixels). -- `width($width)`: validates that the image has a specific width (in pixels). The height is not validated. -- `height($height)`: validates that the image has a specific height (in pixels). The width is not validated. -- `widthBetween($minWidth, $maxWidth)`: validates that the image width (in pixels) is between the `$minWidth` and `$maxWidth` given (inclusive) -- `heightBetween($minHeight, $maxHeight)`: validates that the image height (in pixels) is between the `$minHeight` and `$maxHeight` given (inclusive) - -These rules can be used on `validateMultipleMedia`; - -- `minTotalSizeInKb($maxTotalSizeInKb)`: validates that the combined size of uploads is not smaller than the `$minTotalSizeInKb` given. -- `maxTotalSizeInKb($maxTotalSizeInKb)`: validates that the combined size of uploads is not greater than the `$maxTotalSizeInKb` given. - -### Validating attributes and custom properties - -If you're [using custom properties](/docs/laravel-medialibrary/v11/advanced-usage/using-custom-properties), you can validate them with the `customProperty` function. The first argument should be the name of the custom property you are validating. The second argument should be a string or an array with rules you'd like to use. - -Here's an example where we validate `extra_property` and `another_extra_property`. - -```php -use Illuminate\Foundation\Http\FormRequest; -use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia; - -class StoreLivewireCollectionCustomPropertyRequest extends FormRequest -{ - use ValidatesMedia; - - public function rules() - { - return [ - 'name' => 'required', - 'images' => $this->validateMultipleMedia() - ->customProperty('extra_field', 'required|max:50') - ->customProperty('another_extra_property', ['required', 'max:50']) - ]; - } -} -``` - -## Processing requests - -After you've validated the request, you should persist the changes to the media library. The media library provides two methods for that: `syncFromMediaLibraryRequest` and `addFromMediaLibraryRequest`. Both these methods are available on all [models that handle media](/docs/laravel-medialibrary/v11/basic-usage/preparing-your-model). Either way call the method `toMediaCollection` to update your media-model in the database. This will also ensure that temporary uploads are converted to the appropriate model. - -### `addFromMediaLibraryRequest` - -This method will add all media whose `uuid` is in the request to a media collection of a model. Existing media associated on the model will remain untouched. - -You should probably use this method only when accepting new uploads. - -```php -// in a controller - -public function yourMethod(YourFormRequest $request) -{ - // retrieve model - - $yourModel - ->addFromMediaLibraryRequest($request->get('images')) - ->toMediaCollection('images'); - - flash()->success('Your model has been saved.') - - return back(); -} -``` - -### `syncFromMediaLibraryRequest` - -You should use this method when you are using the `x-media-library-collection` Blade component (or equivalent Vue or React component). - -Here is an example where we are going to sync the contents of the `images` key in the request to the media library. -In this example we use the `images` key, but of course you should use the name that you used. - -All media associated with `$yourModel` whose `uuid` is not present in the `images` array of the request will be deleted. - -```php -// in a controller - -public function yourMethod(YourFormRequest $request) -{ - // retrieve model - - $yourModel - ->syncFromMediaLibraryRequest($request->images) - ->toMediaCollection('images'); - - flash()->success('Your model has been saved.') - - return back(); -} -``` - -After this code has been executed, the media, whose `uuid` is present in the `images` array of request, will be in the `images collection of `$yourModel`. - -```php -$yourModel->getMedia('images'); // the media that we just synced will be returned. -``` - -### Handling custom properties - -If you are using properties for your media items you should pass the names of the custom properties you expect to the `withCustomProperties` method. Only these custom properties will be accepted. - -```php -$yourModel - ->syncFromMediaLibraryRequest($request->images) - ->withCustomProperties('extra_field', 'another_extra_field') - ->toMediaCollection('images'); -``` - -### Setting a name - -If you want to use a specific media name before adding it to disk you can use the `usingName` method. - -```php -$yourModel - ->addFromMediaLibraryRequest($request->images) - ->usingName('my custom name') - ->toMediaCollection('images'); -``` - -Alternatively, you can pass a callable to `usingName`. This callable accepts an instance of `Spatie\MediaLibraryPro\MediaLibraryRequestItem` which can be used to get properties of the uploaded file. - -For this we have to add the `editableName` attribute to the component: - -```html - -``` - -The component now will render an editable input field for the name. - -In this example we're going to set the media name to the lowercase version of the uploaded filename before adding it the media library. - -```php -$yourModel - ->addFromMediaLibraryRequest($request->images) - ->usingName(fn(MediaLibraryRequestItem $item) => strtolower($item->name)) - ->toMediaCollection('images'); -``` - -### Setting a file name - -If you want to rename an uploaded file before adding it to disk you can use the `usingFileName` method. - -```php -$yourModel - ->addFromMediaLibraryRequest($request->images) - ->usingFileName('myFile.jpg') - ->toMediaCollection('images'); -``` - -Alternatively, you can pass a callable to `usingFileName`. This callable accepts an instance of `Spatie\MediaLibraryPro\MediaLibraryRequestItem` which can be used to get properties of the uploaded file. - -In this example we're going to lowercase the name of the uploaded file before adding it the media library. - -```php -$yourModel - ->addFromMediaLibraryRequest($request->images) - ->usingFileName(fn(MediaLibraryRequestItem $item) => strtolower($item->name)) - ->toMediaCollection('images'); -``` - -## Customizing the preview images - -All Blade, Vue and React components will display previews images that are generated by the `preview` conversion of -the `TemporaryUpload` model. This conversion will create a 500x500 representation of the image. - -You can customize this by registering a preview manipulation. Typically, this would be done in a service provider. -Here's an example where we will create 300x300 previews - -```php -use Spatie\MediaLibraryPro\Models\TemporaryUpload; -use Spatie\MediaLibrary\Conversions\Conversion; -use Spatie\Image\Enums\Fit; - -// in a service provider -TemporaryUpload::previewManipulation(function(Conversion $conversion) { - $conversion->fit(Fit::CROP, 300, 300); -}); -``` - -The components will use the `preview` conversion of models that have media associated to them. For example, if you have -a `$blogPost` model, and you use the components to display the media associated to that model, the components will -use `preview` conversion on the `BlogPost` model. - -Make sure such a `preview` conversion exists for each model that handles media. We highly recommend to use `nonQueued` -so the image is immediately available. diff --git a/docs/handling-uploads-with-media-library-pro/upgrading.md b/docs/handling-uploads-with-media-library-pro/upgrading.md deleted file mode 100644 index 68a50ebad..000000000 --- a/docs/handling-uploads-with-media-library-pro/upgrading.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: Upgrading -weight: 10 ---- - -## Upgrading - -This file contains instructions on how to upgrade to another major version of the package. - -## From v3 to v4 - -The main change in v4 is that we upgraded the required version of Media Library from v10 to v11. Under the hood spatie/image v3 is used instead of v2. - -In the latest version of spatie/image some of the manipulations methods have been renamed. If you're using any of these methods in your code, you'll need to update them. Take a look at the [defining conversions page](/docs/laravel-medialibrary/v11/converting-images/defining-conversions) to learn more. - -## From v2 to v3 - -The main change in v3 is that we now use Livewire 3.0 instead of Livewire 2.0. If you're using the JavaScript component, then there are no breaking changes. - -### Update the Livewire version requirement to v3: - -``` -- "livewire/livewire": "^2.0", -+ "livewire/livewire": "^v3.0", -``` - -### Add the Blade directives to your views - -```blade -- -- -- -+ @mediaLibraryStyles - - -+ @mediaLibraryScripts -``` - -### Update usage of the `WithMedia` trait: - -```php -- use Spatie\MediaLibraryPro\Http\Livewire\Concerns\WithMedia; -+ use Spatie\MediaLibraryPro\Livewire\Concerns\WithMedia; -``` - -### `clearMedia` has been removed - -The `->clearMedia()` method has been removed from the trait. Since you can now use model binding you can set your collection back to an empty array if you need to clear your media. - -```php -public function submit() -{ - // submit the form - -- $this->clearMedia(); -+ $this->media = []; -} -``` - -### Make sure you're setting your media properties to a default empty array - -```php -- public $media; -+ public $media = []; -``` - -### The `$mediaComponentNames` property has been removed in favour of Livewire model binding. - -```php -- public $mediaComponentNames = ['images', 'downloads']; - -public $images = []; - -public $downloads = []; -``` - -### Use the Livewire components directly instead of the Blade components - -We now have 1 Livewire component that can handle both Attachment and Collection use cases, use this Livewire component directly instead of using the provided Blade component. - -If you're not using Livewire yourself, you can still use the Blade components like before. - -#### Attachment - -```blade -- - + -``` - -#### Collection - -```blade -- -+ -``` - -## From v1 to v2 - -No changes to the public API were made. Support for PHP 7 and Laravel 8 was dropped. - -You should be able to upgrade without making any changes. diff --git a/docs/handling-uploads-with-media-library-pro/usage-in-afrontend-repository.md b/docs/handling-uploads-with-media-library-pro/usage-in-afrontend-repository.md deleted file mode 100644 index 74dc648e5..000000000 --- a/docs/handling-uploads-with-media-library-pro/usage-in-afrontend-repository.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Usage in a frontend repository -weight: 9 ---- - -If you can't install the package using `composer` because, for example, you're developing an SPA, you can download the packages from GitHub Packages. - -## Registering with GitHub Packages - -You will need to create a Personal Access Token with the `read:packages` permission on the GitHub account that has access to the [spatie/laravel-medialibrary-pro](https://github.com/spatie/laravel-medialibrary-pro) repository. We suggest creating an entirely new token for this and not using it for anything else. You can safely share this token with team members as long as it has only this permission. Sadly, there is no way to scope the token to only the Media Library Pro repository. - -Next up, create a `.npmrc` file in your project's root directory, with the following content: - -_.npmrc_ - -``` -//npm.pkg.github.com/:_authToken=github-personal-access-token-with-packages:read-permission -@spatie:registry=https://npm.pkg.github.com -``` - -Make sure the plaintext token does not get uploaded to GitHub along with your project. Either add the file to your `.gitignore` file, or set the token in your `.bashrc` file as an ENV variable. - -_.bashrc_ - -``` -export GITHUB_PACKAGE_REGISTRY_TOKEN=token-goes-here -``` - -_.npmrc_ - -``` -//npm.pkg.github.com/:_authToken=${GITHUB_PACKAGE_REGISTRY_TOKEN} -@spatie:registry=https://npm.pkg.github.com -``` - -Alternatively, you can use `npm login` to log in to the GitHub Package Registry. Fill in your GitHub credentials, using your Personal Access Token as your password. - -``` -npm login --registry=https://npm.pkg.github.com --scope=@spatie -``` - -If you get stuck at any point, have a look at [GitHub's documentation on this](https://docs.github.com/en/free-pro-team@latest/packages/publishing-and-managing-packages/installing-a-package). - -## Downloading the packages from GitHub Packages - -Now, you can use `npm install --save` or `yarn add` to download the packages you need. - -``` -yarn add @spatie/media-library-pro-styles @spatie/media-library-pro-vue3-attachment -``` - -**You will now have to include the `@spatie/` scope when importing the packages**, this is different from examples in the documentation. - -``` -import { MediaLibraryAttachment } from '@spatie/media-library-pro-vue3-attachment'; -``` - -You can find a list of all the packages on the repository: https://github.com/orgs/spatie/packages?repo_name=laravel-medialibrary-pro.