PHPackages                             esign/laravel-linkable - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. esign/laravel-linkable

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

esign/laravel-linkable
======================

Dynamically link Laravel models

1.5.0(3mo ago)016.8k↓56.1%MITPHPPHP ^8.1CI passing

Since Nov 15Pushed 3mo ago3 watchersCompare

[ Source](https://github.com/esign/laravel-linkable)[ Packagist](https://packagist.org/packages/esign/laravel-linkable)[ Docs](https://github.com/esign/laravel-linkable)[ RSS](/packages/esign-laravel-linkable/feed)WikiDiscussions master Synced 4d ago

READMEChangelog (6)Dependencies (12)Versions (8)Used By (0)

Dynamically link Laravel models
===============================

[](#dynamically-link-laravel-models)

[![Latest Version on Packagist](https://camo.githubusercontent.com/e08b742a94b540b2b9044d95f40b6f4857fa7b0599c33d1c8171afffbb37cc5f/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f657369676e2f6c61726176656c2d6c696e6b61626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/esign/laravel-linkable)[![Total Downloads](https://camo.githubusercontent.com/2b8c9c60a6523c68121c3c33d5299c63125e96cf0b61a781a09adaf2030f0a23/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f657369676e2f6c61726176656c2d6c696e6b61626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/esign/laravel-linkable)[![GitHub Actions](https://github.com/esign/laravel-linkable/actions/workflows/main.yml/badge.svg)](https://github.com/esign/laravel-linkable/actions/workflows/main.yml/badge.svg)

This package allows you to add a dynamic link to a Laravel model. This dynamic link may be a reference to another model or could also be an external URL. In essence, this package is just a Laravel relationship with some extra utility methods.

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require esign/laravel-linkable
```

Usage
-----

[](#usage)

### Preparing your model

[](#preparing-your-model)

To make a model have a dynamic link you may add the `HasDynamicLink` trait.

```
use Esign\Linkable\Concerns\HasDynamicLink;
use Illuminate\Database\Eloquent\Model;

class MenuItem extends Model
{
    use HasDynamicLink;
}
```

Your database structure should look like the following:

```
Schema::create('menu_items', function (Blueprint $table) {
    $table->id();
    $table->string('dynamic_link_type')->nullable();
    $table->string('dynamic_link_url')->nullable();
    $table->string('dynamic_link_linkable_model')->nullable();
});
```

#### Internal links

[](#internal-links)

In case you set the `dynamic_link_type` as `internal` the `dynamic_link_linkable_model` field will be used. In order to know where a internal dynamic link should direct to you may implement `LinkableUrlContract` on the related model:

```
use Esign\Linkable\Contracts\LinkableUrlContract;

class Post extends Model implements LinkableUrlContract
{
    public function linkableUrl(): ?string
    {
        return "http://localhost/posts/{$this->id}";
    }
}
```

#### External links

[](#external-links)

In case you set the `dynamic_link_type` as `external` the `dynamic_link_url` field will be used. The value of this field should be a valid URL, e.g. `https://www.example.com`.

### Storing linkables

[](#storing-linkables)

Instead of using a regular `MorphTo` relation, this package ships with a `SingleColumnMorphTo` relation. Some CMS, including our own, do not allow for morphable relations based on two columns, e.g. `dynamic_link_linkable_type` and `dynamic_link_linkable_id`. The `SingleColumnMorphTo` combines both the type and id fields into a single column, e.g. `dynamic_link_linkable_model`. The value for this single column is stored in the `{model}:{id}` format, e.g. `post:1`. You're able to use both a fully qualified class name or a value from your application's [morph map](https://laravel.com/docs/9.x/eloquent-relationships#custom-polymorphic-types), just like a regular morphTo relation.

> **Note**This approach is not ideal and more complex queries using this relationship may not work as expected. In case you're able to you may overwrite the `dynamicLinkLinkable` relation to use Laravel's default `MorphTo` relationship.

### Linkables overview

[](#linkables-overview)

To create an overview of all possible linkables you can create a [MySQL view](https://dev.mysql.com/doc/refman/5.7/en/create-view.html) that creates a [union](https://dev.mysql.com/doc/refman/5.7/en/union.html) of all possible models that can be linked to:

```
DB::statement('
    CREATE OR REPLACE VIEW linkables AS
    SELECT
        CONCAT("post:", id) AS id,
        "post" AS linkable_type,
        id AS linkable_id,
        CONCAT("Post - ", title) AS label
    FROM posts
    UNION
    SELECT
        CONCAT("comment:", id) AS id,
        "comment" AS linkable_type,
        id AS linkable_id,
        CONCAT("Comment - ", title) AS label
    FROM comments
');
```

This would create the following output:

idlinkable\_typelinkable\_idlabelpost:1post1My First Postcomment:1comment1My First Comment### Rendering dynamic links

[](#rendering-dynamic-links)

This package ships with a view component that will help you render both internal and external links:

```
use Esign\Linkable\Concerns\HasDynamicLink;
use App\Models\Post;
use App\Models\MenuItem;

$post = Post::create();
$menuItemInternal = MenuItem::create([
    'dynamic_link_type' => HasDynamicLink::$linkTypeInternal,
    'dynamic_link_url' => null,
    'dynamic_link_linkable_model' => "post:{$post->id}",
]);

$menuItemExternal = MenuItem::create([
    'dynamic_link_type' => HasDynamicLink::$linkTypeExternal,
    'dynamic_link_url' => 'https://www.esign.eu',
    'dynamic_link_linkable_model' => null,
]);
```

The view component will render an `` tag, when a model of the type `external` is given, the `target="_blank"` and `rel="noopener"` attributes will be applied.

```
Esign
Esign
```

```
Esign
Esign
```

### Extending this package

[](#extending-this-package)

#### Creating your own dynamic link types

[](#creating-your-own-dynamic-link-types)

This Laravel package offers built-in support for [internal](#internal-links) and [external](#external-links) links by default. However, in certain scenarios, you might want to introduce custom link types, such as referencing an anchor tag. To achieve this, you can extend the package's functionality.

1. Extend the `HasDynamicLink` Trait

```
namespace App\Models\Concerns;

use Esign\Linkable\Concerns\HasDynamicLink as BaseHasDynamicLink;

trait HasDynamicLink
{
    use BaseHasDynamicLink {
        dynamicLink as baseDynamicLink;
    }

    public static string $linkTypeAnchor = 'anchor';

    public function dynamicLink(): ?string
    {
        return match ($this->dynamicLinkType()) {
            static::$linkTypeAnchor => $this->dynamicLinkUrl(),
            default => $this->baseDynamicLink(),
        };
    }
}
```

2. Create Your Own View Component

Next, you need to create your own view component that extends the `DynamicLink` component provided by the package. Here's how you can do that:

```
namespace App\View\Components;

use App\Models\Concerns\HasDynamicLink;
use Esign\Linkable\View\Components\DynamicLink as BaseDynamicLink;

class DynamicLink extends BaseDynamicLink
{
    public function render(): ?View
    {
        return match ($this->model->dynamicLinkType()) {
            HasDynamicLink::$linkTypeAnchor => view('linkable.dynamic-link-anchor'),
            default => parent::render(),
        };
    }
}
```

```
merge(['href' => $model->dynamicLink()]) }}>{{ $slot }}
```

3. Use Your Custom View Component

With your custom view component in place, you can now use it in your Blade templates instead of the one provided by the package:

```

    My anchor tag

```

### Testing

[](#testing)

```
composer test
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance79

Regular maintenance activity

Popularity26

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 94% 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.

###  Release Activity

Cadence

Every ~243 days

Recently: every ~278 days

Total

6

Last Release

110d ago

PHP version history (2 changes)1.0.0PHP ^8.0

1.3.0PHP ^8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/4599d7a8f6fdb63dd04305a49ae5ec9700b7a6eacdbe3a54f89584d75e34503f?d=identicon)[esign](/maintainers/esign)

---

Top Contributors

[![jordyvanderhaegen](https://avatars.githubusercontent.com/u/24370626?v=4)](https://github.com/jordyvanderhaegen "jordyvanderhaegen (47 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (3 commits)")

---

Tags

esignlinkable

###  Code Quality

TestsPHPUnit

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/esign-laravel-linkable/health.svg)

```
[![Health](https://phpackages.com/badges/esign-laravel-linkable/health.svg)](https://phpackages.com/packages/esign-laravel-linkable)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[pressbooks/pressbooks

Pressbooks is an open source book publishing tool built on a WordPress multisite platform. Pressbooks outputs books in multiple formats, including PDF, EPUB, web, and a variety of XML flavours, using a theming/templating system, driven by CSS.

45444.2k1](/packages/pressbooks-pressbooks)[flarum/core

Delightfully simple forum software.

201.4M2.3k](/packages/flarum-core)[api-platform/laravel

API Platform support for Laravel

58171.8k14](/packages/api-platform-laravel)[wearepixel/laravel-cart

A cart implementation for Laravel

1374.8k](/packages/wearepixel-laravel-cart)

PHPackages © 2026

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