Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
28 changes: 26 additions & 2 deletions docs/content/architecture/configuration.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Configuration

`config/redot.php` is the single configuration file for `redot/core`. It controls which application surfaces are mounted, the locales the app supports, and locale-aware routing. Its values are available as `config('redot.*')` out of the box. Runtime-editable settings are defined separately in `app/settings.php`.
`config/redot.php` is the single configuration file for `redot/core`. It controls which application surfaces are mounted, the locales the app supports, locale-aware routing, and the bundled packages (Datatables and Toastify). Its values are available as `config('redot.*')` out of the box. Runtime-editable settings are defined separately in `app/settings.php`.

## Publishing the config

Expand All @@ -15,7 +15,7 @@ The config is merged at runtime, so every key is readable without publishing. Pu
`redot.features` toggles the four mountable surfaces and, where relevant, their URL prefix. The package reads these flags both when registering routes and to conditionally render UI (e.g. hiding a "Preview website" link).

- **`website`** — mounts the public website routes. Set `enabled` to turn it on or off.
- **`dashboard`** — mounts the back-office routes. `enabled` toggles it; `prefix` sets the URL segment it lives under (default `dashboard`).
- **`dashboard`** — mounts the back-office routes. `enabled` toggles it; `prefix` sets the URL segment it lives under (default `dashboard`); `guard` names the auth guard dashboard users sign in with (default `admins`). The sidebar, `route_allowed()`, and `permissions:sync` fall back to this guard when a route doesn't name one.
- **`website-api`** — mounts the public website API routes under `api/`. Set `enabled` to toggle it.
- **`dashboard-api`** — mounts the dashboard API routes. `enabled` toggles it; `prefix` sets the segment under `api/` (default `dashboard`).

Expand Down Expand Up @@ -43,6 +43,30 @@ Once languages exist in the database, the active locale list is built from them,
- **`append_locale_to_url`** — when on, the website/dashboard routes are prefixed with a two-letter `{locale}` segment. Turn it off to serve those routes without a locale segment.
- **`redirect_non_locale_urls`** — when on, a request to a non-prefixed URL is redirected to its locale-prefixed equivalent (preserving the query string). When off, such URLs return a 404 instead.

## Paths

`redot.paths` tells core where your application keeps the files it loads by convention. Paths are relative to the application base path.

- **`routes`** — the `global`, `website`, `dashboard`, `website-api`, and `dashboard-api` route files. Core registers its own global routes (select search, uploads) before yours, so a route in your global file with the same URI and name replaces the package one.
- **`layouts.path`** / **`layouts.namespace`** — where `<x-layouts::…>` finds anonymous layout views and layout classes.

When you change one path, copy the whole `paths` block into your config: Laravel merges package config only at the top level, so a partial block leaves the other paths undefined.

## Components

`redot.components` controls the routes behind three components: `select` (the search endpoint of `<x-select-remote>`), `uploader` (the upload endpoint of `<x-uploader>`), and `hugerte` (image uploads in `<x-rich-editor>`). Each takes:

- **`enabled`** — registers the routes. Turn it off when the application doesn't use the component; the rich editor keeps working without image uploads.
- **`middleware`** — middleware added to those routes, `throttle:120,1` by default. Add `auth:admins` (or another guard) to limit who can call them.

## Datatables

`redot.datatables` configures the [Datatables](/packages/datatables/overview) package: `assets` holds the CSS/JS paths the table loads, and `export` lists each export format with its `enabled` flag and exporter class (plus the template, adapter, and engine options for [PDF](/packages/datatables/export)).

## Toastify

`redot.toastify` configures [Toastify](/packages/toastify): `toastifiers` maps each toast type to its icon and color, and `defaults` sets the position, delay, and close button applied to every toast.

## Permissions

`redot.permissions` controls local development shortcuts around route gating.
Expand Down
11 changes: 3 additions & 8 deletions docs/content/commands/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,13 @@ Creates a symbolic link from the framework's `public/` directory to a sibling di

- **`--name`** — the name of the link to create (defaults to `public_html`).

## `datatables:link`
## `redot:publish`

