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

Nova Page Tool Laravel Package

digitalcloud/nova-page-tool

DigitalCloud Nova Page Tool adds CMS-style page management to Laravel Nova. Create, edit, and organize editable pages with templates and SEO-friendly content from your admin panel, making it easy to add static or marketing pages to any Laravel application.

View on GitHub
Deep Wiki
Context7

Getting Started

Check compatibility first. This is a Nova 1.x-era tool (last release December 2018), so it targets Laravel 5.7/5.8, PHP 7.1–7.3, and Nova ^1.0. It will not work on Nova 2+, Laravel 6+, or PHP 8 without patching. Verify composer.json before pulling it into any modern app.

Minimal install for a legacy-compatible app:

composer require digitalcloud/nova-page-tool
php artisan vendor:publish --provider="DigitalCloud\NovaPageTool\ToolServiceProvider" --tag=config
php artisan vendor:publish --provider="DigitalCloud\NovaPageTool\ToolServiceProvider" --tag=migrations
php artisan migrate
php artisan nova:publish   # only if the tool ships compiled assets you need

Register the tool in app/Providers/NovaServiceProvider.php:

public function tools()
{
    return [
        new \DigitalCloud\NovaPageTool\NovaPageTool(),
    ];
}

Where to look first:

  1. vendor/digitalcloud/nova-page-tool/src/ — look for the Page model, the ToolServiceProvider, and any routes/ or database/migrations/ folder. The migrations will tell you the schema (title, slug, body, meta fields), which drives everything downstream.
  2. vendor/digitalcloud/nova-page-tool/resources/js/tool.js — tells you what the UI actually edits.
  3. vendor/digitalcloud/nova-page-tool/config/*.php — for any table name, route prefix, or model override settings.

First use case: drop the tool in, migrate, open /nova, click Pages in the sidebar, create a page with a slug like about and a body, then wire a catch-all frontend route to fetch and render it:

Route::get('/{slug}', function ($slug) {
    $page = \DigitalCloud\NovaPageTool\Models\Page::where('slug', $slug)->firstOrFail();
    return view('page', compact('page'));
})->where('slug', '.*');

That single flow — Nova-managed pages + a catch-all frontend route — is the primary value of the package.

Implementation Patterns

Content authoring via the tool UI, rendering via a wildcard route. The pattern this package is designed around is: non-technical editors create/update pages in the Nova tool; the frontend resolves them by slug through a single controller or route. Keep a real controller class rather than the closure above so you can add caching, view data, and 404 handling in one place.

Treat the Page model as an Eloquent model, not an API. Because it's a plain model (assuming standard Nova-era scaffolding), you can:

  • Seed demo/initial pages in a seeder for local development
  • Query from Blade components, sitemap generators, or menu builders
  • Wrap it in a repository if you need to swap storage later
// Menu builder example
Menu::add('About', Page::where('slug', 'about')->value('slug'));

Custom field extension for structured content. The typical Nova-tool pattern exposes the underlying fields through the tool's Vue component. If the tool only supports a plain body field but you need extra meta (SEO title, description, hero image), the cleanest approach with this era of Nova is:

  1. Add columns via your own migration (don't edit the vendor migration).
  2. Add matching Nova fields to the tool's registered fields or the underlying resource if it has one.
  3. Cast them on the model — protected $casts = ['meta' => 'array'] if a JSON blob was used.

Integrate with caching. Pages change rarely; the frontend query should not hit the DB on every request:

$page = Cache::rememberForever("page:{$slug}", fn () => Page::where('slug', $slug)->firstOrFail());
// In Nova tool or model observer: Cache::forget("page:{$page->slug}"); on save

If the tool bypasses model events (it may write via its own controller), wire cache invalidation into whichever save path it uses — or use short TTLs.

Pair with a slug-route constraint so admin routes (/nova/*) and static routes don't get swallowed. Register your page route last:

// ... all other routes ...
Route::get('/{slug}', [PageController::class, 'show'])->where('slug', '[a-zA-Z0-9\-\/]+');

Multi-page layout reuse. Store a template column (or meta) so editors can pick between layouts in the tool UI, then resolve in the controller: view("pages.{$page->template}").

Localization / multi-site: not handled by the tool. If you need it, either add a locale column and composite unique index (slug, locale), or wrap the package behind your own resource.

Gotchas and Tips

Unmaintained since Dec 2018. The package predates Nova 2 and Laravel 6. Concretely:

  • Nova's tool.js build changed significantly after 1.3; older scripts sometimes fail silently under newer Nova.
  • Illuminate\Support\Str::slug and route registration APIs are stable, so the backend often survives, but the Vue tool UI is the fragile part.
  • If you must upgrade later, budget for replacing this tool with a bespoke Nova Resource + fields rather than trying to patch it.

The migration is additive but not reversible cleanly. Publishing the migration gives you a pages table name that may collide with a table you already made. Check config/ for an override before running migrate; if none exists, rename the table in the published migration before running it.

Slug changes break live URLs. There's typically no redirect table. Add one in your app:

PageObserver::updated → if slug changed, insert into page_redirects (old_slug, page_id)

and resolve redirects in your PageController::show before the 404.

Asset publishing is usually required but easy to miss. Nova tools ship a compiled JS bundle. If the sidebar entry appears but clicking it shows a blank page, run:

php artisan nova:publish

and check public/vendor/digitalcloud/nova-page-tool/. Stale published assets are the #1 "why is my tool UI empty" cause with Nova 1 tools.

Route registration collisions. Tools register their own routes under the nova middleware group. If you use a catch-all /{slug} for public pages, make sure it's registered after Nova::routes() in RouteServiceProvider — otherwise /nova/pages can be shadowed and the tool's AJAX calls return your page view instead of JSON.

Permissions are likely "all or nothing." This era of tools often gate access via Gate::define or just the standard Nova auth. If editors should see pages but not other resources, wrap it in a Nova::tools() conditional:

public function tools()
{
    $tools = [];
    if (Gate::allows('manage-pages')) {
        $tools[] = new \DigitalCloud\NovaPageTool\NovaPageTool();
    }
    return $tools;
}

Verify whether the tool or your app is responsible — check the boot() in ToolServiceProvider for Gate:: calls.

No HTML sanitization guaranteed. If editors can paste rich HTML into the body, render it with {!! !!} only if you trust the editors, or sanitize:

{!! Purify::clean($page->body) !!}

A page-management tool is a common XSS sink in CMS-flavored apps.

Debugging the tool UI: open browser devtools → Network tab, click the tool. If you see 404s on /nova-vendor/digitalcloud/... calls, the tool's route prefix wasn't registered (usually a service provider discovery issue). If you see 500s, check storage/logs/laravel.log — tool controllers in this era don't always catch exceptions gracefully.

Extension point: replace the model. If the tool resolves the model via config (common pattern), you don't need to fork it:

// config/nova-page-tool.php
'model' => App\Models\Page::class,

Extend the vendor model and override getRouteKeyName, casts, or accessors. This is the intended way to add behavior without forking.

Final recommendation for a modern project: treat this as a reference implementation rather than a dependency. The functionality — slug-keyed pages editable in Nova — is roughly 150 lines of your own Nova Resource + a controller. Given the last release is 2018 and it's unlikely to work on current Nova, most teams will spend less time writing a thin replacement than patching this one. Only use it as-is if you're maintaining a legacy Nova 1 app that already depends on it.

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.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus