From 47b0beb0d03735e743dd769e5b1433810e49dafc Mon Sep 17 00:00:00 2001
From: ilhm344 <117576293+ilhm344@users.noreply.github.com>
Date: Sat, 9 Dec 2023 15:58:37 +0500
Subject: [PATCH] added translation of advanced folder
---
.../en/advanced/authentication.blade.php | 124 ++++++
.../pages/en/advanced/authorization.blade.php | 142 +++++++
.../pages/en/advanced/commands.blade.php | 315 ++++++++++++++
.../pages/en/advanced/controller.blade.php | 136 ++++++
.../pages/en/advanced/form_builder.blade.php | 301 +++++++++++++
.../views/pages/en/advanced/helpers.blade.php | 80 ++++
.../pages/en/advanced/localization.blade.php | 8 +
.../views/pages/en/advanced/menu.blade.php | 252 +++++++++++
.../pages/en/advanced/notifications.blade.php | 25 ++
.../pages/en/advanced/socialite.blade.php | 34 ++
.../pages/en/advanced/table_builder.blade.php | 398 ++++++++++++++++++
.../pages/en/advanced/type_casts.blade.php | 88 ++++
.../pages/ru/advanced/authorization.blade.php | 2 +-
13 files changed, 1904 insertions(+), 1 deletion(-)
create mode 100644 resources/views/pages/en/advanced/authentication.blade.php
create mode 100644 resources/views/pages/en/advanced/authorization.blade.php
create mode 100644 resources/views/pages/en/advanced/commands.blade.php
create mode 100644 resources/views/pages/en/advanced/controller.blade.php
create mode 100644 resources/views/pages/en/advanced/form_builder.blade.php
create mode 100644 resources/views/pages/en/advanced/helpers.blade.php
create mode 100644 resources/views/pages/en/advanced/localization.blade.php
create mode 100644 resources/views/pages/en/advanced/menu.blade.php
create mode 100644 resources/views/pages/en/advanced/notifications.blade.php
create mode 100644 resources/views/pages/en/advanced/socialite.blade.php
create mode 100644 resources/views/pages/en/advanced/table_builder.blade.php
create mode 100644 resources/views/pages/en/advanced/type_casts.blade.php
diff --git a/resources/views/pages/en/advanced/authentication.blade.php b/resources/views/pages/en/advanced/authentication.blade.php
new file mode 100644
index 00000000..b427b67f
--- /dev/null
+++ b/resources/views/pages/en/advanced/authentication.blade.php
@@ -0,0 +1,124 @@
+
+
+Basics
+
+
+ The MoonShine admin panel has an authentication system. By default it is enabled
+ but if you need to allow access for all users,
+ then it can be disabled in the configuration file config/moonshine.php
.
+
+
+
+return [
+ // ...
+ 'auth' => [
+ 'enable' => true, // [tl! focus]
+ // ...
+ ],
+ // ...
+];
+
+
+
+
+
+Empowerment
+
+
+ If you use your own guard, provider, then they can be overridden in the configuration,
+ as well as the MoonshineUser
model.
+
+
+
+return [
+ // ...
+ 'auth' => [
+ // ...
+ 'middleware' => Authenticate::class, // [tl! focus:start]
+ 'guard' => 'moonshine',
+ 'guards' => [
+ 'moonshine' => [
+ 'driver' => 'session',
+ 'provider' => 'moonshine',
+ ],
+ ],
+ 'providers' => [
+ 'moonshine' => [
+ 'driver' => 'eloquent',
+ 'model' => MoonshineUser::class,
+ ],
+ ], // [tl! focus:end]
+ // ...
+ ],
+ // ...
+];
+
+
+Login form
+
+
+ You can completely replace the login form with your own, just replace the class in the config with yours,
+ and inside implement FormBuilder
+
+
+
+return [
+ // ...
+ 'forms' => [
+ 'login' => LoginForm::class
+ ],
+ // ...
+];
+
+
+Profile
+
+
+ You can completely replace the profile page with your own, just replace the page class in the config with yours
+
+
+
+return [
+ // ...
+ 'pages' => [
+ // ...
+ 'profile' => ProfilePage::class
+ ],
+ // ...
+];
+
+
+
+ You can override profile fields in the configuration file config/moonshine.php
.
+
+
+
+return [
+ // ...
+ 'auth' => [
+ 'enable' => true,
+ 'fields' => [ // [tl! focus:start]
+ 'username' => 'email',
+ 'password' => 'password',
+ 'name' => 'name',
+ 'avatar' => 'avatar'
+ ], // [tl! focus:end]
+ 'guard' => 'moonshine',
+ // ...
+ ],
+ // ...
+];
+
+
+
+ If you don't want to use an avatar,
+ then specify 'avatar'=>''
or 'avatar'=>false
.
+
+
diff --git a/resources/views/pages/en/advanced/authorization.blade.php b/resources/views/pages/en/advanced/authorization.blade.php
new file mode 100644
index 00000000..6e1fa16c
--- /dev/null
+++ b/resources/views/pages/en/advanced/authorization.blade.php
@@ -0,0 +1,142 @@
+
+
+Basics
+
+
+ The MoonShine admin panel does not depart from Laravel concepts
+ and also using Laravel policy can work with access rights.
+
+
+
+ In MoonShine resource controllers, each method will be checked for permissions.
+ If you have any difficulties, check out the official documentation
+ Laravel.
+
+
+
+ By default, permissions checking is disabled for resources. To enable, you need to add the property
+ withPolicy
.
+
+
+
+namespace App\MoonShine\Resources;
+
+use App\Models\Post;
+use MoonShine\Resources\ModelResource;
+
+class PostResource extends ModelResource
+{
+ protected string $model = Post::class;
+
+ protected bool $withPolicy = true; // [tl! focus]
+
+ //...
+}
+
+
+
+ To create a Policy with an admin panel user binding, you can use the console command:
+
+
+
+ php artisan moonshine:policy
+
+
+
+ Available Policy methods:
+
+
+ viewAny
- index page;
+ view
- detailed page;
+ create
- creating a record;
+ update
- editing a record;
+ delete
- deleting a record;
+ massDelete
- mass deletion of records;
+ restore
- restoring a record after soft deletion;
+ forceDelete
- permanently deletes a record from the database.
+
+
+
+namespace App\Policies;
+
+use Illuminate\Auth\Access\HandlesAuthorization;
+use App\Models\Post;
+use MoonShine\Models\MoonshineUser;
+
+class PostPolicy
+{
+ use HandlesAuthorization;
+
+ public function viewAny(MoonshineUser $user) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function view(MoonshineUser $user, Post $item) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function create(MoonshineUser $user) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function update(MoonshineUser $user, Post $item) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function delete(MoonshineUser $user, Post $item) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function restore(MoonshineUser $user, Post $item) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function forceDelete(MoonshineUser $user, Post $item) // [tl! focus]
+ {
+ return true;
+ }
+
+ public function massDelete(MoonshineUser $user) // [tl! focus]
+ {
+ return true;
+ }
+}
+
+
+Additional logic
+
+
+ If you need to add additional authorization logic to your application or external package,
+ then use the defineAuthorization
method in the AuthServiceProvider
.
+
+
+
+use Illuminate\Database\Eloquent\Model;
+use MoonShine\Contracts\Resources\ResourceContract;
+use MoonShine\MoonShine;
+
+public function boot(): void
+{
+ MoonShine::defineAuthorization(
+ static function (ResourceContract $resource, Model $user, string $ability): bool {
+ return true;
+ }
+ ); // [tl! focus:-4]
+}
+
+
+
diff --git a/resources/views/pages/en/advanced/commands.blade.php b/resources/views/pages/en/advanced/commands.blade.php
new file mode 100644
index 00000000..cce3b294
--- /dev/null
+++ b/resources/views/pages/en/advanced/commands.blade.php
@@ -0,0 +1,315 @@
+
+
+Install
+
+
+ Command to install the MoonShine package in your Laravel project:
+
+
+
+ php artisan moonshine:install
+
+
+
+ Available options:
+
+
+
+ -u
, --without-user
- without creating a super user;
+ -m
, --without-migrations
- without performing migrations.
+
+
+
+ For more detailed information, please refer to the section
+ Installation.
+
+
+Apply
+
+
+ The command to create the apply class is:
+
+
+
+ php artisan moonshine:apply
+
+
+
+ After executing the command, a file will be created in the app/MoonShine/Applies
directory.
+ The created class must be registered with the service provider.
+
+
+Component
+
+
+ The command creates a custom component:
+
+
+
+ php artisan moonshine:component
+
+
+
+ After executing the command, a class for the component will be created in the app/MoonShine/Components
directory
+ and Blade file in the resources/views/admin/components
directory.
+
+
+
+ For more detailed information, please refer to the section
+ Components.
+
+
+Controller
+
+
+ Command to create a controller:
+
+
+
+ php artisan moonshine:controller
+
+
+
+ After executing the command, a controller class will be created in the app/MoonShine/Controllers
directory.
+ Which can be used in admin panel routes.
+
+
+
+ For more detailed information, please refer to the section
+ Controllers.
+
+
+Field
+
+
+ The command allows you to create a custom field:
+
+
+
+ php artisan moonshine:field
+
+
+
+ When executing the command, you can specify whether the field will extend the base class or another field.
+
+
+
+ After executing the command, a field class will be created in the app/MoonShine/Fields
directory
+ and Blade file in the directory /resources/views/admin/fields
.
+
+
+
+ For more detailed information, please refer to the section
+ Fields.
+
+
+Handler
+
+
+ The command creates a Handler class for its import and export implementations:
+
+
+
+ php artisan moonshine:handler
+
+
+
+ After executing the command, the handler class will be created in the directory app/MoonShine/Handlers
.
+
+
+
+ For more detailed information, please refer to the section
+ Import/Export.
+
+
+Page
+
+
+ The command creates a page for the admin panel:
+
+
+
+ php artisan moonshine:page
+
+
+
+ Available options:
+
+
+
+ --crud
- creates a group of pages: index, detail and form page;
+ -
+
--dir=
- the directory in which the files will be located relative to app/MoonShine
,
+ default Page
;
+
+ -
+
--extends=
- a class that the page will extend, for example IndexPage, FormPage or DetailPage.
+
+
+
+
+ After executing the command, a default page (or group of pages) will be created in the directory
+ app/MoonShine/Pages
.
+
+
+
+ For more detailed information, please refer to the section
+ Page.
+
+
+Policy
+
+
+ The command creates a Policy bound to the admin panel user:
+
+
+
+ php artisan moonshine:policy
+
+
+
+ After executing the command, a class will be created in the app/Policies
directory.
+
+
+
+ For more detailed information, please refer to the section
+ Authorization.
+
+
+Resource
+
+
+ Command to create resources:
+
+
+
+ php artisan moonshine:resource
+
+
+
+ Available options:
+
+
+
+ --m|model=
- Eloquent model for model resource;
+ -
+
--t|title=
- section title.
+
+
+
+
+ There are several options available when creating a Resource:
+
+ -
+ Default model resource
+ - model resource with common fields;
+
+ -
+ Separate model resource
+ - model resource with field separation;
+
+ -
+ Model resource with pages
+ - model resource with pages;
+
+ -
+ Empty resource
+ - empty resource.
+
+
+
+
+
+ After executing the command, a resource file will be created in the app/MoonShine/Resources/
directory.
+ If a model resource with pages is created, additional pages will be created in the directory
+ app/MoonShine/Pages
.
+
+
+
+ For more detailed information, please refer to the section
+ Models Resources.
+
+
+Type Cast
+
+
+ The command creates a TypeCast class for working with data:
+
+
+
+ php artisan moonshine:type-cast
+
+
+
+ After executing the command, a file will be created in the app/MoonShine/TypeCasts
directory.
+
+
+
+ For more detailed information, please refer to the section
+ TypeCasts.
+
+
+User
+
+
+ The command that allows you to create a super user:
+
+
+
+ php artisan moonshine:user
+
+
+
+ Available options:
+
+
+
+ --u|username=
- user login/email;
+ --N|name=
- user name;
+ --p|password=
- password.
+
+
+Publish
+
+
+ Posting team:
+
+
+
+ php artisan moonshine:publish
+
+
+
+ There are several options available for publishing:
+
+ - Assets - MoonShine admin panel assets;
+ -
+ Layout
+ - MoonShineLayout class, responsible for the general appearance of the admin panel;
+
+ -
+ System Resources - system MoonShineUserResource, MoonShineUserRoleResource,
+ which you can change.
+
+
+
+
+
diff --git a/resources/views/pages/en/advanced/controller.blade.php b/resources/views/pages/en/advanced/controller.blade.php
new file mode 100644
index 00000000..b91d864b
--- /dev/null
+++ b/resources/views/pages/en/advanced/controller.blade.php
@@ -0,0 +1,136 @@
+
+
+ MoonShine allows you to work in a familiar manner using controllers
+
+
+
+ We provide you with our basic controller, which helps you conveniently work with the UI and
+ render your views with MoonShine layout
+
+
+
+ Useful for displaying your complex solutions or writing additional handlers
+
+
+Generate controller
+
+
+php artisan moonshine:controller
+
+
+Show blade view
+
+
+namespace App\MoonShine\Controllers;
+
+use MoonShine\MoonShineRequest;
+use MoonShine\Http\Controllers\MoonshineController;
+use Symfony\Component\HttpFoundation\Response;
+
+final class CustomViewController extends MoonshineController
+{
+ public function __invoke(MoonShineRequest $request): Response
+ {
+ return $this
+ ->view('path_to_blade', ['param' => 'value'])
+ //->setLayout('custom_layout')
+ ->render();
+ }
+}
+
+
+Display page
+
+
+namespace App\MoonShine\Controllers;
+
+use MoonShine\MoonShineRequest;
+use MoonShine\Http\Controllers\MoonshineController;
+use MoonShine\Pages\Page;
+
+final class CustomViewController extends MoonshineController
+{
+ public function __invoke(MoonShineRequest $request): Page
+ {
+ return MyPage::make();
+ }
+}
+
+
+Show notification
+
+
+namespace App\MoonShine\Controllers;
+
+use MoonShine\MoonShineRequest;
+use MoonShine\Http\Controllers\MoonshineController;
+use Symfony\Component\HttpFoundation\Response;
+
+final class CustomViewController extends MoonshineController
+{
+ public function __invoke(MoonShineRequest $request): Response
+ {
+ $this->toast('Hello world');
+
+ return back();
+ }
+}
+
+
+Send notification
+
+
+namespace App\MoonShine\Controllers;
+
+use MoonShine\MoonShineRequest;
+use MoonShine\Http\Controllers\MoonshineController;
+use Symfony\Component\HttpFoundation\Response;
+
+final class CustomViewController extends MoonshineController
+{
+ public function __invoke(MoonShineRequest $request): Response
+ {
+ $this->notification('Message');
+
+ return back();
+ }
+}
+
+
+Access a page or resource
+
+
+namespace App\MoonShine\Controllers;
+
+use MoonShine\MoonShineRequest;
+use MoonShine\Http\Controllers\MoonshineController;
+use Symfony\Component\HttpFoundation\Response;
+
+final class CustomViewController extends MoonshineController
+{
+ public function __invoke(MoonShineRequest $request): Response
+ {
+ // $request->getPage();
+ // $request->getResource();
+ }
+}
+
+
+Json response
+
+
+namespace App\MoonShine\Controllers;
+
+use MoonShine\MoonShineRequest;
+use MoonShine\Http\Controllers\MoonshineController;
+use Symfony\Component\HttpFoundation\Response;
+
+final class CustomViewController extends MoonshineController
+{
+ public function __invoke(MoonShineRequest $request): Response
+ {
+ return $this->json(message: 'Message', data: [], redirect: null);
+ }
+}
+
+
diff --git a/resources/views/pages/en/advanced/form_builder.blade.php b/resources/views/pages/en/advanced/form_builder.blade.php
new file mode 100644
index 00000000..c4acf44c
--- /dev/null
+++ b/resources/views/pages/en/advanced/form_builder.blade.php
@@ -0,0 +1,301 @@
+@php use MoonShine\Fields\Text; @endphp
+
+
+Basics
+
+
+ Fields and decorations in MoonShine are used inside forms, which are handled by FormBuilder.
+ Thanks to FormBuilder, fields are displayed and filled with data.
+ You can also use FormBuilder on your own pages or even outside of MoonShine.
+
+
+
+make(
+ string $action = '',
+ string $method = 'POST',
+ Fields|array $fields = [],
+ array $values = []
+)
+
+
+
+ action
- handler
+ method
- request type,
+ fields
- fields and decorations.
+ values
- field values.
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->fields([
+ Text::make('Text')
+ ])
+ ->fill(['text' => 'Value'])
+
+
+
+ Same thing through methods:
+
+
+
+FormBuilder::make()
+ ->action('/crud/update')
+ ->method('PUT')
+ ->fields([
+ Text::make('Text')
+ ])
+ ->fill(['text' => 'Value'])
+
+
+
+ Helper is also available:
+
+
+
+@{!! form(request()->url(), 'GET')
+ ->fields([
+ Text::make('Text')
+ ])
+ ->fill(['text' => 'Value'])
+!!}
+
+
+{!!
+ form(request()->url(), 'GET')
+ ->fields([
+ Text::make('Text')
+ ])
+ ->fill(['text' => 'Value'])
+!!}
+
+
+Methods
+
+
+
+
+ The fields
method for declaring form fields and decorations:
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->fields([
+ Heading::make('Title'),
+ Text::make('Text'),
+ ])
+
+
+
+
+
+ fill
method for filling fields with values:
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->fields([
+ Heading::make('Title'),
+ Text::make('Text'),
+ ])
+ ->fill(['text' => 'value'])
+
+
+
+
+
+ The cast
method for casting form values to a specific type.
+ Since by default fields work with primitive types:
+
+
+
+use MoonShine\TypeCasts\ModelCast;
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->fields([
+ Heading::make('Title'),
+ Text::make('Text'),
+ ])
+ ->fillCast(['text' => 'value'], ModelCast::make(User::class))
+
+
+
+ use MoonShine\TypeCasts\ModelCast;
+
+ FormBuilder::make('/crud/update', 'PUT')
+ ->fields([
+ Heading::make('Title'),
+ Text::make('Text'),
+ ])
+ ->fillCast(User::query()->first(), ModelCast::make(User::class))
+
+
+
+ In this example, we cast the data to the User
model format using ModelCast
.
+
+
+
+
+ Read more about TypeCasts in the section of the same name
+
+
+
+
+
+
+ Form buttons can be modified and added.
+
+
+
+ To customize the "submit" button, use the submit
method
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->submit(label: 'Click me', attributes: ['class' => 'btn-primary'])
+
+
+
+ To add new buttons based on ActionButton
, use the buttons
method
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->buttons([
+ ActionButton::make('Delete', route('name.delete'))
+ ])
+
+
+
+
+
+ You can set any html attributes for the form using the customAttributes
method.
+
+
+
+FormBuilder::make()->customAttributes(['class' => 'custom-form']),
+
+
+Asynchronous mode
+
+
+ If you need to submit the form asynchronously, use the async
method.
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->async()
+
+
+
+ After a successful request, you can raise events by adding the asyncEvents
parameter.
+
+
+
+ FormBuilder::make('/crud/update', 'PUT')
+ ->name('main-form')
+ ->async(asyncEvents: ['table-updated-crud', 'form-reset-main-form'])
+
+
+
+ MoonShine already has a set of ready-made events
+
+
+
+ table-updated-{name}
- Updating an asynchronous table by its name
+ form-reset-{name}
- Reset form values by its name
+ fragment-updated-{name}
- Updates a blade fragment by its name
+
+
+
+ If you need to perform precognition validation first, you need the precognitive
method.
+
+
+
+FormBuilder::make('/crud/update', 'PUT')
+ ->precognitive()
+
+
+@include('recipes.form-with-events')
+
+Apply
+
+
+ The apply()
method in FormBuilder iterates through all form fields and calls their apply methods.
+
+
+
+apply(
+ Closure $apply,
+ ?Closure $default = null,
+ ?Closure $before = null,
+ ?Closure $after = null,
+ bool $throw = false,
+)
+
+
+
+ $apply
- callback function;
+ $default
- apply for the default field;
+ $before
- callback function before apply;
+ $after
- callback function after apply;
+ $throw
- throw exceptions.
+
+
+
+
+
+ It is necessary to save the data of all FormBuilder fields in the controller:
+
+
+
+$form->apply(fn(Model $item) => $item->save());
+
+
+
+ A more complex option, indicating events before and after saving:
+
+
+
+$form->apply(
+ static fn(Model $item) => $item->save(),
+ before: function (Model $item) {
+ if (! $item->exists) {
+ $item = $this->beforeCreating($item);
+ }
+
+ if ($item->exists) {
+ $item = $this->beforeUpdating($item);
+ }
+
+ return $item;
+ },
+ after: function (Model $item) {
+ $wasRecentlyCreated = $item->wasRecentlyCreated;
+
+ $item->save();
+
+ if ($wasRecentlyCreated) {
+ $item = $this->afterCreated($item);
+ }
+
+ if (! $wasRecentlyCreated) {
+ $item = $this->afterUpdated($item);
+ }
+
+ return $item;
+ },
+ throw: true
+);
+
+
+
diff --git a/resources/views/pages/en/advanced/helpers.blade.php b/resources/views/pages/en/advanced/helpers.blade.php
new file mode 100644
index 00000000..4c3fae87
--- /dev/null
+++ b/resources/views/pages/en/advanced/helpers.blade.php
@@ -0,0 +1,80 @@
+
+Basic
+
+
+moonshine() // MoonShine instance
+moonshineRegister() // To register apply classes
+moonshineRequest() // With access to resource, pages, posts and components
+moonshineAssets() // Working with assets (MoonShineAssets instance)
+moonshineMenu() // Get menu list
+moonshineLayout() // Render template contents
+
+
+Link to page to_page
+
+
+ $page - Page or page alias (Optional)
+ $resource - Resource or resource alias (Optional)
+ $params - Additional query
+ $redirect - If necessary, perform a redirect immediately
+ $fragment - URL will be used for Fragment loading
+
+
+
+to_page(page: 'form-page');
+to_page(page: IndexPage::class);
+to_page(page: IndexPage::class, resource: PostResource::class);
+to_page(page: new IndexPage(), resource: new PostResource());
+to_page(page: 'form-page', redirect: true);
+to_page(page: 'form-page', fragment: true);
+
+
+FormBuilder
+
+
+form(
+ string $action = '',
+ string $method = 'POST',
+ Fields|array $fields = [],
+ array $values = []
+)
+
+
+TableBuilder
+
+
+form(
+ Fields|array $fields = [],
+ iterable $items = [],
+ ?LengthAwarePaginator $paginator = null
+)
+
+
+TableBuilder
+
+
+actionBtn(
+ Closure|string $label,
+ Closure|string|null $url = null,
+ mixed $item = null
+)
+
+
+Find apply field (filter) class
+
+
+findFieldApply(
+ Field $field,
+ string $type,
+ string $for
+);
+
+findFieldApply($field, 'filters', ModelResource::class);
+
+
+Display 404
+
+
+oops404()
+
+
diff --git a/resources/views/pages/en/advanced/localization.blade.php b/resources/views/pages/en/advanced/localization.blade.php
new file mode 100644
index 00000000..97b1f6b6
--- /dev/null
+++ b/resources/views/pages/en/advanced/localization.blade.php
@@ -0,0 +1,8 @@
+
+
+
+ After installing MoonShine, a directory with translations will also appear in the directory with translations
+ MoonShine, where you can add support for a new language or change current ones.
+
+
+
diff --git a/resources/views/pages/en/advanced/menu.blade.php b/resources/views/pages/en/advanced/menu.blade.php
new file mode 100644
index 00000000..cc064f1d
--- /dev/null
+++ b/resources/views/pages/en/advanced/menu.blade.php
@@ -0,0 +1,252 @@
+
+
+Registration
+
+
+ In the resource study section, we have already figured out how to register sections of the admin panel,
+ after which they also appear in the menu.
+
+
+
+namespace App\Providers;
+
+use Illuminate\Support\ServiceProvider;
+use MoonShine\Menu\MenuItem; // [tl! focus]
+use MoonShine\MoonShine; // [tl! focus]
+use MoonShine\Resources\MoonShineUserResource;
+use MoonShine\Resources\MoonShineUserRoleResource;
+
+class MoonShineServiceProvider extends ServiceProvider
+{
+ //...
+
+ public function boot()
+ {
+ app(MoonShine::class)->menu([ // [tl! focus:start]
+ MenuItem::make('Admins', new MoonShineUserResource()),
+ MenuItem::make('Roles', new MoonShineUserRoleResource()),
+ ]); // [tl! focus:end]
+ }
+}
+
+
+
+ But for the convenience of the interface, we can also group menu items.
+
+
+
+namespace App\Providers;
+
+use Illuminate\Support\ServiceProvider;
+use MoonShine\Menu\MenuItem;
+use MoonShine\Menu\MenuGroup; // [tl! focus]
+use MoonShine\MoonShine;
+use MoonShine\Resources\MoonShineUserResource;
+use MoonShine\Resources\MoonShineUserRoleResource;
+
+class MoonShineServiceProvider extends ServiceProvider
+{
+ //...
+
+ public function boot()
+ {
+ app(MoonShine::class)->menu([
+ MenuGroup::make('System', [ // [tl! focus]
+ MenuItem::make('Admins', new MoonShineUserResource()),
+ MenuItem::make('Roles', new MoonShineUserRoleResource()),
+ ]) // [tl! focus]
+ ]);
+ }
+}
+
+
+
+ You just need to add resources as the second parameter to the MoonShine\Menu\MenuGroup
class.
+ Well, the first parameter is the name of the group!
+
+
+
+
+
+Display condition
+
+
+ Display menus based on condition.
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuGroup::make('System', [
+ MenuItem::make('Admins', new MoonShineUserResource()),
+ MenuItem::make('Roles', new MoonShineUserRoleResource()),
+ ])->canSee(function(Request $request) { // [tl! focus:start]
+ return $request->user('moonshine')?->id === 1;
+ }) // [tl! focus:end]
+]);
+//...
+
+
+External reference
+
+
+ Ability to add a custom link:
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('Laravel Documentation', 'https://laravel.com') // [tl! focus]
+]);
+//...
+
+
+
+ Links can be passed through the function.
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('Admins', function () { // [tl! focus:start]
+ return (new MoonShineUserResource())->route('index');
+ }),
+ MenuItem::make('Home', fn() => route('home')) // [tl! focus:end]
+]);
+//...
+
+
+Icon
+
+
+ It is also possible to change the icon of a menu item.
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuGroup::make('System', [ // [tl! focus:start]
+ MenuItem::make('Admins', new MoonShineUserResource())->icon('heroicons.hashtag'),
+ MenuItem::make('Roles', new MoonShineUserRoleResource())->icon('heroicons.hashtag'),
+ ])->icon('app') // [tl! focus:end]
+ // or
+ MenuGroup::make('Blog', [ // [tl! focus:start]
+ MenuItem::make('Comments', new CommentResource(), 'heroicons.chat-bubble-left')
+ ], 'heroicons.newspaper') // [tl! focus:end]
+]);
+//...
+
+
+
+ For more detailed information, please refer to the section Icons.
+
+
+Label
+
+
+ It is also possible to add a counter to a menu item.
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('Comments', new CommentResource())
+ ->badge(fn() => Comment::query()->count()), // [tl! focus]
+]);
+//...
+
+
+
+
+
+Translation
+
+
+ To translate menu items, you need to pass the translation key as the name
+ and add the translatable()
method.
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('menu.Comments', new CommentResource())
+ ->translatable() // [tl! focus]
+ // or
+ MenuItem::make('Comments', new CommentResource())
+ ->translatable('menu') // [tl! focus]
+]);
+//...
+
+
+
+// lang/ru/menu.php
+
+return [
+ 'Comments' => 'Comments',
+];
+
+
+
+ You can use Laravel's translation tools to translate menu labels.
+
+
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('Comments', new CommentResource())
+ ->badge(fn() => __('menu.badge.new')) // [tl! focus]
+]);
+//...
+
+
+Delimiter
+
+
+ Menu items can be visually divided using MenuDivider
+
+
+
+use MoonShine\Menu\MenuDivider; // [tl! focus]
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('Categories', new CategoryResource()),
+ MenuDivider::make(), // [tl! focus]
+ MenuItem::make('Articles', new ArticleResource()),
+]);
+//...
+
+
+
+
+
+
+ You can use text as a separator. To do this, you need to pass it to the make()
method.
+
+
+
+use MoonShine\Menu\MenuDivider; // [tl! focus]
+
+//...
+app(MoonShine::class)->menu([
+ MenuItem::make('Categories', new CategoryResource()),
+ MenuDivider::make('Divider'), // [tl! focus]
+ MenuItem::make('Articles', new ArticleResource()),
+]);
+//...
+
+
+
+
+
+
diff --git a/resources/views/pages/en/advanced/notifications.blade.php b/resources/views/pages/en/advanced/notifications.blade.php
new file mode 100644
index 00000000..f17aa5b2
--- /dev/null
+++ b/resources/views/pages/en/advanced/notifications.blade.php
@@ -0,0 +1,25 @@
+
+
+
+ If there is a need to add notifications to the MoonShine notification center, then
+ use the MoonShine\Notifications\MoonShineNotification
class.
+
+
+
+use MoonShine\Notifications\MoonShineNotification;
+
+MoonShineNotification::send(
+ message: 'Notification message',
+ // Optional button
+ button: ['link' => 'https://moonshine.cutcode.dev', 'label' => 'Click me'],
+ // Optional id of administrators (default to all)
+ ids: [1,2,3],
+ // Optional icon color (purple, pink, blue, green, yellow, red, gray)
+ color: 'green'
+);
+
+
+
+
+
+
diff --git a/resources/views/pages/en/advanced/socialite.blade.php b/resources/views/pages/en/advanced/socialite.blade.php
new file mode 100644
index 00000000..29757f9a
--- /dev/null
+++ b/resources/views/pages/en/advanced/socialite.blade.php
@@ -0,0 +1,34 @@
+
+
+
+ For convenience, you can link your account to social networks and simplify the authentication process.
+
+
+
+ This functionality is based on the Laravel Socialite package.
+
+
+
+ Make sure you have it installed and configured.
+
+
+
+ Next, in the MoonShine config config/moonshine.php
install the available drivers (you should already have them configured) and the image for the button
+
+
+
+return [
+ //
+ 'socialite' => [
+ 'github' => '/images/github.png',
+ 'facebook' => '/images/facebook.svg'
+ ]
+ //
+];
+
+
+
+ If you use your model for authentication, then you need to add the HasMoonShineSocialite
trait to it.
+
+
+
diff --git a/resources/views/pages/en/advanced/table_builder.blade.php b/resources/views/pages/en/advanced/table_builder.blade.php
new file mode 100644
index 00000000..87db7879
--- /dev/null
+++ b/resources/views/pages/en/advanced/table_builder.blade.php
@@ -0,0 +1,398 @@
+@php use MoonShine\Fields\Text; @endphp
+
+
+Basics
+
+
+ Fields and decorations in MoonShine are used inside tables in preview
mode. TableBuilder is responsible for tables.
+ Using TableBuilder, tables are displayed and filled with data.
+ You can also use TableBuilder on your own pages or even outside of MoonShine.
+
+
+
+make(
+ Fields|array $fields = [],
+ protected iterable $items = [],
+ protected ?Paginator $paginator = null
+)
+
+
+
+ fields
- fields,
+ items
- field values
+ paginator
- paginator object.
+
+
+
+TableBuilder::make([Text::make('Text')], [['text' => 'Value']])
+
+
+
+ Same thing through methods:
+
+
+
+TableBuilder::make()
+ ->fields([
+ Text::make('Text')
+ ])
+ ->items([['text' => 'Value']])
+
+
+
+ Helper is also available:
+
+
+
+@{!! table()
+ ->fields([
+ Text::make('Text')
+ ])
+ ->items([
+ ['text' => 'Value']
+ ])
+!!}
+
+
+{!!
+ table()
+ ->fields([
+ Text::make('Text')
+ ])
+ ->items([
+ ['text' => 'Value']
+ ])
+!!}
+
+Methods
+
+
+
+
+ The fields
method for declaring fields:
+
+
+
+TableBuilder::make()
+ ->fields([
+ Text::make('Text'),
+ ])
+
+
+
+
+
+ items
method for filling the table with data:
+
+
+
+TableBuilder::make()
+ ->fields([
+ Text::make('Text'),
+ ])
+ ->items([['text' => 'Value']])
+
+
+
+ The paginator
method for the table to work with pagination:
+
+
+
+$paginator = Article::paginate();
+
+TableBuilder::make()
+ ->fields([
+ Text::make('Text'),
+ ])
+ ->items($paginator->items())
+ ->paginator($paginator)
+
+// or simple
+
+TableBuilder::make(items: Article::paginate())
+ ->fields([
+ Text::make('Text'),
+ ])
+
+
+
+
+
+ The cast
method for casting table values to a specific type.
+ Since by default fields work with primitive types:
+
+
+
+use MoonShine\TypeCasts\ModelCast;
+
+TableBuilder::make(items: User::paginate())
+ ->fields([
+ Text::make('Email'),
+ ])
+ ->cast(ModelCast::make(User::class))
+
+
+
+ In this example, we cast the data to the User
model format using ModelCast
.
+
+
+
+
+ Read more about TypeCasts in the section of the same name.
+
+
+
+
+
+ To add new buttons based on ActionButton
, use the buttons
method.
+ Buttons will be added for each row, and when bulk mode is enabled, they will be displayed in the footer for bulk actions:
+
+
+
+TableBuilder::make(items: Article::paginate())
+ ->fields([ID::make(), Switcher::make('Active')])
+ ->cast(ModelCast::make(Article::class))
+ ->buttons([
+ ActionButton::make('Delete', route('name.delete')),
+ ActionButton::make('Edit', route('name.edit'))->showInDropdown(),
+ ActionButton::make('Go to home', route('home'))->blank()->canSee(fn($data) => $data->active),
+ ActionButton::make('Mass Delete', route('name.mass_delete'))->bulk()
+ ])
+
+
+
+
+
+ If you need to receive data from the table asynchronously (during pagination, sorting), then use the async
method:
+
+
+
+TableBuilder::make()
+ ->async('/async_url')
+
+
+
+
+
+ You can set any html attributes for the table using the customAttributes
method:
+
+
+
+TableBuilder::make()->customAttributes(['class' => 'custom-form']),
+
+
+
+ You can set any html attributes for table rows and cells:
+
+
+
+TableBuilder::make()->trAttributes(function(mixed $data, int $row, ComponentAttributeBag $attributes): ComponentAttributeBag {
+ return $attributes->merge(['class' => 'bgc-green']);
+}),
+
+
+{!!
+ table()
+ ->simple()
+ ->fields([
+ Text::make('Text')
+ ])
+ ->items([
+ ['text' => 'Value']
+ ])->trAttributes(function(mixed $data, int $row, $attributes) {
+ return $attributes->merge(['class' => 'bgc-green']);
+ })
+!!}
+
+
+TableBuilder::make()->tdAttributes(function(mixed $data, int $row, int $cell, ComponentAttributeBag $attributes): ComponentAttributeBag {
+ return $attributes->merge(['class' => 'bgc-red']);
+}),
+
+
+{!!
+ table()
+ ->simple()
+ ->fields([
+ Text::make('Text')
+ ])
+ ->items([
+ ['text' => 'Value']
+ ])->trAttributes(function(mixed $data, int $row, $attributes) {
+ return $attributes->merge(['class' => 'bgc-red']);
+ })
+!!}
+
+
+
+
+ By default, if the table has no data, it will be empty, but you can display the message “No records yet.”
+ To do this, use the withNotFound
method:
+
+
+
+TableBuilder::make()->withNotFound(),
+
+
+{!!
+ table()
+ ->fields([
+ Text::make('Text')
+ ])->withNotFound()
+!!}
+
+
+
+
+ By default, the table is styled as MoonShine, but using the simple
method you can display the table in a simplified style:
+
+
+
+TableBuilder::make()->simple(),
+
+
+{!!
+ table()
+ ->simple()
+ ->fields([
+ Text::make('Text')
+ ])->items([['text' => 'Value']])
+!!}
+
+
+
+
+ The preview
method disables the display of buttons and sorts for the table:
+
+
+
+TableBuilder::make()->preview(),
+
+
+
+
+
+ Using the vertical
method you can display the table in vertical mode:
+
+
+
+TableBuilder::make()->vertical(),
+
+
+{!!
+ table()
+ //->vertical() broken in alpha3, all done in repo
+ ->fields([
+ Text::make('Text'),
+ Text::make('Text 2')
+ ])->items([['text' => 'Value']])
+!!}
+
+
+
+
+ Using the creatable()
method, you can create an "Add" button to generate new records in the table:
+
+
+
+TableBuilder::make()->creatable(),
+
+
+
+ If the table contains fields in edit mode with a dynamic name,
+ then you need to add a method or parameter reindex
:
+
+
+
+ TableBuilder::make()->creatable(reindex: true),
+ // or
+ TableBuilder::make()->creatable()->reindex(),
+
+
+
+ If you want to limit the number of records that can be added, you must specify the limit
parameter:
+
+
+
+ TableBuilder::make()->creatable(limit: 6),
+
+
+{!!
+ table()
+ ->creatable()
+ ->fields([
+ Text::make('Text'),
+ Text::make('Text 2')
+ ])->items([['text' => 'Value']])
+!!}
+
+
+
+
+ By default, fields in the table are displayed in preview()
mode,
+ but if you want to display them as editable form elements,
+ then you need to use the editable()
method:
+
+
+
+TableBuilder::make()->editable(),
+
+
+{!!
+ table(items: [['text' => 'Value', 'field' => 'Value'], ['text' => '', 'field' => '']])
+ ->creatable()->reindex()->editable()
+ ->fields([
+ Text::make('Text'),
+ Text::make('Field')
+ ])
+!!}
+
+
+
+ In append mode, the last element must be empty (the skeleton of the new entry):
+
+
+
+
+
+
+ To sort rows in a table, use the sortable()
method:
+
+
+
+sortable(
+ ?string $url = null,
+ string $key = 'id',
+ ?string $group = null
+)
+
+
+
+ url
- url handler
+ key
- element key
+ group
- grouping.
+
+
+
+TableBuilder::make()
+ ->sortable(url: '/update_indexes_endpoint', key: 'id', group: 'nested'),
+
+
+{!!
+ table(items: [['text' => 'Value 1', 'field' => 'Value 1'], ['text' => 'Value 2', 'field' => 'Value 2']])
+ ->sortable()
+ ->fields([
+ Text::make('Text'),
+ Text::make('Field')
+ ])
+!!}
+
+
diff --git a/resources/views/pages/en/advanced/type_casts.blade.php b/resources/views/pages/en/advanced/type_casts.blade.php
new file mode 100644
index 00000000..28fecfdb
--- /dev/null
+++ b/resources/views/pages/en/advanced/type_casts.blade.php
@@ -0,0 +1,88 @@
+@php use MoonShine\Fields\Text; @endphp
+
+
+
+ By default in MoonShine, fields operate on primitive types and do not know anything about models.
+ This was done so that the system was not tied only to models, and the fields could, depending on the situation
+ have access to both raw data and typed data
+
+
+
+ TypeCast for models is already included in the MoonShine box, but if you need
+ work with another data type, you will need an object that implements the MoonShineDataCast interface
+
+
+
+namespace MoonShine\Contracts;
+
+interface MoonShineDataCast
+{
+ public function getClass(): string;
+
+ public function hydrate(array $data): mixed;
+
+ public function dehydrate(mixed $data): array;
+}
+
+
+
+ Let's take a look at the TypeCast example for models
+
+
+
+namespace MoonShine\TypeCasts;
+
+use Illuminate\Database\Eloquent\Model;
+use MoonShine\Contracts\MoonShineDataCast;
+
+final class ModelCast implements MoonShineDataCast
+{
+ public function __construct(
+ protected string $class
+ ) {
+ }
+
+ public function getClass(): string
+ {
+ return $this->class;
+ }
+
+ public function hydrate(array $data): mixed
+ {
+ return (new ($this->getClass())($data));
+ }
+
+ public function dehydrate(mixed $data): array
+ {
+ return $data->attributesToArray();
+ }
+}
+
+
+
+ Well, its application in FormBuilder/TableBuilder
+
+
+
+use MoonShine\TypeCasts\ModelCast;
+
+TableBuilder::make(items: User::paginate())
+ ->fields([
+ Text::make('Email'),
+ ])
+ ->cast(ModelCast::make(User::class))
+
+
+
+use MoonShine\TypeCasts\ModelCast;
+
+FormBuilder::make()
+ ->fields([
+ Text::make('Email'),
+ ])
+ ->fillCast(User::query()->first(), ModelCast::make(User::class))
+
+
+
\ No newline at end of file
diff --git a/resources/views/pages/ru/advanced/authorization.blade.php b/resources/views/pages/ru/advanced/authorization.blade.php
index 1f407d9f..e5daf74e 100644
--- a/resources/views/pages/ru/advanced/authorization.blade.php
+++ b/resources/views/pages/ru/advanced/authorization.blade.php
@@ -17,7 +17,7 @@
В ресурс-контроллерах MoonShine каждый метод будет проверяться на наличие прав.
- Если возникают трудности, то ознакомьтесь с официально документацией
+ Если возникают трудности, то ознакомьтесь с официальной документацией
Laravel.