```bash
php artisan datatables:link
php artisan datatables:link --force
php artisan datatables:link --relative
php artisan redot:publish
```

Creates a symbolic link from `public/vendor/datatables` to the Datatables package assets. Required once per install (and again after upgrades) so the table's CSS/JS are served statically. Prefer `vendor:publish --tag=datatables::assets` if symlinks are unavailable.

- **`--force`** — recreate the symlink if it already exists.
- **`--relative`** — create a relative symlink.
Publishes the Redot front-end assets — the shared runtime, plugins, styles, Datatables assets, and the third-party libraries they use — to `public/vendor/redot`. It replaces the whole directory, so files removed from the package don't linger. The starter kit runs it from Composer's `post-install-cmd` and `post-update-cmd`, so the published assets always match the installed `redot/core`.

## `permissions:sync`

Expand Down
12 changes: 12 additions & 0 deletions docs/content/components/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ To give a custom control the same label, hint, and required marker, wrap it in [

Components that wrap a JavaScript widget (date pickers, selects, the rich editor, uploader, …) light up automatically through the [asset & init system](/frontend/asset-system) — you don't wire up any JS yourself.

## Overriding a component

The components on this page ship inside the `redot/core` package, so they update with `composer update`. Only the branding and integration components ([Logo](/components/logo), [Favicon](/components/favicon), [Page Loader](/components/page-loader), [Countries](/components/countries), [Facebook Pixel](/components/facebook-pixel), and [Google Analytics](/components/google-analytics)) live in your application. You can still replace a package component in your application without renaming it:

- **Markup** — add a view with the same name under `resources/components`, such as `resources/components/toasts.blade.php`. Your view is used instead of the package's.
- **Behavior** — add a class with the same name under `App\View\Components`, such as `App\View\Components\Toasts`. Extend the package class (`Redot\View\Components\Toasts`) to change only what you need.

A markup override of a component that has a class still runs the package class, so your view receives the same props and data as the package view. To add, remove, or rename props, override the class as well.

The JavaScript and CSS these components load ship with core, along with the third-party libraries they use (jQuery, Tabler, Tom Select, HugeRTE, Coloris, …). `php artisan redot:publish` copies them to `public/vendor/redot` and runs after every `composer install` and `composer update`, so don't edit them there.

## Component index

### Form inputs
Expand Down Expand Up @@ -61,6 +72,7 @@ Components that wrap a JavaScript widget (date pickers, selects, the rich editor
- [Form Card](/components/form-card) — `<x-form-card>`
- [Page Header](/components/page-header), [Page Loader](/components/page-loader)
- [Pagination](/components/pagination)
- [Redot Styles & Scripts](/frontend/asset-system#loading-the-runtime) — `<x-redot-styles>` / `<x-redot-scripts>`, the shared runtime for a layout
- [Empty](/components/empty) — empty-state placeholder
- [Layouts](/layouts/overview) — page shells (`<x-layouts::dashboard>`, …)

Expand Down
6 changes: 5 additions & 1 deletion docs/content/foundation/helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

## URLs & routing

- **`route_allowed('route.name')`** — whether the current admin may access a named route. Use it to show/hide permission-gated UI. It applies the same conventional and explicit permission aliases as route middleware. Routes that opt out of permission middleware are allowed; protected routes defer to the gate. The guard is guessed from the route's `auth` middleware (falling back to `admins`); pass one explicitly as the second argument to override. See [Datatables](/packages/datatables/overview) for the common use.
- **`route_allowed('route.name')`** — whether the current admin may access a named route. Use it to show/hide permission-gated UI. It applies the same conventional and explicit permission aliases as route middleware. Routes that opt out of permission middleware are allowed; protected routes defer to the gate. The guard is guessed from the route's `auth` middleware (falling back to `redot.features.dashboard.guard`); pass one explicitly as the second argument to override. See [Datatables](/packages/datatables/overview) for the common use.

```php
Action::edit('posts.edit')->visible(route_allowed('posts.edit'));
Expand All @@ -42,6 +42,8 @@
<a href="{{ back_or_route($back, $backParams) }}" class="btn">{{ __('Back') }}</a>
```

- **`is_dashboard_request()`** — whether the current request belongs to the dashboard, including unmatched URLs (such as 404s) under the dashboard prefix. Useful in shared views like error pages.

## Requests & API responses

- **`throw_api_exception($e)`** — turn any caught exception into the standard JSON error envelope (mapping common exceptions to the right HTTP status). You rarely call this directly — it is wired in as the global JSON exception renderer. See [Controllers & API Responses](/foundation/controllers-and-responses).
Expand All @@ -54,6 +56,8 @@
}
```

- **`current_sessions('admins')`** — the active browser sessions of the account signed in on the given guard, newest first. Returns an empty collection unless the `database` session driver is used.

- **`is_mobile()` / `is_desktop()`** — detect the device from the request's user agent. Both return `false` safely when there is no request (e.g. console).

```php
Expand Down
32 changes: 31 additions & 1 deletion docs/content/frontend/asset-system.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Asset & Init System

The dashboard frontend is shipped as static assets under `public/assets` — there is no Vite/Webpack build for the platform layer. A small artisan step compiles per-feature "init" scripts and translations, and a runtime `init()` bootstrap attaches them to any element that carries an `init="..."` attribute. This page is the canonical reference for how JavaScript widgets get wired up.
The dashboard frontend is shipped as static assets — there is no Vite/Webpack build for the platform layer. The shared runtime (`functions.js`, `themer.js`, the `redot-*` plugins, and `redot.css`) ships with `redot/core`, together with the third-party libraries it relies on, and `php artisan redot:publish` copies all of it to `public/vendor/redot`. Your application's own assets live under `public/assets`. A small artisan step compiles per-feature "init" scripts and translations, and a runtime `init()` bootstrap attaches them to any element that carries an `init="..."` attribute. This page is the canonical reference for how JavaScript widgets get wired up.

## Enabling a widget with `init`

Expand Down Expand Up @@ -33,6 +33,33 @@ Each has its own page with the options it accepts:
- [Turnstile](/frontend/inits/turnstile) — Cloudflare captcha
- [Uploader](/frontend/inits/uploader)

## Loading the runtime

A layout loads the whole shared runtime with two components, so the list of libraries and their order stays with `redot/core` and updates with it:

```blade
<head>
...
<x-redot-styles :direction="$direction" />
<link rel="stylesheet" href="{{ hashed_asset('/assets/css/app.css') }}" />
</head>

<body>
{{ $slot }}

<x-redot-scripts />
<script src="{{ hashed_asset('/assets/js/app.js') }}"></script>

@stack('plugins-scripts')
@stack('scripts')
</body>
```

- **`<x-redot-styles>`** — Tabler (in the given `direction`, defaulting to the current language's), Tabler Icons, Glare, OverlayScrollbars, the `plugins-styles` stack, and `redot.css`. Load your application CSS right after it so your rules win.
- **`<x-redot-scripts>`** — jQuery, Lodash, Tabler, `functions.js`, the bundled plugins, the translations and initializer bundles, the runtime (`runtime.js`: running initializers as markup appears, client-side form validation, the CSRF header and session-expiry dialog for AJAX, lightbox links, and Bootbox defaults), toasts, and the restoring of submitted input and validation errors. Load your application script right after it; `app.js` is yours to fill.

The scaffold layout already uses both. To change what they load, [override](/components/overview) `resources/components/redot-styles.blade.php` or `redot-scripts.blade.php`.

## Loading a widget's vendor files

Components load the third-party scripts and styles their widget needs. If you put an `init` attribute on your own markup instead, include the matching `<x-assets.*>` component so those files are on the page:
Expand Down Expand Up @@ -93,9 +120,12 @@ php artisan dependencies:build
2. Use it from Blade: `<div init="my-widget" mywidget-animation="300"></div>`.
3. The next request rebuilds `dist/` and your initializer is live as `init="my-widget"`.

The built-in initializers ship with `redot/core`. To change one, add a file with the same name to `public/assets/inits` (for example `public/assets/inits/tomselect.js`); it replaces the package version in the build.

## Gotchas

- **Never edit `public/assets/dist/*` by hand** — it is regenerated. Edit the source `public/assets/inits/*.js` and `lang/*` files instead.
- **Never edit `public/vendor/redot/*`** — `redot:publish` replaces it after every `composer install` and `composer update`. Override a component or initializer in your application instead.
- An element is initialized only once. If you re-render it and need it re-initialized, render fresh markup rather than reusing an already-initialized element.

## Related
Expand Down
2 changes: 1 addition & 1 deletion docs/content/frontend/inits/hugerte.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ See [Asset & Init System](/frontend/asset-system) for how the `init` attribute i

## Options

The toolbar, plugins, and height come preconfigured, and the editor reads its language, direction, and skin from the page — so there is little to set per field. Images pasted or picked in the editor upload automatically through the configured upload endpoint.
The toolbar, plugins, and height come preconfigured, and the editor reads its language, direction, and skin from the page — so there is little to set per field. Images pasted or picked in the editor upload automatically to the URL in the field's `hugerte-upload-url` attribute, which `<x-rich-editor>` fills in from the `global.hugerte.upload` route. Without that attribute (for example when `redot.components.hugerte.enabled` is off), image uploads are turned off.

The field must have an `id` (the component generates one if you omit it). When the user toggles light/dark, the editor rebuilds to pick up the new skin.

Expand Down
7 changes: 3 additions & 4 deletions docs/content/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,10 @@ php artisan migrate

## Sub-package publish tags

The bundled packages expose their own tags, all following the `package::resource` convention. Their config, views, lang, and routes load automatically; publish only to override.
The bundled packages share the Redot configuration and publish tags: their settings live in `config/redot.php` (under `datatables` and `toastify`), and their assets are published by `php artisan redot:publish`. Views and translations load automatically; publish only to override.

- **Datatables** — `datatables::config`, `datatables::views`, `datatables::lang`, `datatables::assets`. Run `php artisan datatables:link` (or publish `datatables::assets`) so CSS/JS are available under `public/vendor/datatables`. See [Datatables](/packages/datatables/overview).
- **Toastify** — `toastify::config`. See [Toastify](/packages/toastify).
- **Auth, Sidebar, LangExtractor** — nothing to publish; they are wired up for you.
- **Datatables** — `redot::datatables-views`, `redot::datatables-lang`. See [Datatables](/packages/datatables/overview).
- **Toastify, Auth, Sidebar, LangExtractor** — nothing extra to publish; they are wired up for you.

## Publish everything at once

Expand Down
12 changes: 6 additions & 6 deletions docs/content/packages/datatables/export.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Every datatable can offer an export menu so users download the current dataset.

## Enabling PDF export

PDF is configured in `config/datatables.php` under the `export` block. Publish the config first:
PDF is configured under `datatables.export` in `config/redot.php`. Publish the Redot config first if you haven't:

```bash
php artisan vendor:publish --tag=datatables::config
php artisan vendor:publish --tag=redot::config
```

PDF export needs a rendering library installed. The default uses mPDF — install it and you're done:
Expand All @@ -20,7 +20,7 @@ If the export menu offers PDF but the library isn't installed, the export fails

## Options

Configure these under `export.pdf` in `config/datatables.php`:
Configure these under `datatables.export.pdf` in `config/redot.php`:

- **`enabled`** — whether PDF appears among the table's export choices.
- **`template`** — the Blade view rendered into the PDF. Defaults to the packaged template; point it at your own for a custom layout.
Expand All @@ -38,7 +38,7 @@ composer require barryvdh/laravel-dompdf
```

```php
// config/datatables.php
// config/redot.php — datatables.export.pdf
'adapter' => \Redot\Datatables\Adapters\PDF\DomPdf::class,
```

Expand Down Expand Up @@ -76,14 +76,14 @@ Set `template` to your own Blade view. Your template receives `$headings` (an ar
```

```php
// config/datatables.php
// config/redot.php — datatables.export.pdf
'template' => 'templates.pdf.datatable',
```

To tweak the packaged template instead of replacing it, publish the views and edit your copy:

```bash
php artisan vendor:publish --tag=datatables::views
php artisan vendor:publish --tag=redot::datatables-views
```

### Per-table overrides
Expand Down
Loading
Loading