PHPackages                             whilesmart/eloquent-library - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. whilesmart/eloquent-library

ActiveLibrary

whilesmart/eloquent-library
===========================

Polymorphic content library (collections, folders, assets) for Laravel applications.

046PHP

Since Jul 12Pushed 1mo agoCompare

[ Source](https://github.com/whilesmartphp/eloquent-library)[ Packagist](https://packagist.org/packages/whilesmart/eloquent-library)[ RSS](/packages/whilesmart-eloquent-library/feed)WikiDiscussions dev Synced 1w ago

READMEChangelogDependenciesVersions (1)Used By (0)

whilesmart/eloquent-library
===========================

[](#whilesmarteloquent-library)

A polymorphic content library for Laravel: a `Collection` -&gt; `Folder` -&gt; `Asset` hierarchy for anything an owner keeps and reuses (notes, images, offerings, profiles). Each record is scoped to an owner (a workspace, organization, user) through [`whilesmart/eloquent-owner-access`](https://github.com/whilesmartphp/eloquent-owner-access). Assets are thin, polymorphic envelopes: `kind` is an open string, text kinds use `body`, and binary kinds carry a URL or reference in `metadata`, so new kinds need no schema change.

Install
-------

[](#install)

```
composer require whilesmart/eloquent-library
php artisan migrate

```

Routes register automatically under the `api` prefix with `auth:sanctum`. Set `LIBRARY_REGISTER_ROUTES=false` to mount them yourself.

Owning model
------------

[](#owning-model)

Add the trait to whatever owns a library:

```
use Whilesmart\Library\Traits\HasLibrary;

class Workspace extends Model
{
    use HasLibrary;
}

$collection = $workspace->libraryCollections()->create(['name' => 'Brand assets']);

$collection->assets()->create([
    'owner_type' => $workspace->getMorphClass(),
    'owner_id' => $workspace->getKey(),
    'kind' => 'note',
    'title' => 'Tone of voice',
    'body' => 'Friendly and concise.',
]);
```

Endpoints
---------

[](#endpoints)

All routes are mounted under the configured prefix (`api` by default) and a `library` segment.

MethodPathPurposeGET`/api/library/collections`List (filter by owner, `q`)POST`/api/library/collections`CreateGET/PUT/PATCH/DELETE`/api/library/collections/{collection}`Show / update / soft deleteGET`/api/library/folders`List (filter by owner, `library_collection_id`, `parent_folder_id`)POST`/api/library/folders`CreateGET/PUT/PATCH/DELETE`/api/library/folders/{folder}`Show / update / soft deleteGET`/api/library/assets`List (filter by owner, `library_collection_id`, `library_folder_id`, `kind`, `q`)POST`/api/library/assets`CreateGET/PUT/PATCH/DELETE`/api/library/assets/{asset}`Show / update / soft deleteKinds and presenters
--------------------

[](#kinds-and-presenters)

`kind` is a plain string (`note`, `image`, `offering`, `profile`, ...). A `PresenterRegistry`resolves the presenter for a kind from `config('library.presenters')` and exposes two shapes: `present($asset)` (the flat listing entry) and `read($asset)` (the full text payload). Add a kind by adding a presenter class and registering it; the registry never branches on kind. The `DefaultAssetPresenter` matches every kind, so keep it last in the list.

```
$registry = app(Whilesmart\Library\Presenters\PresenterRegistry::class);
$registry->present($asset);
$registry->read($asset);
```

Configuration
-------------

[](#configuration)

Publish the config to override table names, swap any model for a host subclass, or change the presenter list:

```
php artisan vendor:publish --tag=library-config

```

###  Health Score

22

—

LowBetter than 21% of packages

Maintenance59

Moderate activity, may be stable

Popularity10

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity11

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/a1ca6f6e01ecbfe6640ff410c4f0321054fb48d05a5f843c2b89887b90369bcd?d=identicon)[whilesmart](/maintainers/whilesmart)

---

Top Contributors

[![nfebe](https://avatars.githubusercontent.com/u/14317775?v=4)](https://github.com/nfebe "nfebe (3 commits)")

### Embed Badge

![Health badge](/badges/whilesmart-eloquent-library/health.svg)

```
[![Health](https://phpackages.com/badges/whilesmart-eloquent-library/health.svg)](https://phpackages.com/packages/whilesmart-eloquent-library)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
