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

Listify Laravel Package

lookitsatravis/listify

Listify is a Laravel package for adding list functionality to your application. It provides an Eloquent-friendly way to create and manage lists and their items, making it easy to build features like favorites, collections, or simple to-do lists.

View on GitHub
Deep Wiki
Context7

Getting Started

Listify is an Eloquent trait, not a rendering library. Despite the "Blade-friendly" framing in its description, the actual value is in the data layer: given a self-referencing table with a parent_column, an order_column, and a label_column, it produces list-shaped arrays (flat id => label, or nested parent/child) you can hand to a <select>, a recursive partial, or an API resource. If you came here expecting a list renderer with Blade components and wrappers, you will be disappointed — and that mismatch is worth knowing before you spend a day integrating.

The package shows zero stars and zero dependents. Read that as "unmaintained reference code," not "supported dependency." Your first task is a compatibility check, not a feature build:

composer require lookitsatravis/listify
composer show lookitsatravis/listify   # inspect illuminate/* and php constraints

If the constraints don't resolve against your Laravel version, stop and reassess — see Gotchas below, because forking is the likely outcome. If it installs, register the provider manually (this package predates Laravel 5.5 auto-discovery):

// config/app.php
'providers' => [
    Lookitsatravis\Listify\ListifyServiceProvider::class,
],

Then add the trait to the model that represents your tree and configure the column names via the $listify property:

use Lookitsatravis\Listify\ListifyTrait;

class Category extends Model
{
    use ListifyTrait;

    protected $fillable = ['name', 'parent_id', 'position'];

    protected $listify = [
        'parent_column' => 'parent_id',
        'order_column'  => 'position',
        'label_column'  => 'name',
    ];

    public function children()
    {
        return $this->hasMany(self::class, 'parent_id')->orderBy('position');
    }
}

Your first use case should be the smallest possible: an admin form dropdown. Seed three categories with one child, then dd() the output before wiring any view — the shape of the returned array is the contract you're building against, and you want it in front of you:

$options = Category::getNestedList();
dd($options);

Then render:

<select name="category_id">
    @foreach ($options as $id => $label)
        <option value="{{ $id }}">{{ $label }}</option>
    @endforeach
</select>

Where to look first: the README example, then the trait source in vendor/lookitsatravis/listify/src/. The trait is short and is the authoritative API — there is no hosted documentation, no issue tracker activity you can trust, and no changelog that reflects your Laravel version.

Implementation Patterns

Flat select lists. The most common day-to-day use is populating a <select> for a related model. Call the list method, pass the result to the view, iterate. Don't transform the array in the controller — if you need custom labels, do it in the config (label_column) or extend the model with an accessor, because the package builds labels from the configured column.

Nested trees for recursive Blade partials. For multi-level categories you want parent_id => [children] shape, not a flat list. The package exposes a nested variant; use a single recursive partial rather than trying to flatten-and-indent in the view. If the package's nested output is a nested array, a recursive partial that checks is_array($value) is five lines and will outlive the package.

Explicit children relations. Always pair the trait with a children() relation ordered by order_column. This is what keeps the tree consistent when you read via Eloquent directly (eager loading, with('children')) rather than through the package's helpers. If ordering is defined only inside the package helpers, you'll get unsorted results the moment a developer writes $category->children without the trait method.

Ordering maintenance in admin forms. Day-to-day list management — adding a child, moving it up/down, reordering siblings — should be its own controller method and its own form request. Do the read-modify-write inside a DB::transaction. The package may or may not do this for you; assume it doesn't, and wrap it.

Eager loading. Nested list rendering is a classic N+1 trap. Before you optimize, DB::listen() or enable Model::preventLazyLoading() in local. If the package builds the list by walking relations, you'll want with at the query level. A tree of 200 categories should be one or a handful of queries, not 200.

API resources. The list output is fine for <select>s but poor for API payloads — clients need a stable nested shape with id, label, children, not associative arrays keyed by id. Use the package for the admin form, and an API Resource with $this->children()->orderBy('position') recursion for public endpoints. Don't try to make one output serve both.

Caching. Trees are expensive to build and cheap to cache. Wrap the list method in Cache::remember() keyed by the parent id (or 'categories.tree' for a global list), and bust on create/update/delete/move. This is the single-highest-value integration point: reordering is rare, reading is constant.

Seeding. When backfilling or seeding, write parent_id and position explicitly — don't lean on the package to assign order. Seeding through the trait is slower and couples your DatabaseSeeder to an unmaintained API. Set integers in the migration/seed directly; the ordering logic is downstream.

Gotchas and Tips

The package's framing overstates what it does. The description says "rendering," "Blade-friendly," "customizable item templates and wrappers," and "works with arrays, collections, and Eloquent data" — the actual code is an Eloquent trait with a nested-set/ordered-list concern. If your requirements genuinely include "render arrays into custom markup," Listify is not that package. Verify against the trait source before promising anyone a feature.

Version constraints are the real risk. Modern Laravel renames (lists() → pluck(), container binding changes, return-type declarations) will break older packages at call sites you can't easily patch in vendor/. Test on a throwaway branch first. If the install requires --ignore-platform-reqs, you have your answer: fork it, don't require it.

Column-name configuration is easy to get wrong. parent_column, order_column, label_column must match your schema exactly — including any prefix or non-standard naming. A mismatch often silently returns empty lists or malformed trees rather than throwing. When a list comes back empty, the first thing to check is these three keys.

Zero-adoption risk is operational, not just technical. Dependency scanners will flag it as unmaintained. Your team will ask why it's there. Either document the decision and the fork provenance in the README, or in-house the ~150 lines. The middle path — adopting it silently — is the worst option.

Concurrency is not solved for you. Two admins reordering the same list, or a bulk import that writes positions directly, can produce duplicate or gapped positions. There's no uniqueness constraint on (parent_id, position) unless you add one. If shared reordering matters, add the constraint and a transactional reindex in your own layer; if it doesn't (single-admin CMS), note the assumption in the code.

Scoping is a product decision you must make early. Global order (one position column) and per-parent order (parent_id, position) are different schemas. Listify assumes one parent_column; if your product needs per-user orderings of shared rows, this package's model won't fit — migrate before, not after, you've shipped.

$fillable and mass-assignment. The trait writes order_column and parent_column, so those must be fillable or written through the trait's own setters. If reordering "does nothing," check $fillable — this is the classic silent failure.

Children relation and cascade deletes. If your tree allows deleting a parent, children() has to cascade (onDelete('cascade') in the migration) or you'll orphan rows that still hold a parent_id pointing at nothing. Listify won't clean up for you.

Debugging approach. Dump the list before rendering — associative array keyed by id, or nested. If the shape is right and the view is wrong, the bug is in your partial. If the shape is wrong, it's config ($listify columns) or fillability. If it throws, it's a method-signature mismatch with your Laravel version. Those are the three buckets; check them in that order.

Extension point: copy the trait. The cheapest supported option is to cp vendor/.../ListifyTrait.php app/Support/OrderedTree.php, rename the namespace, add the uniqueness constraint and transactional reordering the package lacks, and drop the dependency. You keep the semantics, remove the dependency noise, and take ownership of the ~150 lines you'll touch anyway. For any production use of this package, this is the recommended plan.

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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console