diff --git a/6.x/base-how-to.md b/6.x/base-how-to.md
index 4b8efe38..3e136130 100644
--- a/6.x/base-how-to.md
+++ b/6.x/base-how-to.md
@@ -51,7 +51,7 @@ In order to place something else inside that view, like [widgets](/docs/{{versio
```
To use information from the database, you can:
-- [use view composers](https://laravel.com/docs/5.7/views#view-composers) to push variables inside this view, when it's loaded;
+- [use view composers](https://laravel.com/docs/views#view-composers) to push variables inside this view, when it's loaded;
- load all your dashboard information using AJAX calls, if you're loading charts, reports, etc, and the DB queries might take a long time;
- use the full namespace for your models, like ```\App\Models\Product::count()```;
@@ -290,7 +290,7 @@ This is a default in Backpack v4.
Backpack's authentication uses a completely separate authentication driver, provider, guard and password broker. They're all named ```backpack```, and registered in the vendor folder, invisible to you.
-If you need a separate login for user, just go ahead and create it. [Add the Laravel authentication, like instructed in the Laravel documentation](https://laravel.com/docs/5.7/authentication#authentication-quickstart): ```php artisan make:auth```. You'll then have:
+If you need a separate login for user, just go ahead and create it. [Add the Laravel authentication, like instructed in the Laravel documentation](https://laravel.com/docs/authentication#authentication-quickstart): ```php artisan make:auth```. You'll then have:
- the user login at ```/login``` -> using the AuthenticationController Laravel provides
- the admin login at ```/admin/login``` -> using the AuthenticationControllers Backpack provides
@@ -440,7 +440,7 @@ This will make the registration process pick up a view you can create, in ```res
In Backpack CRUD 6.2 we introduced the ability to require email verification when accessing Backpack routes. To enable this feature please do the following:
-**Step 1** - Make sure your user model (usually `App\Models\User`) implements the `Illuminate\Contracts\Auth\MustVerifyEmail` contract. [More info](https://laravel.com/docs/10.x/verification#model-preparation).
+**Step 1** - Make sure your user model (usually `App\Models\User`) implements the `Illuminate\Contracts\Auth\MustVerifyEmail` contract. [More info](https://laravel.com/docs/verification#model-preparation).
```php
crud->addColumn([
'attribute' => 'name', // foreign key attribute that is shown to user
'orderable' => true,
'orderLogic' => function ($query, $column, $columnDirection) {
- return $query->leftJoin('categories', 'categories.id', '=', 'articles.select')
+ return $query->leftJoin('categories', 'categories.id', '=', 'articles.category_id')
->orderBy('categories.name', $columnDirection)->select('articles.*');
}
]);
diff --git a/6.x/crud-fields.md b/6.x/crud-fields.md
index b9a69023..b054b92e 100644
--- a/6.x/crud-fields.md
+++ b/6.x/crud-fields.md
@@ -883,7 +883,7 @@ CRUD::field([ // Switch
'label' => 'I have not read the terms and conditions and I never will',
// optional
- 'color' => 'primary', // May be any bootstrap color class or an hex color
+ 'color' => '#232323', // in CoreUI v2 theme you can also specify bootstrap colors, like `primary`, `danger`, `success`, etc You can also overwrite the `--bg-switch-checked-color` css variable to change the color of the switch when it's checked
'onLabel' => '✓',
'offLabel' => '✕',
]);
@@ -1138,6 +1138,13 @@ CRUD::field([ // Address google
Using Google Places API is dependent on using an API Key. Please [get an API key](https://console.cloud.google.com/apis/credentials) - you do have to configure billing, but you qualify for $200/mo free usage, which covers most use cases. Then copy-paste that key as your ```services.google_places.key``` value.
+**IMPORTANT NOTE**: Your key needs access to the following APIS:
+- Maps JavaScript API;
+- Places API;
+- Geocoding API.
+
+While developing you can use an "unrestricted key" (no restrictions for where the key is used), but for production you should use a separate key, and **MAKE SURE** you restrict the usage of that key to your own domain.
+
So inside your ```config/services.php``` please add the items below:
```php
'google_places' => [
@@ -1558,6 +1565,13 @@ Using Google Places API is dependent on using an API Key. Please [get an API key
],
```
+**IMPORTANT NOTE**: Your key needs access to the following APIS:
+- Maps JavaScript API;
+- Places API;
+- Geocoding API.
+
+While developing you can use an "unrestricted key" (no restrictions for where the key is used), but for production you should use a separate key, and **MAKE SURE** you restrict the usage of that key to your own domain.
+
**How to save in multiple inputs?**
There are cases where you rather save the information on separate inputs in the database. In that scenario you should use [Laravel mutators and accessors](https://laravel.com/docs/10.x/eloquent-mutators). Using the same field as previously shown (**field name is `location`**), and having `latitude`, `longitude`, `full_address` as the database columns, we can save and retrieve them separately too:
diff --git a/6.x/crud-filters.md b/6.x/crud-filters.md
index 205e3154..8a1221ae 100644
--- a/6.x/crud-filters.md
+++ b/6.x/crud-filters.md
@@ -666,3 +666,27 @@ function() { // if the filter is active (the GET parameter "draft" exits)
// CRUD::addClause('draft');
});
```
+
+
+
+### When to use `addClause()` or `addBaseClause()` to apply filtering logic
+
+In most of our filter examples we use `CRUD::addClause()` to apply filtering logic to that Eloquent model. This allows you to call methods on that model, either standard Laravel methods like `where()` or custom methods like scopes:
+
+```php
+CRUD::addClause('where', 'total', '=', '0'); // call standard laravel method "where" with params
+CRUD::addClause('free'); // call free() on the Model, which would itself call scopeFree()
+```
+
+When the filter is selected, your List operation will also show a small text: "_Showing 1 to 10 entries (filtered from 998)_".
+
+But there's another method you can use to add filtering to the Eloquent model - `addBaseClause()`. This works EXACTLY the same as `addClause()` but the filtering happens _earlier_ in the lifecycle, before pagination is even calculated. That means your users will no longer see the end part of the text above. With the EXACT same filtering, happening before pagination is calculated, your text will become: "_Showing 1 to 10 entries._". In short:
+
+```php
+CRUD::addClause('where', 'total', '=', '0'); // Showing 1 to 10 entries (filtered from 998)
+CRUD::addBaseClause('where', 'total', '=', '0'); // Showing 1 to 10 entries
+```
+
+When should you use one or the other?
+- in 99% of the cases you should probably use `addClause()`; it's more intuitive and informative for the admin, once they click a filter, to have feedback that what they see is a filtered list, out of a bigger list;
+- in 1% of the cases though, when you want to actually _hide_ the total number of entries in the table, you should use `addBaseClause()` instead; for example, if you want to ONLY show the articles of the current logged in person, you would not want them to how many entries are in the database, so you should use `addBaseClause()`;
diff --git a/6.x/crud-operation-fetch.md b/6.x/crud-operation-fetch.md
index 2685f7b3..cc13a988 100644
--- a/6.x/crud-operation-fetch.md
+++ b/6.x/crud-operation-fetch.md
@@ -84,6 +84,32 @@ public function fetchUser() {
}
```
+**Adding attributes to fetched models without appends**
+
+It's already possible to add attributes to the fetched models using the `appends` property in the model. However, this method has some drawbacks, like the fact that the appended attributes will be added to all instances of the model, whenever they are used, not only when they are fetched. If you want to add attributes to the fetched models without using the `appends` property in the model, you can use the `append_attributes` in the fetch configuration. For example:
+
+```php
+public function fetchUser() {
+ return $this->fetch([
+ 'model' => User::class,
+ 'append_attributes' => ['something'],
+ ]);
+ }
+
+// User.php model
+public function something(): Attribute
+{
+ return Attribute::make(
+ get: function (mixed $value, array $attributes) {
+ return $attributes['something_else'];
+ },
+ );
+}
+
+// and in your field definition
+CRUD::field('my_ajax_field')->attribute('something');
+```
+
## Using FetchOperation with `select2_ajax` filter
diff --git a/6.x/faq.md b/6.x/faq.md
index 8f30e58c..6491a5bf 100644
--- a/6.x/faq.md
+++ b/6.x/faq.md
@@ -41,6 +41,21 @@ Backpack PRO is a closed-source add-on, which requires payment in order to recei
No - we're no longer giving away free licenses. But we _have_ released Backpack CRUD v5 and v6 under the MIT License, which means it's free and open-source. It has fewer features, but you can do absolutely do anything you want with it.
+
+### Can I get a discount for university use?
+
+Yes, if you are a teacher at highschool or university and want to use Backpack to teach your students how to code, we're happy to give you a discount for our MULTI-PROJECT and EVERYTHING plans, so your students can quickly learn PHP, Laravel and Backpack. Reach out to us from your .edu email (or provide other proof). For this use case, please make sure to "refresh" your token every year, to prevent misuse.
+
+
+### Can I get a discount for a backlink?
+
+Yes, but only for your second/third purchases. Before your license expires, you will receive an email offering you 20% discount if you include a backlink from your website to ours. Reply to that email with a link, and our team will help you get the discount.
+
+To get the 20% discount:
+- include a backlink from your MAIN WEBSITE (not from your admin panel), to our main website: `https://backpackforlaravel.com?utm_source=customer_ref`; most people add a link to their footer; here are a few ideas: `Admin Panel by Backpack`, `Backoffice by Backpack`, `CMS Powered by Backpack`, `ERP Powered by Backpack`, `Powered By Backpack`;
+- make sure the link is `dofollow` (regular link);
+- make sure to keep the link there for 12 months;
+
## Installation
@@ -233,4 +248,4 @@ APP_DEBUG=false
```
php artisan config:clear
php artisan config:cache
-```
\ No newline at end of file
+```
diff --git a/6.x/introduction.md b/6.x/introduction.md
index 7bab24a6..b7d36647 100644
--- a/6.x/introduction.md
+++ b/6.x/introduction.md
@@ -6,8 +6,8 @@ Backpack is a collection of Laravel packages that help you **build custom admini
In a nutshell:
-- UI - Backpack will provide you with a _visual interface_ for the admin panel (the HTML, the CSS, the JS), authentication functionality & global bubble notifications; you can choose from one of the 3 themes we have developed (powered by Tabler, CoreUI v4 or CoreUI v2), a third-party theme or create your own theme; the enormous advantage of using a Bootstrap-based HTML theme is that when you need custom pages, you already have the HTML blocks for the UI, you don't have to design them yourself;
-- CRUDs - Backpack will also help you build _sections where your admins can manipulate entries for Eloquent models_; we call them _CRUD Panels_ after the most basic operations: Create, Read, Update & Delete; after [understanding Backpack](/docs/{{version}}/getting-started-basics), you'll be able to create a CRUD panel in a few minutes per model:
+- **UI** - Backpack will provide you with a _visual interface_ for the admin panel (the HTML, the CSS, the JS), authentication functionality & global bubble notifications; you can choose from one of the 3 themes we have developed (powered by Tabler, CoreUI v4 or CoreUI v2), a third-party theme or create your own theme; the enormous advantage of using a Bootstrap-based HTML theme is that when you need custom pages, you already have the HTML blocks for the UI, you don't have to design them yourself.
+- **CRUDs** - Backpack will also help you build _sections where your admins can manipulate entries for Eloquent models_; we call them _CRUD Panels_ after the most basic operations: Create, Read, Update & Delete; after [understanding Backpack](/docs/{{version}}/getting-started-basics), you'll be able to create a CRUD panel in a few minutes per model:

@@ -31,8 +31,8 @@ php artisan backpack:build
```
If you have NOT created your Eloquent models yet, you can use whatever you want for that. We recommend:
-- FREE - [`laravel-shift/blueprint`](https://github.com/laravel-shift/blueprint) as the best **YAML-based tool** for this;
-- PAID - [`backpack/devtools`](https://backpackforlaravel.com/products/devtools) as the best **web interface** for this; it makes it dead simple to create Eloquent models, from the comfort of your web browser;
+- FREE - [`laravel-shift/blueprint`](https://github.com/laravel-shift/blueprint) as the best **YAML-based tool** for this.
+- PAID - [`backpack/devtools`](https://backpackforlaravel.com/products/devtools) as the best **web interface** for this. It makes it dead simple to create Eloquent models, from the comfort of your web browser.
---
@@ -56,7 +56,7 @@ We heavily recommend you spend a little time to understand Backpack, and only af
### Requirements
- - Laravel 10.x or 11.x
+ - Laravel 10.x or 11.x or 12.x
- MySQL / PostgreSQL / SQLite / SQL Server
@@ -78,9 +78,9 @@ Backpack v6 is the current version and is actively maintained by the Backpack te
### License
Backpack is open-core:
-- **Backpack CRUD is free & open-source, licensed under the [MIT License](https://github.com/Laravel-Backpack/CRUD/blob/main/LICENSE.md)**; it is perfect if you're building a simple admin panel - it's packed with features! it's also perfect if you're building an open-source project, the permissive license allows you to do whatever you want;
-- **Backpack PRO is a paid, closed-source add-on, licensed under our [EULA](https://backpackforlaravel.com/eula)**; [PRO](https://backpackforlaravel.com/products/pro-for-unlimited-projects) adds additional functionality to CRUD, that will be useful when your admin panel grows (see our [FREE vs PRO comparison](https://backpackforlaravel.com/docs/6.x/features-free-vs-paid));
-- Of the other add-ons we've created, some are FREE and some are PAID; please see [our add-ons list](https://backpackforlaravel.test/docs/6.x/add-ons-official) for more info;
+- **Backpack CRUD is free & open-source, licensed under the [MIT License](https://github.com/Laravel-Backpack/CRUD/blob/main/LICENSE.md)**. It is perfect if you're building a simple admin panel - it's packed with features! It's also perfect if you're building an open-source project, the permissive license allows you to do whatever you want.
+- **Backpack PRO is a paid, closed-source add-on, licensed under our [EULA](https://backpackforlaravel.com/eula)**. [PRO](https://backpackforlaravel.com/products/pro-for-unlimited-projects) adds additional functionality to CRUD, which will be useful when your admin panel grows (see our [FREE vs PRO comparison](https://backpackforlaravel.com/docs/6.x/features-free-vs-paid)).
+- Of the other add-ons we've created, some are FREE and some are PAID. Please see [our add-ons list](https://backpackforlaravel.test/docs/6.x/add-ons-official) for more info.
[Our documentation](https://backpackforlaravel.com/docs) covers both CRUD and PRO, with all the PRO features clearly labeled PRO.
@@ -89,9 +89,9 @@ Backpack is open-core:
### Versioning, Updates and Upgrades
Starting with the previous version, all our packages follow [semantic versioning](https://semver.org/). Here's what `major.minor.patch` (e.g. `6.0.1`) means for us:
-- `major` - breaking changes, major new features, complete rewrites; released **once a year**, in February; it adds features that were previously impossible and upgrades our dependencies; upgrading is done by following our clear and detailed upgrade guides;
-- `minor` - new features, released in backwards-compatible ways; **every few months**; update takes seconds;
-- `patch` - bug fixes & small non-breaking changes; historically **every week**; update takes seconds;
+- `major` - breaking changes, major new features, complete rewrites; released **once a year**, in February. It adds features that were previously impossible and upgrades our dependencies; upgrading is done by following our clear and detailed upgrade guides.
+- `minor` - new features, released in backwards-compatible ways; **every few months**; update takes seconds.
+- `patch` - bug fixes & small non-breaking changes; historically **every week**; update takes seconds.
When we release a new Backpack\CRUD version, all paid add-ons receive support for it the same day.
@@ -100,15 +100,15 @@ When you buy a premium Backpack add-on, you get access to not only _updates_, bu
### Add-ons
-Backpack's core is open-source and free (Backpack\CRUD). FREE
+Backpack's core is open-source and free (Backpack\CRUD). **FREE**
The reason we've been able to build and maintain Backpack since 2016 is that Laravel professionals have supported us, by buying our paid products. As of 2022, these are all Backpack add-ons, which we highly recommend:
-- [Backpack PRO](/products/pro-for-unlimited-projects) - a crazy amount of added features; PAID
-- [Backpack DevTools](/products/devtools) - a developer UI for generating migrations, models and CRUDs; PAID
-- [Backpack FigmaTemplate](/products/figma-template) - quickly create designs and mockups, using Backpack's design; PAID
-- [Backpack EditableColumns](/products/editable-columns) - let your admins do quick edits, right in the table view; PAID
+- [Backpack PRO](/products/pro-for-unlimited-projects) - a crazy amount of added features; **PAID**
+- [Backpack DevTools](/products/devtools) - a developer UI for generating migrations, models and CRUDs; **PAID**
+- [Backpack FigmaTemplate](/products/figma-template) - quickly create designs and mockups, using Backpack's design; **PAID**
+- [Backpack EditableColumns](/products/editable-columns) - let your admins do quick edits, right in the table view; **PAID**
-In addition to our open-source core and our closed-source add-ons, there are a few other add-ons you might want to take a look at, that treat common use cases. Some have been developed by our core team, some by our wonderful community. You can just install interfaces to manage [site-wide settings](https://github.com/Laravel-Backpack/Settings), [the default Laravel users table](https://github.com/eduardoarandah/UserManager), [users, groups & permissions](https://github.com/Laravel-Backpack/PermissionManager), [content for custom pages, using page templates](https://github.com/Laravel-Backpack/PageManager), [news articles, categories and tags](https://github.com/Laravel-Backpack/NewsCRUD), etc. FREE
+In addition to our open-source core and our closed-source add-ons, there are a few other add-ons you might want to take a look at, that treat common use cases. Some have been developed by our core team, some by our wonderful community. You can just install interfaces to manage [site-wide settings](https://github.com/Laravel-Backpack/Settings), [the default Laravel users table](https://github.com/eduardoarandah/UserManager), [users, groups & permissions](https://github.com/Laravel-Backpack/PermissionManager), [content for custom pages, using page templates](https://github.com/Laravel-Backpack/PageManager), [news articles, categories and tags](https://github.com/Laravel-Backpack/NewsCRUD), etc. **FREE**
For more information, please see [our add-ons page](/addons).
diff --git a/6.x/upgrade-guide.md b/6.x/upgrade-guide.md
index d0884234..84866270 100644
--- a/6.x/upgrade-guide.md
+++ b/6.x/upgrade-guide.md
@@ -55,7 +55,8 @@ Please make sure your project respects the requirements below, before you start
"backpack/editable-columns": "^3.0",
"backpack/revise-operation": "^2.0",
"backpack/medialibrary-uploaders": "^1.0",
- "backpack/devtools": "^2.0",
+ "backpack/devtools": "^3.0",
+ "backpack/generators": "^4.0",
```
Step 3.1. We removed `PackageVersions` and the cache busting string is now handled by `Basset`.
@@ -81,7 +82,7 @@ When asked to install a theme, please choose the CoreUIv2 theme. It'll be easier
**No changes needed.** But there are a few improvements you _could_ make, if you want, that will help clean up your Models and move a bit of logic that might be admin-panel-only to the admin panel files:
-Step 4. (OPTIONAL) If you use acessors and mutators for upload fields, you can now use Uploaders instead. TODO: link to migration steps
+Step 4. (OPTIONAL) If you use acessors and mutators for upload fields, you can now [use Uploaders instead](/docs/{{version}}/crud-uploaders).
Step 5. (OPTIONAL) If you use accessors and mutators any other fields, you can [use Eloquent model events on fields](/docs/{{version}}/crud-operation-create#use-events-in-your-field-definition).
@@ -178,6 +179,10 @@ It's as easy as using an asset from a CDN, but it's much _much_ better than that
Step 18. **Have you developed any custom fields, columns, operations etc?** Rephrased: do you have anything inside your `resources/views/vendor/backpack/crud` directory? If so, we recommended you load your CSS & JS assets using `@basset('path/to/file.css')` instead of `@loadonce('path/to/file.css')` or ``. This will not only make sure that piece of JS/CSS/code is only loaded once per pageload, but it will also help serve all assets from one central location (your `storage/app/public` directory) which can be easily cleared using `php artisan basset:clear` to force cache-busting. You can find [more info about it here](https://github.com/laravel-backpack/basset).
+
+Step 18.B. If you have custom pages or custom operations, take particular note of the fact that the `backpack::` view namespace no longer exists. Most likely, when you try to use views from that namespace you will get an error saying "_No hint path defined for namespace [backpack]_". To fix this, the best solution is to change from using the namespace directly (eg. `@extends('backpack::blank')`) to using the backpack_view helper (eg. `@extends(backpack_view('blank'))`). That helper will make sure to load that blade file, from whatever theme is active right now (with fallback to the `vendor/backpack/ui` directory). Alternatively, if you only want to support ONE theme, you can replace that `backpack::` namespace with the namespace of the theme (eg. `backpack.theme-tabler::`).
+
+
----
Step 19. If you've published and overriden any CRUD blade files, please take a look at the changes, and re-do them in your files too. We've done quite a few changes, to account for different themes in v6. For custom components, a good way to make them pretty would be to copy-paste HTML from [Tabler](https://tabler.io/preview), [CoreUIv4](https://coreui.io/demos/bootstrap/4.2/free/), [Backstrap](https://backstrap.net/) (depending on what theme you've chosen to use) or straight out [Bootstrap](https://getbootstrap.com/docs/5.3/examples/). // TODO: link to diff
diff --git a/7.x-dev/base-components.md b/7.x-dev/base-components.md
index 8f61b769..dd5da5a9 100644
--- a/7.x-dev/base-components.md
+++ b/7.x-dev/base-components.md
@@ -30,8 +30,8 @@ All components also allow you to specify custom attributes. When you specify a c
Even though the 'target' attribute doesn't _technically_ exist in the component, that attribute will be placed on that component's `a` element.
-
-## Available Components
+
+## UI Components
### Menu Item
@@ -46,7 +46,6 @@ Note that you can further customize this using custom attributes. If you define
-
### Menu Separator
@@ -74,12 +73,293 @@ To show a dropdown menu, with elements, you can use the `menu-dropdown` and `men
```
-Notes:
-- on `menu-dropdown` you can define `nested="true"` to flag that dropdown as nested (aka. having a parent); so you can have dropdown in dropdown in dropdown;
+Notes:
+- on `menu-dropdown` you can define `nested="true"` to flag that dropdown as nested (aka. having a parent); so you can have dropdown in dropdown in dropdown;
- on both components, you can also define custom attributes; eg. if you define a `target` on one, that will be passed down to the `a` element;
+
+## Data Components
+
+These are the components that Backpack uses inside the default CRUD operations. Starting Backpack v7, they are exposed as components, so that you can also use them _outside_ the CrudControllers, or in your custom operations.
+
+
+
+### Dataform
+
+
+
+This component helps you show a form _anywhere you want_, so the admin can easily create or edit an entries for an Eloquent model. The dataform component is a extension of a CrudController - so a CrudController for that entity needs to be already set up, and passed to this component as a parameter:
+
+```html
+
+```
+
+**Configuration options:**
+- `operation='create'` - by default, the datatable component will pick up everything that controller sets up for the Create operation; if you want to change the operation it will initialize, you can pass this parameter;
+- `:entry="\App\Models\Invoice::find(1)"` - if you want to use UpdateOperation or a custom form operation that needs the entry;
+- `:setup="function($crud, $parent) {}"` - if you want to make changes to the operation setup (eg. add/remove fields, configure functionality), you can use this parameter; the closure passed here will be run _after_ the setup of that operation had already completed;
+- `:save-actions="[]"` - provide an array of save action definitions or save action classes to replace the defaults (see [Custom save actions](#dataform-custom-save-actions));
+- `:form-inside-card="true"` - render the form inside a Backpack card wrapper so it visually matches the default create/update screens; leave it `false` to output only the raw form markup.
+
+**Advanced example:**
+
+```html
+
+```
+
+
+#### Custom save actions
+
+The Dataform component can swap out the default `Save and back / edit / new` buttons with your own logic. Pass an array to the `:save-actions` attribute containing save action classes (or definitions) that implement Backpack's `SaveActionInterface`:
+
+```php
+@php
+ use App\Backpack\Crud\SaveActions\SaveAndApprove;
+ use Backpack\CRUD\app\Library\CrudPanel\SaveActions\SaveAndBack;
+@endphp
+
+
+```
+
+Each entry in the array can be:
+- an instance of a class that implements `SaveActionInterface` (recommended);
+- the fully qualified class name of a save action (the container will resolve it);
+- a plain array definition (see [`crud-save-actions.md`](crud-save-actions.md)).
+
+Backpack will replace the default actions for that form, honour the order defined by each class, and fallback to the first action if no default applies.
+
+
+
+
+### Dataform Modal
+
+
+
+This component helps you show a form _anywhere you want_ inside a modal, so the admin can easily create or edit an entry for an Eloquent model without having to refresh the whole page.
+
+To use this component you are required to add `CreateInModalOperation` and/or `UpdateInModalOperation` in your CrudController. The dataform modal component is a extension of a CrudController - so a CrudController for that entity needs to be already set up, and passed to this component as a parameter:
+
+First, in your CrudController, either remove `CreateOperation` in favor of `CreateInModalOperation`, or you can keep both operations. Having both of them is usefull if you want your ListOperation to still show the regular "Create" button, but you would like also to have the possibility to create this entity somewhere else in your application using a modal form.
+
+```php
+use \Backpack\DataformModal\Http\Controllers\Operations\CreateInModalOperation;
+```
+
+```html
+
+```
+
+**Configuration options:**
+- `operation='createInModal'` - by default, the component will pick up everything that controller sets up for the Create operation; if you want to change the operation it will initialize, you can pass this parameter, eg: `updateInModal`
+- `:entry="\App\Models\Invoice::find(1)"` - if you want to use UpdateInModalOperation or a custom form operation that needs the entry;
+- `:setup="function($crud, $parent) {}"` - if you want to make changes to the operation setup (eg. add/remove fields, configure functionality), you can use this parameter; the closure passed here will be run _after_ the setup of that operation had already completed;
+- `:save-actions="[]"` - replace the default modal buttons with your own save action classes.
+
+**Advanced example:**
+
+```html
+
+```
+
+
+> **NOTE**: The date_picker (jquery version) does not properly work in this context. Please use any alternative.
+
+
+### Datatable
+
+
+
+Useful if you want to show the entries in the database, for an Eloquent model. This component shows a datatable _anywhere you want_, so the admin to easily list, filter, search and perform other operations on entries of an Eloquent model. The datatable component is a extension of a CrudController - so a CrudController for that entity needs to be already set up, and passed to this component as a parameter:
+
+```html
+
+```
+
+**Configuration options:**
+- `name='invoices_datatable'` - by default, a name will be generated; but you can pick one you can recognize;
+- `operation='list'` - by default, the datatable component will pick up everything that controller sets up for the List operation; if you want to change the operation it will initialize, you can pass this parameter;
+- `:useFixedHeader="false"` - set this to explicitly enable or disable the sticky header; it defaults to the operation's `useFixedHeader` setting, falling back to `true`;
+- `:setup="function($crud, $parent) {}"` - if you want to make changes to the operation setup (eg. add/remove columns, configure functionality), you can use this parameter; the closure passed here will be run _after_ the setup of that operation had already completed;
+
+**Advanced example:**
+
+```html
+
+```
+
+
+
+
+### Datagrid
+
+
+
+Useful if you want to show the attributes of an entry in the database (the attributes of an Eloquent model). This components shows a grid view with all attributes that are configured using CRUD columns.
+
+There are two ways to use the Datagrid component:
+
+#### Datagrid for an existing CrudController
+
+Your datagrid will pick up the configuration in your CrudController automatically.
+
+
+```html
+
+```
+
+**Configuration options:**
+- `name='datagrid'` - by default, a name will be generated; but you can pick one you can recognize;
+- `operation='show'` - by default, the datagrid component will pick up everything that controller sets up for the Show operation; if you want to change the operation it will initialize, you can pass this parameter;
+- `:setup="function($crud, $entry) {}"` - if you want to make changes to the operation setup (eg. add/remove columns, configure functionality), you can use this parameter; the closure passed here will be run _after_ the setup of that operation had already completed;
+
+**Advanced example:**
+
+```html
+
+```
+
+#### Datagrid for an Eloquent entry
+
+If you want to show a datagrid component for a entity that does _not_ have a CrudController, you can do that too. But you have to manually specify the columns you want to be shown:
+
+```html
+
+```
+
+
+
+
+
+### Datalist
+
+
+
+Useful if you want to show the attributes of an entry in the database (the attributes of an Eloquent model). This components shows a table with all attributes that are configured using CRUD columns.
+
+There are two ways to use the Datalist component:
+
+#### Datalist for an existing CrudController
+
+Your datalist will pick up the configuration in your CrudController automatically.
+
+
+```html
+
+```
+
+**Configuration options:**
+- `name='invoices_datalist'` - by default, a name will be generated; but you can pick one you can recognize;
+- `operation='show'` - by default, the datalist component will pick up everything that controller sets up for the Show operation; if you want to change the operation it will initialize, you can pass this parameter;
+- `:setup="function($crud, $entry) {}"` - if you want to make changes to the operation setup (eg. add/remove columns, configure functionality), you can use this parameter; the closure passed here will be run _after_ the setup of that operation had already completed;
+
+**Advanced example:**
+
+```html
+
+```
+
+#### Datalist for an Eloquent entry
+
+If you want to show a datalist component for a entity that does _not_ have a CrudController, you can do that too. But you have to manually specify the columns you want to be shown:
+
+```html
+
+```
+
+
+
+
+
+## Syntaxes for Using Components
+
+All components that Backpack provides are available to use both using the "full namespace" syntax:
+
+```html
+
+```
+
+and using the slightly shorter "alias" syntax:
+
+```html
+
+```
+
+You can use whichever one you prefer. But please note that if you need to pass the components to a dynamic Laravel Blade component, only the "alias" syntax will work (eg. you will pass `:component='bp-datagrid'`). This is a limitation from Laravel, not Backpack.
+
+
## Overriding Default Components
diff --git a/7.x-dev/base-how-to.md b/7.x-dev/base-how-to.md
index 4b8efe38..8d2a90a1 100644
--- a/7.x-dev/base-how-to.md
+++ b/7.x-dev/base-how-to.md
@@ -6,6 +6,17 @@
## Look and feel
+
+### Text direction: LTR or RTL
+
+By default, the text direction is set to left-to-right. If your UI is in Arabic, Hebrew or any other language that needs to show right-to-left, you can easily enable that - just go to `config/backpack/ui.php` and change the `html_direction` variable to `rtl`:
+
+```
+ // Direction, according to language
+ // (left-to-right vs right-to-left)
+ 'html_direction' => 'ltr',
+```
+
### Customize the menu or sidebar
@@ -51,7 +62,7 @@ In order to place something else inside that view, like [widgets](/docs/{{versio
```
To use information from the database, you can:
-- [use view composers](https://laravel.com/docs/5.7/views#view-composers) to push variables inside this view, when it's loaded;
+- [use view composers](https://laravel.com/docs/views#view-composers) to push variables inside this view, when it's loaded;
- load all your dashboard information using AJAX calls, if you're loading charts, reports, etc, and the DB queries might take a long time;
- use the full namespace for your models, like ```\App\Models\Product::count()```;
@@ -290,7 +301,7 @@ This is a default in Backpack v4.
Backpack's authentication uses a completely separate authentication driver, provider, guard and password broker. They're all named ```backpack```, and registered in the vendor folder, invisible to you.
-If you need a separate login for user, just go ahead and create it. [Add the Laravel authentication, like instructed in the Laravel documentation](https://laravel.com/docs/5.7/authentication#authentication-quickstart): ```php artisan make:auth```. You'll then have:
+If you need a separate login for user, just go ahead and create it. [Add the Laravel authentication, like instructed in the Laravel documentation](https://laravel.com/docs/authentication#authentication-quickstart): ```php artisan make:auth```. You'll then have:
- the user login at ```/login``` -> using the AuthenticationController Laravel provides
- the admin login at ```/admin/login``` -> using the AuthenticationControllers Backpack provides
@@ -440,7 +451,7 @@ This will make the registration process pick up a view you can create, in ```res
In Backpack CRUD 6.2 we introduced the ability to require email verification when accessing Backpack routes. To enable this feature please do the following:
-**Step 1** - Make sure your user model (usually `App\Models\User`) implements the `Illuminate\Contracts\Auth\MustVerifyEmail` contract. [More info](https://laravel.com/docs/10.x/verification#model-preparation).
+**Step 1** - Make sure your user model (usually `App\Models\User`) implements the `Illuminate\Contracts\Auth\MustVerifyEmail` contract. [More info](https://laravel.com/docs/verification#model-preparation).
```php
+### Dataform
+
+Shows a dataform component from a particular CrudController. For more info about the configuration parameter, please see the [dataform component docs](/docs/{{version}}/base-components#dataform).
+
+```php
+[
+ 'type' => 'dataform',
+ 'controller' => 'App\Http\Controllers\Admin\InvoiceCrudController',
+ 'name' => 'invoice_form',
+ 'setup' => function($crud, $parent) {
+ // you can use this closure to modify your CrudController definition.
+ $crud->removeField('notes');
+ }
+]
+```
+
+
+### Chip
+
+Shows a chip blade view - which is useful to show more information about a database entry, using little screen real estate.
+
+```php
+[
+ 'type' => 'chip',
+ 'view' => 'crud::chips.general',
+ 'title' => 'invoices',
+ 'entry' => Invoice::first(),
+]
+```
+
+
+
+
+
+### Datatable
+
+Shows a datatable component from a particular CrudController. For more info about the configuration parameter, please see the [datatable component docs](/docs/{{version}}/base-components#datatable).
+
+```php
+[
+ 'type' => 'datatable',
+ 'controller' => 'App\Http\Controllers\Admin\PetShop\InvoiceCrudController',
+ 'name' => 'invoices',
+ 'setup' => function($crud, $parent) {
+ // you can use this closure to modify your CrudController definition.
+ if ($parent) {
+ $crud->addClause('where', 'owner_id', $parent->id);
+ }
+ }
+]
+```
+
+
+
### Div
@@ -367,7 +422,7 @@ Allows you to include multiple widgets within a "div" element with the attribute
]
```
-Anything you specify on this widget, other than ```type``` and ```content```, has to be a string, and will be considered an attribute of the "div" element.
+Anything you specify on this widget, other than ```type``` and ```content```, has to be a string, and will be considered an attribute of the "div" element.
For example, in the following snippet, ```class``` and ```custom-attribute``` are attributes of the "div" element:
```php
diff --git a/7.x-dev/crud-chips.md b/7.x-dev/crud-chips.md
new file mode 100644
index 00000000..4f571ba3
--- /dev/null
+++ b/7.x-dev/crud-chips.md
@@ -0,0 +1,268 @@
+# Chips
+
+---
+
+
+## About
+
+A chips helps show the information of a database entry, in a format that takes up little space visually. It can be used anywhere you want, but it's particularly useful inside operations to:
+- show more info inside a table cell in the **ListOperation**;
+- show a related item in more detail in the **ShowOperation**;
+
+A chip consists of only one file - a blade file with the same name as the chip type (ex: ```general.blade.php```). Backpack provides you with one chip type, that is very general (hence the name). This chip is designed to accomodate most types of database entries - but if your needs are more particular, you can easily [create an entirely new chip type](#creating-a-custom-chip-type).
+
+
+### Default Chip Types
+
+
+#### General Chip
+
+
+
+This chip was designed to be so general, that it's useful to show _most_ types of entries from the database. The general chip has 3 sections: `heading`, `image` and `details`. All sections are optional. Each of those sections has one mandatory attribute, `content`. Any other attributes you specify on those sections will be placed on that DOM element.
+
+Here's a very minimal usage of the general chip:
+
+```php
+@include('crud::chips.general', [
+ 'heading' => [
+ 'content' => 'John Doe',
+ ],
+ 'image' => [
+ 'content' => asset('uploads/person1.jpg'),
+ ],
+ 'details' => [
+ [
+ 'icon' => 'la la-hashtag',
+ 'content' => '8AH13A7',
+ ],
+ [
+ 'icon' => 'la la-envelope',
+ 'content' => 'john.doe@example.com',
+ ],
+ [
+ 'icon' => 'la la-phone',
+ 'content' => '+1 (555) 123-4567',
+ ]
+ ]
+])
+```
+
+But you can also specify more attributes, to enhance your chip with links, titles etc:
+
+```php
+@include('crud::chips.general', [
+ 'heading' => [
+ 'content' => 'John Doe',
+ 'href' => 'https://google.com/',
+ 'target' => '_blank',
+ 'title' => 'Example of a chip without URL',
+ ],
+ 'image' => [
+ 'content' => asset('uploads/person1.jpg'),
+ 'element' => 'a',
+ 'href' => 'https://chatgpt.com/',
+ 'target' => '_blank',
+ 'title' => 'Image can have its own URL, but why?! Falls back to the one in the heading',
+ ],
+ 'details' => [
+ [
+ 'icon' => 'la la-hashtag',
+ 'content' => '8AH13A7',
+ 'url' => 'mailto:john.doe@example.com',
+ 'title' => 'Click to email',
+ ],
+ [
+ 'icon' => 'la la-envelope',
+ 'content' => 'john.doe@example.com',
+ 'url' => 'mailto:john.doe@example.com',
+ 'title' => 'Click to email',
+ ],
+ [
+ 'icon' => 'la la-phone',
+ 'content' => '+1 (555) 123-4567',
+ 'url' => 'tel:+15551234567',
+ 'title' => 'Click to call',
+ ]
+ ]
+])
+```
+
+
+### How to use chips
+
+Depending on _where_ you want to use a chip, there are a few ways you can do that. Remember - a chip is a simple blade file, so the methods below should be pretty intuitive:
+
+
+#### How to use a chip inside a custom blade view
+
+If you want to load a chip inside a custom page, custom component or anything else custom, you can just include the blade view directly, and pass whatever attributes you want to show. For example, if you want to use the `general` chip you can just include that blade file, and pass some of the variables it supports:
+
+```php
+{{-- Example of General chip for a person, with data from a User model --}}
+@include('crud::chips.general', [
+ 'heading' => [
+ 'content' => $user->name,
+ 'href' => backpack_url('http://github.com/user/'.$user-%3Eid.'/show'),
+ 'title' => 'Click to preview',
+ ],
+ 'image' => [
+ 'content' => backpack_avatar_url(http://github.com/$user), // doesn't work well with dummy data
+ 'element' => 'a',
+ 'href' => backpack_url('http://github.com/user/'.$user-%3Eid.'/show'),
+ 'title' => 'Because of dummy data, this image is not available, but it would show a profile image',
+ ],
+ 'details' => [
+ [
+ 'icon' => 'la la-hashtag',
+ 'content' => $user->id,
+ 'url' => backpack_url('http://github.com/user/'.$user-%3Eid.'/show'),
+ 'title' => 'Click to preview',
+ ],
+ [
+ 'icon' => 'la la-envelope',
+ 'content' => $user->email,
+ 'url' => 'mailto:'.$user->email,
+ 'title' => 'Click to email',
+ ],
+ [
+ 'icon' => 'la la-calendar',
+ 'content' => $user->created_at->format('F j, Y'),
+ 'title' => 'Created at '.$user->created_at,
+ ]
+ ]
+])
+```
+
+
+#### How to use a chip as a datatable column
+
+
+
+When your datatables have too many columns, chips become particularly useful. They allow you to compress the info from 5 or more columns... into a single chip column. This improves the UX of big datatables - your admins will no longer have to expand the table row or use horizontal scrolling to see crucial info.
+
+Remember, a chip is just a simple blade file. So to use a chip as a column, we can just use the `view` column type, and pass the path to our chip file. For example:
+
+```php
+// after we create an `invoice` chip
+// we can use that chip as a column:
+CRUD::addColumn([
+ 'name' => 'info',
+ 'type' => 'view',
+ 'view' => 'crud::chips.invoice',
+]);
+```
+
+Now create that blade file, by running `php artisan backpack:chip invoice`. This will create a file in `resources/views/admin/chips` for you to edit, and customize as you like. By default, it just uses the `$entry` variable (which will be present if you use it as a column). You can include the `general` chip view if it's good enough for you, or copy-paste the HTML from the `general` chip, and modify it to your liking (you can run `php artisan backpack:chip invoice --from=general` to create a chip with all the HTML from general).
+
+Please note:
+- If your chip uses any info from RELATED items, you should probably eager load those items. For example if you're in an InvoiceCrudController you could do this in your `setupListOperation()` or hell maybe even in setup(): `CRUD::with(['event', 'event.production', 'event.venue', 'event.venue.city']);` - that way when your chip needs that info, it already has it onpage, and makes no extra queries;
+- By default, the view column type is not searchable. In order to make your chip columns searchable you need to [specify a custom ```searchLogic``` in your declaration](/docs/{{version}}/crud-columns#custom-search-logic).
+- By default, the view column type is not orderable. In order to make your chip columns orderable you need to [specify a custom ```orderLogic``` in your declaration](/docs/{{version}}/crud-columns#custom-order-logic).
+
+
+#### How to use a chip as a widget
+
+
+
+Chip files usually only contain the minimum content and styling necessary. You can include them as widgets directly, but they probably won't look very pretty on a custom page, because they don't have a background, borders, shadow etc. That's why we've also created a `chip` widget, which adds wrappers just like the other widgets - so that your chip will look good when placed on a custom page (or an existing CRUD page, why not).
+
+To use the `chip` widget, you can do:
+
+```php
+Widget::add()
+ ->to('after_content') // optional
+ ->type('chip')
+ ->view('crud::chips.owner')
+ ->title('Owner')
+ ->entry($owner);
+```
+
+
+
+
+## Overwriting Default Chip Types
+
+You can override a chip by create a file in ```resources\views\vendor\backpack\crud\chips``` with the same name. But it is NOT recommended to override the `general` chip type. When you do that, you're forfeiting any future updates for that chip. We can't push updates to a file that you're no longer using.
+
+In 99.9% of the cases, it's recommended NOT to override the default `general` chip file, but to create a _custom_ chip file. That will make it a lot easier to upgrade to newer versions of Backpack - because the file is completely in your control.
+
+
+
+
+## Creating a Custom Chip Type
+
+Chips consist of only one file - a blade file with the same name as the chip type (ex: ```person.blade.php```). You can create one by placing a new blade file inside ```resources\views\vendor\backpack\crud\chips```. Be careful to choose a distinctive name - usually the model name works best.
+
+To create a new chip file in the standard directory, you can run:
+- `php artisan backpack:chip {chip-name}` to create a new file in that directory, from our stub that assumes you want to use that chip inside the ListOperation and ShowOperation, so you'll be using the `$entry` variable to define what you want the chip to include;
+- `php artisan backpack:chip {chip-name} --from=general` to create a new file in that directory, from our `general` chip, so you can change the HTML however you want;
+
+For example, you can do `php artisan backpack:chip invoice` to create ```invoice.blade.php``` that helps you define what that chips includes:
+
+```php
+@php
+ $last_purchase = $entry->invoices()->orderBy('issuance_date', 'DESC')->first()->issuance_date;
+@endphp
+
+@include('crud::chips.general', [
+ 'heading' => [
+ 'content' => 'Invoice '.$entry->series.' '.$entry->number.' - '.$entry->owner->name,
+ 'href' => backpack_url('http://github.com/pet-shop/invoice/'.$entry-%3Eid.'/show'),
+ ],
+ 'details' => [
+ [
+ 'icon' => 'la la-dollar',
+ 'content' => $entry->total,
+ 'title' => 'Total invoice amount $'.$entry->total,
+ ],
+ [
+ 'icon' => 'la la-tags',
+ 'content' => $entry->items->count().' items',
+ ],
+ [
+ 'icon' => 'la la-calendar',
+ 'content' => $last_purchase->format('F j, Y'),
+ 'title' => 'Issuance date: '.$last_purchase,
+ ]
+ ]
+])
+```
+
+But you can also run `php artisan backpack:chip custom --from=general`, wipe everything inside the generated file, and include your own custom HTML, hardcoded or not:
+
+```html
+
+```
+
+Otherwise, you can create a completely custom chip, that looks and works differently from the `general` chip, and re-use that in your application. There are no limitations - since chips are simple blade files. Just copy-paste the HTML from the `general` chip and change it to match your needs.
diff --git a/7.x-dev/crud-columns.md b/7.x-dev/crud-columns.md
index f7956e27..a06774b3 100644
--- a/7.x-dev/crud-columns.md
+++ b/7.x-dev/crud-columns.md
@@ -208,6 +208,23 @@ Show connected items selected via checklist_dependency field. It's definition is
+
+### ckeditor PRO
+
+The perfect match for the [CKEditor field](https://github.com/Laravel-Backpack/ckeditor-field). The CKEditor column will just output the non-escaped text value of a db column (or model attribute). Its definition is simple:
+
+```php
+[
+ 'name' => 'info', // The db column name
+ 'label' => 'Info', // Table column heading
+ 'type' => 'ckeditor',
+],
+```
+
+For more information, please see [backpack/ckeditor-field](https://github.com/Laravel-Backpack/ckeditor-field) on Github - that is the add-on that provides this functionality.
+
+
+
### closure
@@ -429,6 +446,7 @@ Display database stored JSON in a prettier way to your users.
'label' => 'JSON',
'type' => 'json',
// 'escaped' => false, // echo using {!! !!} instead of {{ }}, in order to render HTML
+ 'toggle' => true //show a toggle button on the column that show/hide the json contents
],
```
@@ -818,6 +836,23 @@ The text column will just output the text value of a db column (or model attribu
+
+### tinymce PRO
+
+The perfect match for the [`tinymce` field](https://github.com/Laravel-Backpack/tinymce-field). The tinymce column will just output the non-escaped text value of a db column (or model attribute). Its definition is simple:
+```php
+[
+ 'name' => 'info', // The db column name
+ 'label' => 'Info', // Table column heading
+ 'type' => 'tinymce',
+],
+```
+
+For more information on the TinyMCE field and column, see [backpack/tinymce-field](
+The perfect match for the [`tinymce` field](https://github.com/Laravel-Backpack/tinymce-field)) on Github - that's the addon that provides this functionality.
+
+
+
### time
@@ -983,21 +1018,6 @@ Show a thumbnail image stored in the db column as `base64` image string.
-
-### ckeditor PRO
-
-The ckeditor column will just output the non-escaped text value of a db column (or model attribute). Its definition is:
-
-```php
-[
- 'name' => 'info', // The db column name
- 'label' => 'Info', // Table column heading
- 'type' => 'ckeditor',
-],
-```
-
-
-
### date_picker PRO
@@ -1363,21 +1383,6 @@ Its definition is very similar to the [table *field type*](/docs/{{version}}/cru
-
-### tinymce PRO
-
-The tinymce column will just output the non-escaped text value of a db column (or model attribute). Its definition is:
-
-```php
-[
- 'name' => 'info', // The db column name
- 'label' => 'Info', // Table column heading
- 'type' => 'tinymce',
-],
-```
-
-
-
### video PRO
@@ -1394,21 +1399,6 @@ Display a small screenshot for a YouTube or Vimeo video, stored in the database
-
-### wysiwyg PRO
-
-The wysiwyg column will just output the non-escaped text value of a db column (or model attribute). Its definition is:
-
-```php
-[
- 'name' => 'info', // The db column name
- 'label' => 'Info', // Table column heading
- 'type' => 'wysiwyg',
-],
-```
-
-
-
## Overwriting Default Column Types
@@ -1509,7 +1499,7 @@ $this->crud->addColumn([
'attribute' => 'name', // foreign key attribute that is shown to user
'orderable' => true,
'orderLogic' => function ($query, $column, $columnDirection) {
- return $query->leftJoin('categories', 'categories.id', '=', 'articles.select')
+ return $query->leftJoin('categories', 'categories.id', '=', 'articles.category_id')
->orderBy('categories.name', $columnDirection)->select('articles.*');
}
]);
diff --git a/7.x-dev/crud-fields.md b/7.x-dev/crud-fields.md
index 3f33283f..2bd742f6 100644
--- a/7.x-dev/crud-fields.md
+++ b/7.x-dev/crud-fields.md
@@ -383,6 +383,13 @@ Input preview:
+
+### ckeditor
+
+Show a WYSIWIG field to the user, powered by CKEditor. This field is provided as a first-party add-on - see instructions [here](https://github.com/Laravel-Backpack/ckeditor-field).
+
+
+
### color
@@ -839,7 +846,7 @@ Input preview:
### summernote
-Show a [Summernote wysiwyg editor](http://summernote.org/) to the user.
+Show a [Summernote WYSIWYG editor](http://summernote.org/) to the user.
```php
CRUD::field([ // Summernote
@@ -865,6 +872,9 @@ CRUD::field([
> NOTE: Summernote does NOT sanitize the input. If you do not trust the users of this field, you should sanitize the input or output using something like HTML Purifier. Personally we like to use install [mewebstudio/Purifier](https://github.com/mewebstudio/Purifier) and add an [accessor or mutator](https://laravel.com/docs/8.x/eloquent-mutators#accessors-and-mutators) on the Model, so that wherever the model is created from (admin panel or app), the output will always be clean. [Example here](https://github.com/Laravel-Backpack/demo/commit/7342cffb418bb568b9e4ee279859685ddc0456c1).
+#### Uploading files with summernote
+
+Summernote saves images as base64 encoded strings in the database. If you want to save them as files on the server, you can use the [Summernote Uploader](https://backpackforlaravel.com/docs/7.x/crud-uploaders). Please note that the Summernote Uploader is part of the `backpack/pro` package.
Input preview:

@@ -883,7 +893,7 @@ CRUD::field([ // Switch
'label' => 'I have not read the terms and conditions and I never will',
// optional
- 'color' => 'primary', // May be any bootstrap color class or an hex color
+ 'color' => '#232323', // in CoreUI v2 theme you can also specify bootstrap colors, like `primary`, `danger`, `success`, etc You can also overwrite the `--bg-switch-checked-color` css variable to change the color of the switch when it's checked
'onLabel' => '✓',
'offLabel' => '✕',
]);
@@ -963,6 +973,13 @@ CRUD::field([ // Time
+
+### tinymce
+
+Show a WYSIWYG editor powered by TinyMCE to the admin. This is provided using a first-party add-on - see instructions [here](https://github.com/Laravel-Backpack/tinymce-field).
+
+
+
### upload
@@ -1138,6 +1155,13 @@ CRUD::field([ // Address google
Using Google Places API is dependent on using an API Key. Please [get an API key](https://console.cloud.google.com/apis/credentials) - you do have to configure billing, but you qualify for $200/mo free usage, which covers most use cases. Then copy-paste that key as your ```services.google_places.key``` value.
+**IMPORTANT NOTE**: Your key needs access to the following APIS:
+- Maps JavaScript API;
+- Places API;
+- Geocoding API.
+
+While developing you can use an "unrestricted key" (no restrictions for where the key is used), but for production you should use a separate key, and **MAKE SURE** you restrict the usage of that key to your own domain.
+
So inside your ```config/services.php``` please add the items below:
```php
'google_places' => [
@@ -1186,13 +1210,6 @@ Input preview:
-
-### ckeditor
-
-This field is providedy by a third-party integration, you can find instructions on how to install and use it [here](https://github.com/Laravel-Backpack/ckeditor-field).
-
-
-
### date_range PRO
@@ -1423,6 +1440,13 @@ Using Google Places API is dependent on using an API Key. Please [get an API key
],
```
+**IMPORTANT NOTE**: Your key needs access to the following APIS:
+- Maps JavaScript API;
+- Places API;
+- Geocoding API.
+
+While developing you can use an "unrestricted key" (no restrictions for where the key is used), but for production you should use a separate key, and **MAKE SURE** you restrict the usage of that key to your own domain.
+
**How to save in multiple inputs?**
There are cases where you rather save the information on separate inputs in the database. In that scenario you should use [Laravel mutators and accessors](https://laravel.com/docs/10.x/eloquent-mutators). Using the same field as previously shown (**field name is `location`**), and having `latitude`, `longitude`, `full_address` as the database columns, we can save and retrieve them separately too:
@@ -2527,13 +2551,6 @@ Input preview:

-
-
-
-### tinymce
-
-TinyMCE is now provided by a third-party package, you can find instructions on how to use and configure it [here](https://github.com/Laravel-Backpack/tinymce-field).
-
@@ -2567,29 +2584,6 @@ So you should use [attribute casting](https://mattstauffer.com/blog/laravel-5.0-
Vimeo does not require an API key in order to query their DB, but YouTube does, even though their free quota is generous. You can get a free YouTube API Key inside [Google Developers Console](https://console.developers.google.com/) ([video tutorial here](https://www.youtube.com/watch?v=pP4zvduVAqo)). Please DO NOT use our API Key - create your own. The key above is there just for your convenience, to easily try out the field. As soon as you decide to use this field type, create an API Key and use _your_ API Key. Our key hits its ceiling every month, so if you use our key most of the time it won't work.
-
-
-
-### wysiwyg PRO
-
-Show a wysiwyg (CKEditor) to the user.
-
-```php
-CRUD::field([ // WYSIWYG Editor
- 'name' => 'description',
- 'label' => 'Description',
- 'type' => 'wysiwyg',
-
- // optional configuration
- 'options' => [], // ckeditor configuration options
-
- // elfinder configuration options when using [the file manager package](https://github.com/Laravel-Backpack/FileManager)
- // to use this feature you need to be running backpack/pro:2.2.1 or higher and backpack/filemanager:3.0.8 or higher
- // for `elfinderOptions` passing an empty array or `true` will enable the file manager with default options
- 'elfinderOptions' => [],
-]);
-```
-
## Overwriting Default Field Types
diff --git a/7.x-dev/crud-filters.md b/7.x-dev/crud-filters.md
index 205e3154..29a2bcd0 100644
--- a/7.x-dev/crud-filters.md
+++ b/7.x-dev/crud-filters.md
@@ -621,6 +621,100 @@ CRUD::filter('trashed')
## Tips and Tricks
+
+### Use Filters on custom admin panel pages
+
+Filters can be added to any admin panel page, not just the main CRUD table. Imagine that you want to have a dashboard page, with a few widgets that show some data. You can add filters to that page, and use them to filter the data shown in the widgets.
+
+
+
+
+You start by [creating a new page](/docs/{{version}}/base-about#custom-pages-1) to hold your custom content, eg: a reports page.
+
+```bash
+php artisan backpack:page Reports
+```
+
+To use filters on a custom admin panel page, you should edit the blade file (in this example the `resources/views/admin/reports.blade.php` file) to **add the filters navbar** and **the event listeners**:
+```diff
+@extends(backpack_view('blank'))
+
+@section('content')
+
+
Reports
+
Page for Reports
+
+
+
+
+
+
++ @include('crud::inc.filters_navbar')
+
+
+
+
+@endsection
+
++@push('after_scripts')
++
++@endpush
+```
+
+After that, time to add your own filters in your controller (in this example, `ReportsController.php`):
+
+```php
+class ReportsController extends Controller
+{
+ public function index()
+ {
+ $crud = app('crud');
+
+ $crud->addFilter([
+ 'type' => 'simple',
+ 'name' => 'checkbox',
+ 'label' => 'Simple',
+ ], false);
+
+ $crud->addFilter([ // dropdown filter
+ 'name' => 'select_from_array',
+ 'type' => 'dropdown',
+ 'label'=> 'Dropdown',
+ ], ['one' => 'One', 'two' => 'Two', 'three' => 'Three']);
+
+ return view('admin.reports', [
+ 'title' => 'Reports',
+ 'breadcrumbs' => [
+ trans('backpack::crud.admin') => backpack_url('http://github.com/dashboard'),
+ 'Reports' => false,
+ ],
+ 'crud' => $crud,
+ ]);
+ }
+}
+```
+
+That's it, you should now have the filters navbar on your reports page. You can use the event listeners to update the data shown on the page based on the filters selected by the user.
+Here are the Javascript events you can listen to:
+- `backpack:filter:changed` when a filter is changed;
+- `backpack:filter:cleared` when a filter is cleared;
+- `backpack:filters:cleared` when all filters are cleared;
+
### Add a debounce time to filters
@@ -639,7 +733,7 @@ CRUD::filter('name')
All filter types accept a `debounce`, like for example the simple filter, range filter etc.
-### Adding a filter using array syntax
+### Add a filter using array syntax
In Backpack v4-v5 we used an "array syntax" to add and manipulate filters. That syntax is still supported for backwards-compatiblity. But it most cases it's easier to use the fluent syntax.
diff --git a/7.x-dev/crud-operation-fetch.md b/7.x-dev/crud-operation-fetch.md
index 2685f7b3..cc13a988 100644
--- a/7.x-dev/crud-operation-fetch.md
+++ b/7.x-dev/crud-operation-fetch.md
@@ -84,6 +84,32 @@ public function fetchUser() {
}
```
+**Adding attributes to fetched models without appends**
+
+It's already possible to add attributes to the fetched models using the `appends` property in the model. However, this method has some drawbacks, like the fact that the appended attributes will be added to all instances of the model, whenever they are used, not only when they are fetched. If you want to add attributes to the fetched models without using the `appends` property in the model, you can use the `append_attributes` in the fetch configuration. For example:
+
+```php
+public function fetchUser() {
+ return $this->fetch([
+ 'model' => User::class,
+ 'append_attributes' => ['something'],
+ ]);
+ }
+
+// User.php model
+public function something(): Attribute
+{
+ return Attribute::make(
+ get: function (mixed $value, array $attributes) {
+ return $attributes['something_else'];
+ },
+ );
+}
+
+// and in your field definition
+CRUD::field('my_ajax_field')->attribute('something');
+```
+
## Using FetchOperation with `select2_ajax` filter
diff --git a/7.x-dev/crud-operations.md b/7.x-dev/crud-operations.md
index 459b393c..baf14bbe 100644
--- a/7.x-dev/crud-operations.md
+++ b/7.x-dev/crud-operations.md
@@ -179,6 +179,123 @@ Inside a ```setupOperationNameRoutes()```, you'll notice that's also where we de
Once an operation name has been set using that route, you can do ```$crud->getOperation()``` inside your views and do things according to this.
+
+## Operation Lifecycle
+
+When making customizations to existing operations or creating custom operations, it's important to understand how Backpack loads operations in the first place. Let's take it from the top, with a practical example. Backpack CRUDs follow the simple MVC pattern (Model-View-Controller):
+- a route points to a CrudController (eg. `Route::crud('article', 'ArticleCrudController')`)
+- that `ArticleCrudController` then loads operations as traits eg. `use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation;`
+
+Inside `DeleteOperation` (or any other operation) you will typically have these at least three methods, including `setupXxxRoutes()` and `setupXxxDefaults()` methods:
+
+```php
+
+trait DeleteOperation
+{
+ // Defines which routes are needed for the operation
+ protected function setupDeleteRoutes($segment, $routeName, $controller) {}
+
+ // Add the default settings, buttons, etc that this operation needs.
+ protected function setupDeleteDefaults() {}
+
+ // Custom methods, that the routes registered above call
+ public function destroy($id) {}
+}
+```
+
+When do these get called? Well:
+- `setupDeleteRoutes()` gets called _when routes are being set up_; if your CRUD routes are defined in `routes/backpack/custom.php` like our convention, then _that_ is when those methods are called;
+- `setupDeleteDefaults()` and all other methods in the CrudController get called when the request is processed; let's get deeper into that;
+
+When a request to `example.com/admin/article` gets made:
+- Laravel will setup all routes; that includes the CRUD routes, so it will call all setupXxxRoutes methods, in all operation traits, used on all CrudControllers);
+- Laravel will identify that the route points to a particular CrudController, and a particular method inside that controller (in our example, `DeleteOperation::destroy`, used inside `ArticleCrudController`); so it will instantiate the ArticleCrudController;
+- when `ArticleCrudController` gets instantiate, its `parent::__construct()` method will set up the operation for you; and it will do it in the following order:
+
+1. CrudController will set up the operation defaults (by calling `DeleteOperation::setupDeleteDefaults()`);
+2. CrudController will call the `ArticleController::setup()`, to allow you as a developer to set up all operation in one place. It's discouraged to use the `setup()` method for that - in practice it's much cleaner to have a setup method for each operation.
+3. CrudController will call the `ArticleController::setupDeleteOperation()` method, if present, to allow the developer to configure that operation;
+
+This means you can think of the Operation lifecycle of having the following "lifecycle events":
+- the operation routes being set up
+- the defaults being set up
+- the operation being set up (aka configured by developer)
+
+Understanding these moments and their order, is important in order to place your custom logic _in the right place_ and _at the right time_ in the operation lifecycle.
+
+
+### Lifecycle Hooks
+
+At important points in the CRUD Lifecycle, Backpack triggers what we call "_lifecycle events_". You can hook into those events - by registering custom code that will run when that lifecycle event happens. This allows you to customize the process, without having to override any of the core files for that CRUD or Operation.
+
+For example, in a Backpack CRUD all routes are setup on the **CrudController** using methods like `setupModerateOperationRoutes()`. Before those methods are called, Backpack triggers an event called `crud:before_all_route_setup`. If you want to add your own code that runs there, you can do:
+
+```php
+use Backpack\CRUD\app\Library\CrudPanel\Hooks\Facades\LifecycleHook;
+
+LifecycleEvent::hookInto('crud:before_setup_routes', function($controller) {
+ // do something before the routes are setup
+});
+```
+
+#### General Lifecycle Events
+
+Here are all the general lifecycle events Backpack triggers:
+
+- `crud:before_setup_routes` - before any operation routes are registered
+- `crud:after_setup_routes` - after all operation routes have been registered
+- `crud:before_setup_defaults` - before all defaults are setup
+- `crud:after_setup_defaults` - after all defaults have been setup
+- `crud:before_setup` - before any operation is set up
+- `crud:after_setup` - after that operation has been set up
+
+
+#### Operation Lifecycle Events
+
+In addition to the general Lifecycle events above, each operation can trigger its own lifecycle events. For example, here are the lifecycle events triggered by the Create operation:
+
+`create:before_setup` - exposes parameters: $crud
+`create:after_setup` - exposes parameters: $crud
+
+You can hook into those events using a similar syntax to the general lifecycle events:
+
+```php
+LifecycleEvent::hookInto(['create:before_setup'], function() {
+ $this->crud->addButton('top', 'create', 'view', 'crud::buttons.create');
+});
+```
+
+Note that when using the hooks for specific operations, the hook is prefixed with the operation name followed by the hook name. This allow you to hook into specific operation events, or even to multiple events at the same time:
+
+```php
+LifecycleEvent::hookInto(['create:before_setup', 'list:before_setup'], function() {
+ // do something before the create operation and the list operation are setup
+});
+```
+
+
+### How to add your own hooks
+
+You can add your own lifecycle events to your custom operations by calling the `LifecycleEvent::trigger()` method at the appropriate points in your operation. For example, if you have a custom operation that need to do something after some action happens in the operation, you can trigger a lifecycle event like this:
+
+```php
+public function moderate() {
+ // do something to "moderate" the entry and register the hook
+ LifecycleEvent::trigger('moderate:after_moderation', [
+ 'controller' => $this,
+ 'operation' => 'moderate',
+ ]);
+}
+```
+
+Then, other developers can hook into that event like this:
+
+```php
+LifecycleEvent::hookInto(['moderate:after_moderation'], function($controller, $operation) {
+ // do something after the moderate operation has been executed
+});
+```
+
## Creating a Custom Operation
diff --git a/7.x-dev/crud-save-actions.md b/7.x-dev/crud-save-actions.md
index 4fb61c85..679aac24 100644
--- a/7.x-dev/crud-save-actions.md
+++ b/7.x-dev/crud-save-actions.md
@@ -16,6 +16,91 @@ There are four save actions registered by Backpack by default. They are:
- ```save_and_new``` (Save and go to create new entity page)
- ```save_and_preview``` (Save and go to show the current entity)
+
+## Save Action Classes
+
+Save actions are now first-class citizens. Instead of maintaining large array definitions in each CrudController, you can encapsulate the behaviour inside PHP classes that implement `Backpack\CRUD\app\Library\CrudPanel\SaveActions\SaveActionInterface`. Backpack ships with `SaveAndBack`, `SaveAndEdit`, `SaveAndNew`, and `SaveAndPreview` as examples, and also provides `SaveAndList` for projects that want an explicit "Save and go to list" button.
+
+### Quick start
+
+1. **Create a class** inside your application (for example `app/Backpack/Crud/SaveActions/SaveAndApprove.php`).
+2. **Extend** `AbstractSaveAction` (recommended) or implement `SaveActionInterface` directly.
+3. **Override** the methods that describe your button.
+4. **Register** the class with `CRUD::addSaveAction()` / `CRUD::replaceSaveActions()` or pass it to Blade components like ``.
+
+```php
+hasAccess('update') && $crud->entry?->canBeApproved();
+ }
+
+ public function getRedirectUrl(CrudPanel $crud, Request $request, $itemId = null): ?string
+ {
+ return route('admin.invoices.approve', $itemId ?? $request->input('id'));
+ }
+}
+```
+
+> **Tip:** `AbstractSaveAction` already implements `toArray()`, order handling, and sensible defaults. Override only what you need. If you must store additional data, you can still return a custom array by implementing `SaveActionInterface` yourself.
+
+### Registering class-based actions
+
+Inside your CrudController you can now pass the class instead of an array:
+
+```php
+use App\Backpack\Crud\SaveActions\SaveAndApprove;
+
+CRUD::replaceSaveActions([
+ new SaveAndApprove(),
+ \Backpack\CRUD\app\Library\CrudPanel\SaveActions\SaveAndBack::class,
+]);
+```
+
+Backpack recognizes three inputs when registering save actions:
+- an instantiated save action class;
+- the fully qualified class name (it is resolved via the container so dependencies can be injected);
+- the legacy associative array definition (still supported).
+
+The action `order` is taken from the class (or array) and Backpack reorders conflicts automatically. If you need to adjust the order later you can still call `CRUD::orderSaveActions()`.
+
+### Using classes in Blade components
+
+The `bp-dataform` component accept save action classes through the `:save-actions` attribute. This allows you to reuse the same custom buttons outside CrudControllers:
+
+```php
+
+```
+
+When no save actions are provided, Backpack falls back to the defaults registered on the controller.
+
## Save Actions API
diff --git a/7.x-dev/crud-uploaders.md b/7.x-dev/crud-uploaders.md
index 2b49ef32..e5089291 100644
--- a/7.x-dev/crud-uploaders.md
+++ b/7.x-dev/crud-uploaders.md
@@ -5,12 +5,12 @@
## About
-Uploading and managing files is a common task in Admin Panels. Starting with Backpack v6, you can fully setup your upload fields in your field definition, using purpose-built classes we call Uploaders. No more need to create mutators, manual validation of input or custom code to handle the files - though you can still do that, if you want.
+Uploading and managing files is a common task in Admin Panels. In Backpack v7, your field definition can include uploading logic, thanks to some classes we call Uploaders. You don't need to create mutators, manual validation of input or custom code to handle file upload - though you can still do that, if you want.
-
-## How it works
+
+## How to Use Uploaders
-When adding an upload field (`upload`, `upload_multiple`, `image` or `dropzone`) to your operation, tell Backpack that you want to use the appropriate Uploader, by using `withFiles()`:
+When adding an upload field (`upload`, `upload_multiple`, `image`, `dropzone`, `easymde`, `summernote`) to your operation, tell Backpack that you want to use the appropriate Uploader, by using `withFiles()`:
```php
CRUD::field('avatar')->type('upload')->withFiles();
@@ -23,8 +23,8 @@ That's it. Backpack will now handle the upload, storage and deletion of the file
> - (*) If you want your files to be deleted when the entry is deleted, please [Configure File Deletion](#deleting-files-when-entry-is-deleted)
-
-## Configuring the Uploaders
+
+## How to Configure Uploaders
The `withFiles()` method accepts an array of options that you can use to customize the upload.
@@ -56,6 +56,177 @@ This allows you to overwrite or set the uploader class for this field. You can u
- **`fileNamer`** - default: **null**
It accepts a `FileNameGeneratorInterface` instance or a closure. As the name implies, this will be used to generate the file name. Read more about in the [Naming uploaded files](#upload-name-files) section.
+
+## Available Uploaders
+
+We've already created Uploaders for the most common scenarios:
+- CRUD comes with `SingleFile`, `MultipleFiles`, `SingleBas64Image`
+- PRO comes with `DropzoneUploader`, `EasyMDEUploader`, `SummernoteUploader`
+- if you want to use spatie/medialibrary you can just install [medialibrary-uploaders](https://github.com/Laravel-Backpack/medialibrary-uploaders) to get `MediaAjaxUploader`, `MediaMultipleFiles`, `MediaSingleBase64Image`, `MediaSingleFile`
+
+
+
+## How to Create Uploaders
+
+Do you want to create your own Uploader class, for your custom field? Here's how you can do that, and how Uploader classes work behind the scenes.
+
+First thing you need to decide if you are creating a _non-ajax_ or _ajax_ uploader:
+- _non-ajax_ uploaders process the file upload when you submit your form;
+- _ajax_ uploaders process the file upload before the form is submitted, by submitting an AJAX request using Javascript;
+
+
+### How to Create a Custom Non-Ajax Uploader
+
+First let's see how to create a non-ajax uploader, for that we will create a `CustomUploader` class that extends the abstract class `Uploader`.
+
+```php
+namespace App\Uploaders\CustomUploader;
+
+use Backpack\CRUD\app\Library\Uploaders\Uploader;
+
+class CustomUploader extends Uploader
+{
+ // the function we need to implement
+ public function uploadFiles(Model $entry, $values)
+ {
+ // $entry is the model instance we are working with
+ // $values is the sent files from request.
+
+ // do your upload logic here
+
+ return $valueToBeStoredInTheDatabaseEntry;
+ }
+
+ // this is called when your uploader field is a subfield of a repeatable field. In here you receive
+ // the sent values in the current request and the previous repeatable values (only the uploads values).
+ protected function uploadRepeatableFiles($values, $previousValues)
+ {
+ // you should return an array of arrays (each sub array is a repeatable row) where the array key is the field name.
+ // backpack will merge this values along the other repeatable fields and save them in the database.
+ return [
+ [
+ 'custom_upload' => 'path/file.jpg'
+ ],
+ [
+ 'custom_upload' => 'path/file.jpg'
+ ]
+ ];
+ }
+}
+```
+
+You can now use this uploader in your field definition:
+
+```php
+CRUD::field('avatar')->type('upload')->withFiles([
+ 'uploader' => \App\Uploaders\CustomUploader::class,
+]);
+```
+
+If you custom uploader was created to work for a custom field (say it's called `custom_upload`), you can tell Backpack to always use this uploader for that field type - that way you don't have to specify it every time you use the field. You can do that in your Service Provider `boot()` method, by adding it to the `UploadersRepository`:
+
+```php
+// in your App\Providers\AppServiceProvider.php
+
+protected function boot()
+{
+ app('UploadersRepository')->addUploaderClasses(['custom_upload' => \App\Uploaders\CustomUploader::class], 'withFiles');
+}
+```
+
+You can now use `CRUD::field('avatar')->type('custom_upload')->withFiles();` and it will use your custom uploader. What happens behind the scenes is that Backpack will register your uploader to run on 3 different model events: `saving`, `retrieved` and `deleting`.
+
+The `Uploader` class has 3 "entry points" for the mentioned events: **`storeUploadedFiles()`**, **`retrieveUploadedFiles()`** and **`deleteUploadedFiles()`**. You can override these methods in your custom uploader, but typically you will not need to do that. The methods already delegate what will happen to the relevant methods (eg. if it's not a repeatable, call ```uploadFiles()```, othewise call ```uploadRepeatableFiles()```).
+
+Notice this custom class you're creating is extending `Backpack\CRUD\app\Library\Uploaders\Uploader`. That base uploader class has most of the functionality implemented and uses **"strategy methods"** to configure the underlying behavior.
+
+**`shouldUploadFiles`** - a method that returns a boolean to determine if the files should be uploaded. By default it returns true, but you can overwrite it to add your custom logic.
+
+**`shouldKeepPreviousValuesUnchanged`** - a method that returns a boolean to determine if the previous values should be kept unchanged and not perform the upload.
+
+**`hasDeletedFiles`** - a method that returns a boolean to determine if the files were deleted from the field.
+
+**`getUploadedFilesFromRequest`** - this is the method that will be called to get the values sent in the request. Some uploaders require you get the `->files()` others the `->input()`. By default it returns the `->files()`.
+
+This is the implementation of those methods in `SingleFile` uploader:
+```php
+protected function shouldKeepPreviousValueUnchanged(Model $entry, $entryValue): bool
+{
+ // if a string is sent as the value, it means the file was not changed so we should keep
+ // previous value unchanged
+ return is_string($entryValue);
+}
+
+protected function hasDeletedFiles($entryValue): bool
+{
+ // if the value is null, it means the file was deleted from the field
+ return $entryValue === null;
+}
+
+protected function shouldUploadFiles($value): bool
+{
+ // when the value is an instance of UploadedFile, it means the file was uploaded and we should upload it
+ return is_a($value, 'Illuminate\Http\UploadedFile', true);
+}
+
+
+### How to Create a Custom Ajax Uploader
+
+For the ajax uploaders, the process is similar, but your custom uploader class should extend `BackpackAjaxUploader` instead of `Uploader` (**note that this requires backpack/pro**).
+
+```php
+
+namespace App\Uploaders\CustomUploader;
+
+use Backpack\Pro\Uploaders\BackpackAjaxUploader;
+
+class CustomUploader extends BackpackAjaxUploader
+{
+ // this is called on `saving` event of the main entry, at this point you already performed the upload
+ // of the files in the ajax endpoint. By default they are in a temp folder, so here is the place
+ // where you should move them to the final disk and path and setup what will be saved in the database.
+ public function uploadFiles(Model $entry, $values)
+ {
+ return $valueToBeStoredInTheDatabaseEntry;
+ }
+
+ // this is called when your uploader field is a subfield of a repeatable field. In here you receive
+ // the sent values in the current request and the previous repeatable values (only the uploads values).
+ protected function uploadRepeatableFiles($values, $previousValues)
+ {
+ // you should return an array of arrays (each sub array is a repeatable row) where the array key is the field name.
+ // backpack will merge this values along the other repeatable fields and save them in the database.
+ return [
+ [
+ 'custom_upload' => 'path/file.jpg'
+ ],
+ [
+ 'custom_upload' => 'path/file.jpg'
+ ]
+ ];
+ }
+}
+```
+
+The process to register the uploader in the `UploadersRepositoy` is the same as the non-ajax uploader. `app('UploadersRepository')->addUploaderClasses(['custom_upload' => \App\Uploaders\CustomUploader::class], 'withFiles');` in the boot method of your provider.
+
+In addition to the field configuration, ajax uploaders require that you use the `AjaxUploadOperation` trait in your controller. The operation is responsible to register the ajax route where your files will be sent and the upload process will be handled and the delete route from where you can delete **temporary files**.
+
+Similar to model events, there are two "setup" methods for those endpoints: **`processAjaxEndpointUploads()`** and **`deleteAjaxEndpointUpload()`**. You can overwrite them to add your custom logic but most of the time you will not need to do that and just implement the `uploadFiles()` and `uploadRepeatableFiles()` methods.
+
+The ajax uploader also has the same "strategy methods" as the non-ajax uploader (see above), but adds a few more:
+- **`ajaxEndpointSuccessResponse($files = null)`** - This should return a `JsonResponse` with the needed information when the upload is successful. By default it returns a json response with the file path.
+- **`ajaxEndpointErrorResponse($message)`** - Use this method to change the endpoint response in case the upload failed. Similar to the success it should return a `JsonResponse`.
+- **`getAjaxEndpointDisk()`** - By default a `temporaryDisk` is used to store the files before they are moved to the final disk (when uploadFiles() is called). You can overwrite this method to change the disk used.
+- **`getAjaxEndpointPath()`** - By default the path is `/temp` but you can override this method to change the path used.
+- **`getDefaultAjaxEndpointValidation()`** - Should return the default validation rules (in the format of `BackpackCustomRule`) for the ajax endpoint. By default it returns a `ValidGenericAjaxEndpoint` rule.
+
+
+For any other customization you would like to perform, please check the source code of the `Uploader` and `BackpackAjaxUploader` classes.
+
+
+## FAQ about Uploaders
+
### Handling uploads in relationship fields
@@ -184,6 +355,22 @@ class SomeModel extends Model
}
```
+
+## Deleting temporary files
+
+When using ajax uploaders, the files are uploaded to a temporary disk and path before being moved to the final disk and path. If by some reason the user does not finish the operation, those files may lay around in your server temporary folder.
+To delete them, we have created a `backpack:purge-temporary-folder` command that you can schedule to run every day, or in the time frame that better suits your needs.
+
+```php
+// in your routes/console
+use Illuminate\Console\Scheduling\Schedule;
+
+Schedule::command('backpack:purge-temporary-folder')->daily();
+
+```
+
+For additional configuration check the `config/backpack/operations/ajax-uploads.php` file. Those configurations can also be passed on a "per-command" basis, eg: `backpack:purge-temporary-folder --disk=public --path=temp --older-than=5`.
+
### Configuring uploaders in custom fields
diff --git a/7.x-dev/index.md b/7.x-dev/index.md
index cb6360d6..c46ebe04 100644
--- a/7.x-dev/index.md
+++ b/7.x-dev/index.md
@@ -16,7 +16,7 @@
- [3. Advanced Features](/docs/{{version}}/getting-started-advanced-features)
- [4. Add-ons, License & Support](/docs/{{version}}/getting-started-license-and-support)
- [Tutorials](/docs/{{version}}/tutorials)
-
+
#### Admin UI
- [About](/docs/{{version}}/base-about)
@@ -36,6 +36,7 @@
+ [Columns](/docs/{{version}}/crud-columns)
+ [Buttons](/docs/{{version}}/crud-buttons)
+ [Filters](/docs/{{version}}/crud-filters)
+ + [Chips](/docs/{{version}}/crud-chips)
+ [Create](/docs/{{version}}/crud-operation-create) & [Update](/docs/{{version}}/crud-operation-update)
+ [Fields](/docs/{{version}}/crud-fields)
+ [Save Actions](/docs/{{version}}/crud-save-actions)
@@ -44,6 +45,7 @@
+ [Delete](/docs/{{version}}/crud-operation-delete)
+ [Show](/docs/{{version}}/crud-operation-show)
+ [Columns](/docs/{{version}}/crud-columns)
+ + [Chips](/docs/{{version}}/crud-chips)
- [Additional Operations](/docs/{{version}}/crud-operations)
+ [Clone](/docs/{{version}}/crud-operation-clone)
+ [Reorder](/docs/{{version}}/crud-operation-reorder)
diff --git a/7.x-dev/installation.md b/7.x-dev/installation.md
index 8fc6859d..b6e6197d 100644
--- a/7.x-dev/installation.md
+++ b/7.x-dev/installation.md
@@ -5,11 +5,11 @@
## Requirements
-If you can run Laravel 10 or 11, you can install Backpack. Backpack does _not_ have additional requirements.
+If you can run Laravel 12, you can install Backpack. Backpack does _not_ have additional requirements.
For the following process, we assume:
-- you have a [working installation of Laravel](https://laravel.com/docs/11.x#installation) (an existing project is fine, you don't need a *fresh* Laravel install);
+- you have a [working installation of Laravel](https://laravel.com/docs/12.x#installation) (an existing project is fine, you don't need a *fresh* Laravel install);
- you have configured your .ENV file with your database and mail information;
@@ -24,7 +24,14 @@ For the following process, we assume:
Go to your Laravel project's directory, then in your terminal, run:
``` bash
-composer require backpack/crud
+# during beta, configure your Composer.json to accept unstable version, by running:
+composer config minimum-stability dev
+composer config prefer-stable true
+
+# then require the v7-beta:
+composer require backpack/crud:"^7.0@dev"
+
+# and finally, install Backpack:
php artisan backpack:install
```
diff --git a/7.x-dev/introduction.md b/7.x-dev/introduction.md
index 02ca3170..3ea33a23 100644
--- a/7.x-dev/introduction.md
+++ b/7.x-dev/introduction.md
@@ -6,8 +6,8 @@ Backpack is a collection of Laravel packages that help you **build custom admini
In a nutshell:
-- UI - Backpack will provide you with a _visual interface_ for the admin panel (the HTML, the CSS, the JS), authentication functionality & global bubble notifications; you can choose from one of the 3 themes we have developed (powered by Tabler, CoreUI v4 or CoreUI v2), a third-party theme or create your own theme; the enormous advantage of using a Bootstrap-based HTML theme is that when you need custom pages, you already have the HTML blocks for the UI, you don't have to design them yourself;
-- CRUDs - Backpack will also help you build _sections where your admins can manipulate entries for Eloquent models_; we call them _CRUD Panels_ after the most basic operations: Create, Read, Update & Delete; after [understanding Backpack](/docs/{{version}}/getting-started-basics), you'll be able to create a CRUD panel in a few minutes per model:
+- **UI** - Backpack will provide you with a _visual interface_ for the admin panel (the HTML, the CSS, the JS), authentication functionality & global bubble notifications; you can choose from one of the 3 themes we have developed (powered by Tabler, CoreUI v4 or CoreUI v2), a third-party theme or create your own theme; the enormous advantage of using a Bootstrap-based HTML theme is that when you need custom pages, you already have the HTML blocks for the UI, you don't have to design them yourself.
+- **CRUDs** - Backpack will also help you build _sections where your admins can manipulate entries for Eloquent models_; we call them _CRUD Panels_ after the most basic operations: Create, Read, Update & Delete; after [understanding Backpack](/docs/{{version}}/getting-started-basics), you'll be able to create a CRUD panel in a few minutes per model:

@@ -31,8 +31,8 @@ php artisan backpack:build
```
If you have NOT created your Eloquent models yet, you can use whatever you want for that. We recommend:
-- FREE - [`laravel-shift/blueprint`](https://github.com/laravel-shift/blueprint) as the best **YAML-based tool** for this;
-- PAID - [`backpack/devtools`](https://backpackforlaravel.com/products/devtools) as the best **web interface** for this; it makes it dead simple to create Eloquent models, from the comfort of your web browser;
+- FREE - [`laravel-shift/blueprint`](https://github.com/laravel-shift/blueprint) as the best **YAML-based tool** for this.
+- PAID - [`backpack/devtools`](https://backpackforlaravel.com/products/devtools) as the best **web interface** for this. It makes it dead simple to create Eloquent models, from the comfort of your web browser.
---
@@ -56,7 +56,7 @@ We heavily recommend you spend a little time to understand Backpack, and only af
### Requirements
- - Laravel 10.x or 11.x
+ - Laravel 10.x or 11.x or 12.x
- MySQL / PostgreSQL / SQLite / SQL Server
@@ -78,9 +78,9 @@ Backpack v6 is the current version and is actively maintained by the Backpack te
### License
Backpack is open-core:
-- **Backpack CRUD is free & open-source, licensed under the [MIT License](https://github.com/Laravel-Backpack/CRUD/blob/main/LICENSE.md)**; it is perfect if you're building a simple admin panel - it's packed with features! it's also perfect if you're building an open-source project, the permissive license allows you to do whatever you want;
-- **Backpack PRO is a paid, closed-source add-on, licensed under our [EULA](https://backpackforlaravel.com/eula)**; [PRO](https://backpackforlaravel.com/products/pro-for-unlimited-projects) adds additional functionality to CRUD, that will be useful when your admin panel grows (see our [FREE vs PRO comparison](https://backpackforlaravel.com/docs/6.x/features-free-vs-paid));
-- Of the other add-ons we've created, some are FREE and some are PAID; please see [our add-ons list](https://backpackforlaravel.test/docs/6.x/add-ons-official) for more info;
+- **Backpack CRUD is free & open-source, licensed under the [MIT License](https://github.com/Laravel-Backpack/CRUD/blob/main/LICENSE.md)**. It is perfect if you're building a simple admin panel - it's packed with features! It's also perfect if you're building an open-source project, the permissive license allows you to do whatever you want.
+- **Backpack PRO is a paid, closed-source add-on, licensed under our [EULA](https://backpackforlaravel.com/eula)**. [PRO](https://backpackforlaravel.com/products/pro-for-unlimited-projects) adds additional functionality to CRUD, which will be useful when your admin panel grows (see our [FREE vs PRO comparison](https://backpackforlaravel.com/docs/7.x/features-free-vs-paid)).
+- Of the other add-ons we've created, some are FREE and some are PAID. Please see [our add-ons list](https://backpackforlaravel.test/docs/7.x/add-ons-official) for more info.
[Our documentation](https://backpackforlaravel.com/docs) covers both CRUD and PRO, with all the PRO features clearly labeled PRO.
@@ -89,9 +89,9 @@ Backpack is open-core:
### Versioning, Updates and Upgrades
Starting with the previous version, all our packages follow [semantic versioning](https://semver.org/). Here's what `major.minor.patch` (e.g. `7.0.1`) means for us:
-- `major` - breaking changes, major new features, complete rewrites; released **once a year**, in February; it adds features that were previously impossible and upgrades our dependencies; upgrading is done by following our clear and detailed upgrade guides;
-- `minor` - new features, released in backwards-compatible ways; **every few months**; update takes seconds;
-- `patch` - bug fixes & small non-breaking changes; historically **every week**; update takes seconds;
+- `major` - breaking changes, major new features, complete rewrites; released **once a year**, in February. It adds features that were previously impossible and upgrades our dependencies; upgrading is done by following our clear and detailed upgrade guides.
+- `minor` - new features, released in backwards-compatible ways; **every few months**; update takes seconds.
+- `patch` - bug fixes & small non-breaking changes; historically **every week**; update takes seconds.
When we release a new Backpack\CRUD version, all paid add-ons receive support for it the same day.
@@ -100,15 +100,15 @@ When you buy a premium Backpack add-on, you get access to not only _updates_, bu
### Add-ons
-Backpack's core is open-source and free (Backpack\CRUD). FREE
+Backpack's core is open-source and free (Backpack\CRUD). **FREE**
The reason we've been able to build and maintain Backpack since 2016 is that Laravel professionals have supported us, by buying our paid products. As of 2022, these are all Backpack add-ons, which we highly recommend:
-- [Backpack PRO](/products/pro-for-unlimited-projects) - a crazy amount of added features; PAID
-- [Backpack DevTools](/products/devtools) - a developer UI for generating migrations, models and CRUDs; PAID
-- [Backpack FigmaTemplate](/products/figma-template) - quickly create designs and mockups, using Backpack's design; PAID
-- [Backpack EditableColumns](/products/editable-columns) - let your admins do quick edits, right in the table view; PAID
+- [Backpack PRO](/products/pro-for-unlimited-projects) - a crazy amount of added features. **PAID**
+- [Backpack DevTools](/products/devtools) - a developer UI for generating migrations, models and CRUDs. **PAID**
+- [Backpack FigmaTemplate](/products/figma-template) - quickly create designs and mockups, using Backpack's design. **PAID**
+- [Backpack EditableColumns](/products/editable-columns) - let your admins do quick edits, right in the table view. **PAID**
-In addition to our open-source core and our closed-source add-ons, there are a few other add-ons you might want to take a look at, that treat common use cases. Some have been developed by our core team, some by our wonderful community. You can just install interfaces to manage [site-wide settings](https://github.com/Laravel-Backpack/Settings), [the default Laravel users table](https://github.com/eduardoarandah/UserManager), [users, groups & permissions](https://github.com/Laravel-Backpack/PermissionManager), [content for custom pages, using page templates](https://github.com/Laravel-Backpack/PageManager), [news articles, categories and tags](https://github.com/Laravel-Backpack/NewsCRUD), etc. FREE
+In addition to our open-source core and our closed-source add-ons, there are a few other add-ons you might want to take a look at, that treat common use cases. Some have been developed by our core team, some by our wonderful community. You can just install interfaces to manage [site-wide settings](https://github.com/Laravel-Backpack/Settings), [the default Laravel users table](https://github.com/eduardoarandah/UserManager), [users, groups & permissions](https://github.com/Laravel-Backpack/PermissionManager), [content for custom pages, using page templates](https://github.com/Laravel-Backpack/PageManager), [news articles, categories and tags](https://github.com/Laravel-Backpack/NewsCRUD), etc. **FREE**
For more information, please see [our add-ons page](/addons).
diff --git a/7.x-dev/release-notes.md b/7.x-dev/release-notes.md
index 3df11af9..e6555e9c 100644
--- a/7.x-dev/release-notes.md
+++ b/7.x-dev/release-notes.md
@@ -2,60 +2,101 @@
---
-**Planned launch date:** Dec 4th, 2024
+**Planned launch date:** August 1st, 2025
-For the past 2 years, we've done our very best to make all changes to Backpack in a backwards-compatible way. To not push a new version, because we know it's a pain in the bee's hind to upgrade stuff. But... it's time for a new release. Have no fear though, we've made this super easy for you.
+For the past 2.5 years, we've done our very best to make all changes to Backpack in a backwards-compatible way. To not push a new version, because we know it's a pain to upgrade stuff. But... it's time for a new release. Have no fear though, we've made this super easy for you - and the new features & bug fixes are worth it!
-Backpack v7 is a maintenance release. Yes, it does have a few breaking changes, but they will not impact 99.9% of projects. But that doesn't mean you shouldn't follow the upgrade guide! Please do - read it from top to bottom and make sure none of the changes impact you.
+Here are the BIG things Backpack v7 brings to the table and why you should upgrade from [Backpack v6](/docs/6.x) to v7. But first... we should give credit where credit is due. **Big BIG thanks to our team: [Pedro Martins](https://github.com/pxpm), [Jorge Castro](https://github.com/jcastroa87)**, [Karan Datwani](https://github.com/karandatwani92)** and [Cristian Tabacitu](https://github.com/tabacitu) for working on this new version - and of course **our paying customers**, who have made all of this possible by supporting our work 🙏
-Here are the BIG things Backpack v7 brings to the table and why you should upgrade from [Backpack v6](/docs/6.x) to v7. But first... we should give credit where credit is due. **Big BIG thanks to**:
-- **[Pedro Martins](https://github.com/pxpm)** for x;
-- **[Jorge Castro](https://github.com/jcastroa87)** for y;
-- **[Karan Datwani](https://github.com/karandatwani92)** for z;
-- **[Cristian Tabacitu](https://github.com/tabacitu)** for t;
-- **our paying customers**, who have made all of this possible by supporting our work 🙏
-
-Together, our team has put in an incredible amount of work to make v7 what it is - more than XXX commits, across YYY months, all while still maintaining, bug fixing and improving v6. Again, big thanks to everybody who has helped made this happen 🙏
+Together, our team has put in an incredible amount of work to make v7 what it is - more than 1000 commits, across more than 8 months, all while still maintaining, bug fixing and improving v6. Again, big thanks to everybody who has helped made this happen - and of course, BIG thanks to our beta testers 🙏
## Added
-### CRUD Lifecycle Hooks
+### Data Components
+
+Our team has spend a lot of time and effort to make it possible to include the content of our main operations... anywhere you want. In the process, we've not only bent the laws of physics (ok maybe only PHP), but also made those operations _cleaner_.
+
+#### Datatable component
+
+
+
+You can now include a datatable anywhere you want! Just use the component in your custom views, custom pages or custom operations - it will pick up all the setup from your existing CrudController. [Read more](/docs/{{version}}/base-components#datatable-1).
+
+#### Dataform component
+
+
+
+You can now include a form anywhere you want! Same as the datatable - just use the component in your custom blade files, and it will pick up the fields from your CrudController. [Read more](/docs/{{version}}/base-components#dataform-component).
+
+#### Datalist component
+
+
+
+You can now use the content of the Show page for a particular entry... anywhere you want. It's as simple as loading the component and passing the CrudController. [Read more](/docs/{{version}}/base-components#datalist-component).
+
+#### Datagrid component
-// TODO
+
-### Two-Factor Authentication
+Our previous design for the Show operation worked fine... but it wasn't pretty. We've developed an alternative comopnent, so that your Show operation looks a little better - just specify you want the show operation to use `datagrid` in your `config/backpack/operations/show.php`. Of course... you can also use it (you guessed it)... anywhere you want. It's as simple as loading the component and passing the CrudController. [Read more](/docs/{{version}}/base-components#datagrid-component).
-// TODO
+### Chips
-### Re-Usable Filters
+
-// just like your air purifier
-// TODO
+You know columns, you know fields - please welcome... chips! A chips helps show the information of a database entry, in a format that takes up little space visually. It can be used anywhere you want, but it's particularly useful inside the Show and List operations, to cram as much info as possible in as little space as possible. [Read more](/docs/{{version}}/crud-chips).
-### Browser Tests
+### Skins
-// TODO
+
+It's been 2.5 years since we've adopted Tabler as our default HTML template - and in this time, we have only grown more fond of it. We are truly convinced that it's the best free Bootstrap template for admin panels, and our partnership and commitment has only grown. This new version of Backpack comes with a new feature inside our Tabler theme... skins.
+
+Skins are a simple CSS file, that you can enable/not, to give your admin panel a completely different look. We're launching with one modern skin (that we call "non-liquid glass"). Soon enough, we'll follow up with a few more skins and... a way for you to _quickly_ create a custom skin, that will match your brand colors.
+
+### CRUD Lifecycle Hooks
+
+Previously when working with Operations, developers found themselves needing to _override_ an entire operation method, in order to do things before/after the routes/defaults/operation is set up. This created a lot of duplicate code, and made it hard to maintain. Now, you can use CRUD Lifecycle Hooks to add your own code before/after each operation method. This is a much cleaner way to add your own code, without having to override the entire method. [Read more](/docs/{{version}}/crud-operations#lifecycle-hooks).
+
+### Re-usable Filters - Inside Custom Pages or Operations
+
+
+
+Starting with this Backpack version, you can use the [filters](/docs/{{version}}/crud-filters) in custom pages too. Instead of being tied to DataTables, filters now trigger generic Javascript events like `backpack:filter:changed`. You can catch those events using custom code in Javascript or Livewire... and do stuff. This it possible to use filters on completely custom pages - like custom dashboards, custom reports or custom operations. [Read more](/docs/{{version}}/crud-filters#use-filters-on-custom-admin-panel-pages).
+
+### Filters inside CustomViews
+
+Filters can now be used inside [Custom Views for your List operation](https://backpackforlaravel.com/docs/{{version}}/crud-operation-list-entries#custom-views-for-listoperation-pro). This means once the admin has selected the Custom View, they can further drill down in the list, using the filters. But not only that... you can _remove_ the general filters and add entirely new filters, just for that Custom View.
## Changed
+### New Versions for All Assets
+
+We've bumped the version of ALL javascript and CSS assets we have, across the board. By upgrading to Backpack v7, you're automatically getting the best they have to offer - including Tabler, Bootstrap, Datatables etc.
+
### Uploaders
-// TODO
+We've ironed out all the quirks of Uploaders (and uploaders inside repeatables etc). This needed a few small breaking changes, but nothing that should affect you, if you haven't created custom uploaders. Try them again - they should all work fine now!
### Moved TinyMCE and CKEditor fields & columns
-// TODO
+We've moved the TinyMCE & CKeditor fields & columns from PRO to their own addons - released under open-source licenses. Please note that the underlying JS libraries are under GPLv2 license - which means you should not use them inside paid projects without purchasing a license from their respective creators.
### Basset
-// TODO
+A revolution in how easy it is to load CSS and JS assets in PHP, but we found out the hard way that making things easy is... _hard_. We're glad to tell you we've finally fixed most problems that came with Basset - and it's more reliable than ever. Additionally, you can now:
+- name your assets, to easily use the same asset in multiple places;
+- publish the assetmap, to override assets from vendor packages;
+- use Basset on localhost (to code without an internet connection);
+- store your assets in Git, so there's zero need to run basset in production;
+
+For more information, check out [the docs for Basset's next version](https://github.com/Laravel-Backpack/basset/tree/next).
### Parent Theme
-// TODO
+// TODO: docs
## Removed
diff --git a/7.x-dev/upgrade-guide.md b/7.x-dev/upgrade-guide.md
index 00ee27a4..d09616e2 100644
--- a/7.x-dev/upgrade-guide.md
+++ b/7.x-dev/upgrade-guide.md
@@ -4,6 +4,8 @@
This will guide you to upgrade from Backpack v6 to v7. The steps are color-coded by the probability that you will need it for your application: High, Medium and Low. **At the very least, please read what's in bold**.
+> IMPORTANT NOTE: This upgrade guide is NOT AT ALL final. We do not recommend you upgrade your existing project to v7. We're working on making the upgrade process easier for you. We will let you know when this changes.
+
## Requirements
@@ -26,7 +28,7 @@ Please make sure your project respects the requirements below, before you start
## Upgrade Steps
-Step 0. **[Upgrade to Laravel 11](https://laravel.com/docs/11.x/upgrade) if you don't use it yet, then test to confirm your app is working fine.**
+Step 0. **[Upgrade to Laravel 12](https://laravel.com/docs/12.x/upgrade) if you don't use it yet, then test to confirm your app is working fine.**
### Composer
@@ -34,31 +36,34 @@ Please make sure your project respects the requirements below, before you start
Step 1. Update your ```composer.json``` file to require:
```
- "backpack/crud": "v7-dev",
+ "backpack/crud": "^7.0.0-beta",
```
Step 2. Bump the version of any first-party Backpack add-ons you have installed (eg. `backpack/pro`, `backpack/editable-columns` etc.) to the versions that support Backpack v6. For 3rd-party add-ons, please check each add-on's Github page. Here's a quick list of 1st party packages and versions:
```js
- "backpack/crud": "v7-dev",
- "backpack/pro": "v3-dev",
- "backpack/filemanager": "^3.0",
- "backpack/theme-coreuiv2": "^1.0",
- "backpack/theme-coreuiv4": "^1.0",
- "backpack/theme-tabler": "^1.0",
- "backpack/logmanager": "^5.0",
- "backpack/settings": "^3.1",
- "backpack/newscrud": "^5.0",
- "backpack/permissionmanager": "^7.0",
- "backpack/pagemanager": "^3.2",
- "backpack/menucrud": "^4.0",
- "backpack/backupmanager": "^5.0",
- "backpack/editable-columns": "^3.0",
- "backpack/revise-operation": "^2.0",
- "backpack/medialibrary-uploaders": "^1.0",
- "backpack/devtools": "^2.0",
+ "backpack/crud": "^7.0.0-beta",
+ "backpack/pro": "^3.0.0-alpha",
+ "backpack/filemanager": "dev-next",
+ "backpack/theme-coreuiv2": "dev-next",
+ "backpack/theme-coreuiv4": "dev-next",
+ "backpack/theme-tabler": "dev-next",
+ "backpack/logmanager": "dev-next",
+ "backpack/settings": "dev-next",
+ "backpack/newscrud": "dev-next",
+ "backpack/permissionmanager": "dev-next",
+ "backpack/pagemanager": "dev-next",
+ "backpack/menucrud": "dev-next",
+ "backpack/backupmanager": "dev-next",
+ "backpack/editable-columns": "dev-next",
+ "backpack/revise-operation": "dev-next",
+ "backpack/medialibrary-uploaders": "dev-next",
+ "backpack/devtools": "dev-next",
+ "backpack/generators": "dev-next",
```
+> **Note:** To install Backpack v7 beta and its add-ons, set `"minimum-stability": "beta"` in your `composer.json`.
+
Step 3. Let's get the latest Backpack and install it. If you get any conflicts with **Backpack 1st party add-ons**, most of the time you just need to move one version up, eg: from `backpack/menucrud: ^3.0` to `backpack/menucrud: ^4.0`. See the step above again. Please run:
```bash
@@ -89,22 +94,51 @@ No changes needed.
### Config
-No changes needed.
+Step X. **Operation Config Files** - We have added new configuration options in the files inside `config/backpack/operations/`. If you have those files published, it is recommended that you copy the new options in your files too.
+
+Step X. **Show Operation New Default** - inside `config/backpack/operations/show.php` you'll find a new option, to choose which component will be used on the show operation. By default it's the new component `bp-datagrid`, but you can switch to `bp-datalist` if you want to keep the same look as before:
+
+```php
+ // Which component to use for displaying the Show page?
+ 'component' => 'bp-datalist', // options: bp-datagrid, bp-datalist, or a custom component alias
+```
+
+Step X. **Theme Tabler** - The default layout for theme tabler has changed. If you had the tabler config published you are good to go. **In case you don't have the tabler theme config published** and want to keep the old layout, you should publish it by running `php artisan vendor:publish --tag="theme-tabler-config"` and changing:
+```diff
+- 'layout' => 'horizontal',
++ 'layout' => 'horizontal_overlap',
+```
+You should also remove the glass skin and fuzzy background from the theme styles:
+```diff
+'styles' => [
+ base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/backpack-color-palette.css'),
+- base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/glass.css'),
+- base_path('vendor/backpack/theme-tabler/resources/assets/css/skins/fuzzy-background.css'),
+ ],
+```
### CrudControllers
-No changes needed.
+Step X. The `wysiwyg` field and column have been removed, because they were hiding functionality. But don't worry, they were just alias columns. Behind the scenes, they were just loading the `ckeditor` field and `text` column respectively. If you're using the `wysiwyg` column of field in your CrudController, replace them with their originals.
+
+Step X. The `ckeditor` field and column have been moved from the PRO package to an open-source addon. If you are using either of them and want to keep doing so, just run `composer require backpack/ckeditor-field`. Please note that CKEditor is a 3rd party JS library that requires _payment_ when used for commercial purposes (GPL licensed). See their [pricing page](https://ckeditor.com/pricing/) for options. We can give away a few sub-licenses every year - [contact us](https://backpackforlaravel.com/contact) to see if any are still available. If you would rather move away from CKEditor, you can just change your field/column to use `summernote` instead, they are both HTML editors so your content should be compatible. Summernote has more limited editing options, but it's MIT-licensed.
+
+Step X. Similarly, the `tinymce` field and column have been moved from the PRO package to an open-source addon. If you are using either of them and want to keep doing so, just run `composer require backpack/tinymce-field`. Please note that TinyMCE is a 3rd party JS library that normally requires _payment_ when used for commercial purposes (GLP licensed). See their [pricing page](https://www.tiny.cloud/pricing/) for options. You can sign-up for [free commercial licenses on their website here](https://www.tiny.cloud/get-tiny/). If you would rather move away from TinyMCE, you can just change your field/column to use `summernote` instead, they are both HTML editors so your content should be compatible. Summernote has more limited editing options, but it's MIT-licensed.
+
### CSS & JS Assets
-No changes needed.
+
### Views
-No changes needed.
+**List Operation View** - The List Operation view got a huge change. We decoupled the datatable from the view, so that you can use the table anywhere you would like.
+Most of the code is still identical but moved to `datatable.blade.php`. The `list.blade.php` view now only includes the mentioned datatable component.
+
+If you had customized the `list.blade.php` you should move your customizations to `datatable.blade.php`.
### Security
@@ -116,6 +150,7 @@ No changes needed.
Step xx. Clear your app's cache:
```
+php artisan basset:clear
php artisan config:clear
php artisan cache:clear
php artisan view:clear
@@ -132,9 +167,10 @@ If the table view still looks wonky (search bar out of place, big + instead of e
### Upgrade Add-ons
-For any addons you might have upgraded, please double-check if they have an upgrade guide. For example:
-- Xx package has the upgrade guide here;
-- Yy package has the upgrade guide here;
+**backpack/file-manager** Using the File Manager package? Most of the views that weren't in use were removed, and the dependencies were bumped. If you didn't do any customization you should delete the `resources/views/vendor/elfinder` (`rm -rf resources/views/vendor/elfinder`) folder.
+No need to publish any views anymore if you are not customizing them. If you were, publish the new view files (`php artisan vendor:publish --provider="Backpack\FileManager\FileManagerServiceProvider" --tag="elfinder-views"`). Then apply your customization on the new files, now located at: `resources/views/vendor/backpack/filemanager/`
+
+Additional the `browse` and `browse_multiple` **fields/columns** are now part of this package. If you previously made any modifications to this fields/columns you should publish the new views (`php artisan vendor:publish --provider="Backpack\FileManager\FileManagerServiceProvider" --tag="filemanger-fields"` and `php artisan vendor:publish --provider="Backpack\FileManager\FileManagerServiceProvider" --tag="filemanager-columns"`), and carry over the modifications from the old files to this new files.
---
diff --git a/README.md b/README.md
index 8dea706d..8056e3e6 100644
--- a/README.md
+++ b/README.md
@@ -12,5 +12,5 @@ You can find the online version of the Backpack documentation at https://backpac
- pull requests are welcome and appreciated;
- pull requests should point to the ```master``` branch;
- all links should point to the current version of the documentation page (ex: ```/docs/{{version}}/installation```);
-- all images should be uploaded to ```https://backpackforlaravel.com/uploads/docs/``` and used from there; ask @tabacitu to help upload them;
+- all images should be uploaded to ```https://backpackforlaravel.com/uploads/docs/``` and used from there; ask [@tabacitu](https://github.com/tabacitu) to help upload them;
- all headings should be prepended by an HTML anchor, with the name of the heading; this way, Algolia can take the user directly to that heading (ex: ``````);