Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Administrator Laravel Package

frozennode/administrator

Frozennode Administrator is a Laravel admin package that generates configurable CRUD interfaces for Eloquent models, with built-in authentication, relationships, filters, sorting, and customizable fields and actions.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package into a Laravel 4.x/5.0–5.2 project (it will not resolve on modern Laravel — see Gotchas):

composer require frozennode/administrator

Because it predates package auto-discovery, register it manually in config/app.php:

'providers' => [
    // ...
    'Frozennode\Administrator\AdministratorServiceProvider',
],
'aliases' => [
    // ...
    'Administrator' => 'Frozennode\Administrator\Facades\Administrator',
],

Publish the config and the front-end assets:

php artisan vendor:publish
# older Laravel 4:
# php artisan config:publish frozennode/administrator
# php artisan asset:publish frozennode/administrator

Set the essential values in config/administrator.php (or app/config/packages/frozennode/administrator/administrator.php on L4): title, login_path (where unauthenticated users are redirected), redirect_path, home_page, and the menu array. Point model_config_path at the directory that will hold one config file per model (config/administrator by default on L5).

Then write your first model config — the whole package is driven by these files:

// config/administrator/posts.php  ->  /admin/posts
return [
    'title'  => 'Posts',
    'single' => 'post',
    'model'  => 'App\Post',
    'columns' => ['id', 'title', 'created_at'],
    'edit_fields' => [
        'title'      => ['type' => 'text'],
        'body'       => ['type' => 'wysiwyg'],
        'published'  => ['type' => 'bool'],
        'author'     => ['type' => 'relationship', 'name' => 'author', 'title' => 'Author'],
    ],
    'sort' => ['column' => 'created_at', 'direction' => 'desc'],
];

Visit /admin and log in via your existing auth flow. The first real use case is exactly this: a small internal back office over a handful of Eloquent models where you want CRUD screens without writing controllers or Blade views.

Where to look first

  • config/administrator.php — global behavior (auth redirect, menu, dashboard, route middleware).
  • The per-model config files — this is where 90% of your day-to-day work lives.
  • vendor/frozennode/administrator/src/Frozennode/Administrator/Fields/ — the authoritative list of field types and their supported options (the README is thin on details).

Implementation Patterns

One config file per model, filename = route slug. users.php becomes /admin/users. Keep these in version control alongside your models. single => true turns a config into a singleton settings-style page with no list view.

Use columns and edit_fields as two separate projections. columns drives the index table (display names as keys, 'column'/'relation' keys for relations); edit_fields drives the create/edit form with type plus type-specific options. Don't try to make one do both.

query_filter for row-level scoping and eager loading. It receives the query builder and must return it:

'query_filter' => function ($query) {
    if (! Auth::user()->isAdmin()) {
        $query->where('user_id', Auth::id());
    }
    return $query->with('author');
},

action_permissions for per-record authorization. Keys are view, create, update, delete, and each can be a closure receiving the model. Pair this with the global permission closure so editors get a "no access" page rather than a broken form.

Field-type mapping you'll reach for constantly: text, textarea, wysiwyg, markdown, number, password, date, datetime, enum, bool, image, file, color, key, relationship. For relationships, 'name' => 'author' is the Eloquent method name; belongs_to/has_many/many_to_many options are inferred, but you can override with 'options' => function () { return User::pluck('name', 'id'); }.

formatter vs setter. formatter transforms a value for display in the list; setter transforms on save (function (&$model, $value) { $model->password = Hash::make($value); }). This is how you handle hashing, JSON packing, slug generation, and date normalization.

filters for the index view. Declare them explicitly with 'type' => 'date' / 'type' => 'select'; date filters also need date_format. Filters are the fastest way to make a large table usable without writing a custom query screen.

custom_actions for workflow buttons (approve, export, restore). The closure gets the model and can return a message. Actions appear as row buttons and POST to a generated route, so they inherit your middleware.

Menu grouping and dashboard. Global menu takes groups with title and items; home_page picks the model shown after login, and dashboard_view lets you render a custom dashboard Blade partial instead of a model list. This is the cheapest place to give non-technical users a landing page.

Override views, don't fork. Mirror the package view under your app's package-views directory (app/views/packages/frozennode/administrator/ on L4, resources/views/packages/... on L5) and the view finder prefers yours. Use this for branding, custom row markup, or extra buttons.

Protect the routes yourself. On L5.2+ set 'middleware' => 'auth' in the global config if your version supports it; otherwise wrap the generated route group in your own middleware. Always verify with php artisan route:list that admin/* routes are behind auth.

Gotchas and Tips

  • It's abandoned. Last release 2016-08-15, targeted at Laravel 4/5.0–5.2 and PHP 5.x. It won't install on Laravel 6+ (dependency constraints), and on PHP 8 it trips on removed helpers and iterator/ArrayAccess signatures. Before committing, price up a maintained alternative (Filament, Nova, Backpack) or a fork you own — the config-file productivity gain evaporates if you're maintaining the package itself.
  • login_path does not authenticate. It's only the redirect target for the login page. Without auth middleware the entire admin (including delete routes) is public. Add the middleware before you create the first model config.
  • Missing provider = blank page or "Class 'Administrator' not found." There is no auto-discovery; forgetting the provider/alias in config/app.php is the most common first-run failure.
  • Config caching and path typos fail silently. After editing model configs run php artisan config:clear. If model_config_path is wrong you get "no models" rather than an error. A model config whose model class doesn't autoload also tends to 404/blank rather than explain itself.
  • Filename is the route. Renaming posts.php to blog_posts.php changes the URL; there is no separate slug setting to fall back on.
  • Sorting/filtering on joined columns is flaky. Qualify with the table name (posts.created_at), and if it still misbehaves, fall back to query_filter ordering or an accessor column.
  • Assets must be published. Broken wysiwyg editors, dead image upload buttons, and missing CSS all usually mean public/packages/frozennode/administrator wasn't published. Image fields additionally need location (filesystem path) and name (public URL prefix), plus sizes for thumbnails.
  • Date fields need the right date_format. A mismatch saves 0000-00-00 instead of erroring. Use the PHP format string the picker expects (m/d/Y, Y-m-d H:i:s).
  • Password fields: never put password in columns; use a setter to hash and a 'visible' => false on edit fields where you want it omitted from the grid. Skipping the setter stores plaintext.
  • unique validation needs care. The package's validation_rules are plain Laravel rules; on update, unique will flag the record against itself unless you use Rule::unique(...)->ignore($id) or a closure. messages in the model config customizes the copy.
  • Custom actions can fail silently. A CSRF token or middleware mismatch makes the button a no-op. Check the browser network tab and storage/logs/laravel.log; confirm the action name appears under custom_actions with the right permissions key.
  • Soft deletes: default scopes hide deleted rows, but a deleted_at column in columns confuses editors. Expose restore as a custom_action and keep the timestamp out of the grid.
  • Heavy closures run every request. options and formatter closures execute on each page render — don't put unbounded queries in them; cache option lists if the table is large.
  • Stay out of vendor/. View overrides and custom Field subclasses (bind your own widget type) are the supported extension points; editing package source will be lost on the next composer update.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core