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

Extended Routes Laravel Package

dragon-code/extended-routes

A small Laravel package that extends the native router with extra helper methods and macros, letting you declare routes more concisely while staying fully compatible with standard Laravel routing, middleware, and route caching.

View on GitHub
Deep Wiki
Context7

Getting Started

Install it like any small Laravel helper:

composer require dragon-code/extended-routes

There is no config file to publish and no migration step. Laravel package auto-discovery registers the service provider. After install, the first thing to inspect is the package source (src/) and the README, because the value of this package is a thin routing macro layer rather than a large framework. Then run:

php artisan route:list

to see exactly which routes the macro adds to your application. That is the fastest way to verify the package's behavior against your Laravel version.

The first realistic use case is a soft-deletable resource. Instead of hand-writing restore and force-delete routes next to Route::resource(), you register the resource and let the package add the trashed endpoints:

// routes/web.php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;

Route::resource('posts', PostController::class)->withTrashed();

The resulting resource now includes the normal CRUD routes plus the trashed operations, typically:

  • PATCH /posts/{post}/restore → posts.restore
  • DELETE /posts/{post}/force → posts.forceDelete

Your controller then implements the corresponding actions:

public function restore(Post $post)
{
    $post->restore();

    return back()->with('status', 'Post restored.');
}

public function forceDelete(Post $post)
{
    $post->forceDelete();

    return redirect()->route('posts.index');
}

That is the day-to-day win: fewer hand-maintained routes, consistent naming, and soft-delete behavior expressed directly in the route definition.

The current release line is 4.x; 4.0.1 is a patch that only adjusts Composer dependency constraints. It adds no routes, options, or config, so the install and first-use flow above is unchanged from 4.0.0. Treat the upgrade from 4.0.x as a routine composer update and re-run route:list afterwards to confirm nothing shifted.

Implementation Patterns

Use resource routes as the default, not the exception. The package is most useful when your application already follows Laravel resource conventions. Register the resource once and chain the trashed behavior:

Route::resource('posts', PostController::class)->withTrashed();

For API-only controllers, keep the same pattern with apiResource so you do not accidentally expose create and edit HTML routes:

Route::apiResource('posts', PostController::class)->withTrashed();

Confirm the exact chained method names against the package README/source for your installed version, then standardize on one form across the codebase so route definitions stay predictable. The 4.0.1 patch did not change this surface, so any snippets you collected for 4.0.0 remain valid.

Pair the routes with route model binding that can see trashed models. The restore and force-delete endpoints receive a model that is soft-deleted, so implicit binding will normally return 404. Resolve it explicitly:

public function restore(Post $post)
{
    // If the route binding does not already include trashed models:
    // $post = Post::withTrashed()->findOrFail($post->id);
    $post->restore();

    return response()->noContent();
}

A cleaner pattern is a dedicated route binding for the trashed actions, or a small base controller method that resolves with withTrashed(). Do this consistently so restore/force-delete never fail because of binding behavior.

Authorize the trashed actions separately. Policies usually need restore and forceDelete abilities in addition to update and delete. Wire them through middleware or authorize() calls:

public function restore(Post $post)
{
    $this->authorize('restore', $post);
    $post->restore();

    return back();
}

If you use Route::resource(...)->withTrashed() inside a group with auth middleware, the authorization still belongs in the controller or policy — routing does not enforce it.

Keep URL design consistent across nested resources. For nested soft-deletable resources, use shallow nesting or explicit parameters so restore/force-delete URLs remain readable:

Route::resource('users.posts', PostController::class)
    ->shallow()
    ->withTrashed();

Check route:list afterward; nested resource parameter names and generated route names are the most common source of surprises.

Expose trashed listings deliberately. A common workflow is a normal index for active records and a query flag or separate endpoint for trashed ones:

public function index(Request $request)
{
    $posts = $request->boolean('trashed')
        ? Post::onlyTrashed()->paginate()
        : Post::paginate();

    return view('posts.index', compact('posts'));
}

If the package provides a trashed-index helper in your version, prefer it; otherwise keep the filter in the controller so the route surface stays small.

Use form method spoofing in Blade. Restore and force-delete are PATCH/DELETE routes, so forms need @method:

<form method="POST" action="{{ route('posts.restore', $post) }}">
    @csrf
    @method('PATCH')
    <button type="submit">Restore</button>
</form>

Test the generated routes, not just the controller. Feature tests should hit the restore and force-delete endpoints and assert both the database state and the authorization behavior. Route-level tests catch naming and parameter regressions early.

Gotchas and Tips

  • The package is small and effectively a single-purpose macro. Historically it has been archived/low-traffic; the 4.0.1 release (a dependency-constraint fix only) is maintenance, not a signal of active feature development. Treat it as a convenience macro, not critical infrastructure. If you need long-term stability, copy the relevant macro into your own service provider or define the routes explicitly; the behavior is easy to reproduce.
  • 4.0.1 is a dependency-only patch. If composer update previously failed or resolved oddly, this release is the fix. If you are pinned to 4.0.0, upgrading is low risk — but still re-run your route tests, since a composer.lock churn can pull a different Laravel/Illuminate minor that affects routing internals.
  • Verify the exact API for your Laravel version. Laravel itself has evolved withTrashed() support on resource registrations. Avoid chaining both a native and package-provided trashed helper, or you may register duplicate routes and get name collisions.
  • Route caching is the first debugging step. After adding or changing route macros, run php artisan route:clear and php artisan route:cache in deployment. Macros registered too late in the boot cycle may not appear in the cached route table.
  • Route model binding and soft deletes are the biggest pitfall. A trashed model will 404 on implicit binding unless the binding includes trashed records. Confirm this for restore and forceDelete before writing controller logic.
  • Watch route names and parameter names. route('posts.restore', $post) depends on the resource parameter being {post}. If you customize ->parameters() or use nested resources, regenerate URLs through the helper rather than hard-coding paths.
  • Authorization is not automatic. The route existing does not mean the user may restore or permanently delete. Add restore/forceDelete policy methods and test them; otherwise any authenticated user with the URL can act.
  • Be careful with permanent deletion. Force-delete routes should usually sit behind stricter middleware or a dedicated admin guard. Consider auditing or logging these actions.
  • Debug with route:list. Use php artisan route:list --name=posts and --columns=method,uri,name,action,middleware to verify exactly what the package registered. This is more reliable than assuming from the README.
  • Extension points are limited but sufficient. If the package's defaults do not fit, extend the controller, override the resource registrar, or register your own macros in AppServiceProvider::boot(). For a package this size, a local macro is often the cleanest long-term answer.
  • Check compatibility before upgrading Laravel. Confirm that a 4.0.x constraint set (as adjusted in 4.0.1) satisfies your target Illuminate version, and run route registration plus a restore/force-delete feature test before adopting it in a new project.
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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package