PHPackages                             kupidonkhv/voyager-extension - 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. [Admin Panels](/categories/admin)
4. /
5. kupidonkhv/voyager-extension

ActiveLibrary[Admin Panels](/categories/admin)

kupidonkhv/voyager-extension
============================

Voyager Admin Panel Extension with Laravel 12 compatibility

v1.0.3(7mo ago)115MITPHP

Since Sep 13Pushed 7mo agoCompare

[ Source](https://github.com/kupidonkhv/voyager-extension)[ Packagist](https://packagist.org/packages/kupidonkhv/voyager-extension)[ Docs](https://github.com/kupidonkhv/voyager-extension)[ RSS](/packages/kupidonkhv-voyager-extension/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (5)Versions (4)Used By (0)

Voyager Extension
=================

[](#voyager-extension)

The package extends the original [Voyager Admin Panel](https://github.com/the-control-group/voyager) with some new advantages and features.

Features
--------

[](#features)

- Integration of v10 [laravel-medialibrary](https://docs.spatie.be/laravel-medialibrary/) by Spatie
- Basic action buttons in add-edit mode (Save) can be Sticky and Autohide now.
- Custom Browse columns order. Can be defined in two ways.
- Tabs Layout for an add-edit bread mode.
- Tree view mode for models have parent\_id field.
- New extended Browse Bread appearance and options.
- New extended BREAD Builder appearance and options.
- New basic actions for add-edit mode: Save and continue &amp; Save and create.

New custom fields:

- VE Image. Title and Alt field are supported.
- VE Media Files (including images), supports Sorting and unlimited attached custom fields with different types.
- VE Select Dropdown Tree. Dropdown selection for Tree type structures (with parent\_id).
- VE Fields Group. JSON kind group of fields inside the one model field.
- VE Sortable JSON Multi Fields. JSON kind group of multi-fields (multi-rows) stored in the model field.
- VE Related Models. Set of a related models list.
- VE Inline Fields Set. The complex combined field. Each field can store multiple rows (or only one) each of them may hold multiple type custom fields.
- VE Page Layout. Allows organizing layout of blocks, forms, widgets and content on a Page. Depends on Voyager Site package.

Package installation
--------------------

[](#package-installation)

> #### Requirement
>
> [](#requirement)
>
> Laravel: v8+, v9+, v10+, v11+, v12+
> Voyager: v1.6+ (recommended: kupidonkhv/voyager-fork for Laravel 12 compatibility)
> You should fully install the package [Voyager](https://github.com/the-control-group/voyager) or [Voyager Fork](https://github.com/kupidonkhv/voyager-fork) before.

Via Composer

```
$ composer require kupidonkhv/voyager-extension
```

Then run migrations:

```
$ php artisan migrate
```

Publish config if you need:

```
$ php artisan vendor:publish --provider="MonstreX\VoyagerExtension\VoyagerExtensionServiceProvider" --tag="config"

```

To use Image fields you need publish and migrate [laravel-medialibrary](https://docs.spatie.be/laravel-medialibrary/) resources

```
$ php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
$ php artisan migrate
```

Optional you may like to publish the config [laravel-medialibrary](https://docs.spatie.be/laravel-medialibrary/) as well

```
$ php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="config"
```

Configure
---------

[](#configure)

#### Config file

[](#config-file)

```
/*
|
| Use original browse.blade.php or use extended one
|
*/
'legacy_browse_bread' => false,

/*
| Use original edit-add.blade.php or use extended one
*/
'legacy_edit_add_bread' => false,

/*
| Use original tools/bread/edit-add.blade.php or use extended one
*/
'legacy_bread_list' => false,

/*
| Use sticky action panel (if 'enabled' = true) instead the original action buttons.
| If 'autohide' = true will show and hide automatically on mouse over/leave events.
| Uses in edit-add.blade.php and tools/bread/edit-add.blade.php
*/
'sticky_action_panel' => [
    'enabled' => true,
    'autohide' => false,
],

/*
| CLone Record parameters
| @params: enabled - if action is available
|          reset_types - A value of these bread type fields will be cleared
|          suffix_fields - The suffix '(clone)' will be added to these fields content
*/
'clone_record' => [
    'enabled' => true,
    'reset_types' => ['image', 'multiple_images','file'],
    'suffix_fields' => ['title','name','slug'],
],

/*
| You can enable or disable the custom path and urls generator for medialibrary images
| at MonstreX\VoyagerExtension\Generators\MediaLibraryPathGenerator
| and at MonstreX\VoyagerExtension\Generators\MediaLibraryUrlGenerator
*/
'use_media_path_generator' => true,
'use_media_url_generator' => true,

/*
|
| Use Str::slug function on media file names before saving
|
*/
'slug_filenames' => true,
```

> #### Using coordinates field
>
> [](#using-coordinates-field)

Some of legacy voyager fields like 'coordinates' don't work properly in the mode 'legacy\_edit\_add\_bread' =&gt; false
To make it work as supposed to be you need copy the legacy template file into your own template folder: /resources/views/vendor/voyager/formfields/coordinates.blade.php
Then you should replace string:

```
var gMapVm = new Vue({ el: '#coordinates-formfield' });
```

with:

```
if (typeof gMapVm === 'undefined') {
    var gMapVm = new Vue({ el: '#coordinates-formfield' });
}
```

#### Models

[](#models)

To use additional images fields you should to configure your models like this:

```
namespace App;

use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Article extends Model implements HasMedia
{
   use InteractsWithMedia;
}
```

Also you can use any other advantages provided by [laravel-medialibrary](https://docs.spatie.be/laravel-medialibrary/) package.

Description and usage
---------------------

[](#description-and-usage)

Design of the BREAD Builder was changed to make it more compact and handy (can be disabled by config):

[![BREAD Builder](/docs/images/bread-layout.png)](/docs/images/bread-layout.png)

All JSON fields are collapsable now and collapsed by default. To expand json editors - just click on it.

Common extra details in BREAD Builder page:

[![BREAD Extra Options](/docs/images/bread-extra.png)](/docs/images/bread-extra.png)

New basic action buttons on the sticky panel for add-edit modes (can be disabled by config):

[![Sticky Action Panel](/docs/images/sticky-panel.png)](/docs/images/sticky-panel.png)

The package also provide some new type fields.

> ### Field: VE Image
>
> [](#field-ve-image)

The field utilize **laravel-medialibrary** package to store single image. In addition this field can hold text attributes TITLE and ALT.

[![VE Image](/docs/images/adv-image.png)](/docs/images/adv-image.png)

> ### Field: VE Media Files
>
> [](#field-ve-media-files)

This field represents **laravel-medialibrary** collection with subsets of additional custom fields. Uses to store any media files. The collection can be sorted as you need using drag and drop. Select and group removing is implemented.

By default it keeps two fields - **Title** and **Alt**. Changing a file inside a collection element is allowed. You can use the field like a collection of widgets or just like a sortable image collection. Elements of media collection can hold additional content fields using **BREAD Json Options**.

> Implemented fields types:

```
{
    "extra_fields": {
        "content": {
            "type": "textarea",
            "title": "Description"
        },
        "code": {
            "type": "codemirror",
            "title": "HTML Widget"
        },
        "link": {
            "type": "text",
            "title": "URL"
        }
    }
}
```

> Accepted files types template:

```
{
  "input_accept": "image/*,.pdf,.zip,.js,.html,.doc,.xsxl"
}
```

By default uses "image/\*" template.

[![VE Media Files](/docs/images/adv-media-files.png)](/docs/images/adv-media-files.png)

> Retrieving field data on frontend side.

You can use any method provided by laravel-medialibrary package. The field name of is represented media gallery name.

```
$image = $post->getFirstMedia('field_name');
$imageUrl = $image->getFullUrl();
$imageTitle = $image->getCustomProperty('title');
$imageAlt = $image->getCustomProperty('alt');
```

More details see in the original [laravel-medialibrary documentation](https://docs.spatie.be/laravel-medialibrary/v7/basic-usage/retrieving-media/).

> ### Field: VE Fields Group
>
> [](#field-ve-fields-group)

Is a simple JSON like fieldset. Support three field subtypes inside: text, number and textarea. Useful when you need implement the same group fields in different models. [![Fields Group](/docs/images/fields-group.png)](/docs/images/fields-group.png)

BREAD Json Options:

```
{
    "fields": {
        "seo_title": {
            "label": "SEO Title",
            "type": "text"
        },
        "meta_description": {
            "label": "META Description",
            "type": "text"
        },
        "meta_keywords": {
            "label": "META Keywords",
            "type": "text"
        }
    }
}
```

Retrieving data:

```
@if($seo = json_decode($Post->seo->fields))
  {{ $seo->seo_title->value }}
@endif
```

> ### Field: VE JSON Fields
>
> [](#field-ve-json-fields)

Sortable multi-rows and multi-fields JSON storage.
[![Fields Group](/docs/images/fields-json-multi.png)](/docs/images/fields-json-multi.png)

BREAD Json multi-field configuration:

```
{
    "json_fields": {
        "group": "Param Group",
        "name": "Param Name",
        "value": "Param Value"
    }
}
```

Stored data structure (2 rows):

```
{
  "fields": {
    "group": "Field Group",
    "name": "Field Name",
    "value": "Field value"
  },
  "rows": [
      {
        "group":"Main",
        "name":"Services",
        "value":"12"
      },
      {
        "group":"Second",
        "name":"Packages",
        "value": "100"
      }
  ]
}
```

> ### Field: VE Select Dropdown Tree
>
> [](#field-ve-select-dropdown-tree)

Represents tree-like dropdown control related to the certain model. BREAD Json Options (Post model, category\_id field):

```
{
    "browse_filter": true,
    "relationship": {
        "model": "\\App\\Models\\Category",
        "key": "id",
        "label": "title",
        "field": "category",
        "ref_field": "category_id",
        "filter_label": "Product category"
    }
}
```

Where:
**browse\_filter** - if you use filter for this field in the browse mode
**model** - Source model class
**key** - Key field to reference
**label** - Display name field
**ref\_field** - The current model field referenced to the relative model
**filter\_label** - Display label for the filter mentioned above (if present).

In a Post model add:

```
public function category()
{
    return $this->belongsTo(Category::class);
}
```

> ### Field: VE Related Models
>
> [](#field-ve-related-models)

Represents of a sortable model records list. Uses autocomplete field to add new specified entries.
The model describes in details Bread field.

[![Fields Group](/docs/images/adv-related.png)](/docs/images/adv-related.png)

```
{
    "related_model": {
        "source": "pages",
        "search_field": "title",
        "display_field": "title",
        "fields": [
            "title",
            "slug",
            "price"
        ]
    }
}
```

Where:
**source:** a slug of the model
**search\_field:** a field for search
**display\_field:** a field to display as label/title,
**fields:** set of fields to store.

Predefined fields are: id and field mentioned in the display\_field option.

Stored JSON format:

```
[
    {
        "display_field":"title",
        "fields": {
            "id":1,
            "title":"Proin volutpat, eros sed semper hendrerit",
            "slug":"proin-volutpat-eros-sed-semper-hendrerit",
            "price": 500
        }
    },
    ...
]
```

> ### Field: VE Inline Fields Set
>
> [](#field-ve-inline-fields-set)

The complex combined field. Represent groups of built in internal custom fields. 10 Internal field types supported. Fields data can be stored as in your current model field and also as a specified table data.

[![Inline Fields Set](/docs/images/adv-inline-set.png)](/docs/images/adv-inline-set.png)

Row details data for the field:

```
{
    "inline_set": {
        "source": "App\\Models\\Meta",
        "many": true,
        "columns": 2,
        "fields": {
            "date": {
                "label": "Date",
                "type": "date"
            },
            "select": {
                "label": "Select",
                "type": "select",
                "options": {
                    "val1": "Option One",
                    "val2": "Option Two",
                    "val3": "Option Three"
                },
                "default": "val3"
            },
            "number": {
                "label": "Number",
                "type": "number",
                "attrs": {
                    "required": true
                }
            },
            "checkbox": {
                "label": "Checkbox",
                "type": "checkbox",
                "on": "Enabled",
                "off": "Disabled",
                "default": "on"
            },
            "radio": {
                "label": "Radio",
                "type": "radio",
                "options": {
                    "center": "Center",
                    "left": "Left",
                    "right": "Right"
                },
                "default": "left"
            },
            "image": {
                "label": "Image",
                "type": "media",
                "remove_delay": 5000
            },
            "rich_text": {
                "label": "Rich Text Box",
                "type": "richtext",
                "min_height": 150
            },
            "code": {
                "label": "Ace Editor",
                "type": "code",
                "mode": "html",
                "theme": "monokai",
                "minlines": 3,
                "maxlines": 20
            },
            "seo_title": {
                "label": "Title",
                "type": "text",
                "class": "col-md-12",
                "attrs": {
                    "required": true
                }
            },
            "meta_description": {
                "label": "Description",
                "type": "textarea",
                "class": "col-md-6"
            },
            "meta_keywords": {
                "label": "Keywords",
                "type": "textarea",
                "class": "col-md-6"
            }
        }
    }
}
```

Where:
*many:* Many rows allowed if true. *columns:* Number of columns for fields set separation (many sets in one row). The values are: 1 - 6.
*source:* Model name (class) for the data storage. If not present used local model field.
Storage model should have next fields:
*row\_id* - keeps local inline fields set row id. *model* - master model name.
*model\_id* - master model id.
*model\_field* - master model related field.
*order* - a sorting field, keeps row order.

Also, all custom inline fields you need with specific types.

Allowed fields:
*number* - db storage type: number
*text* - db storage type: varchar
*textarea* - db storage type: text
*richtext* - db storage type: text, supported option: min\_height
*code* - db storage type: text, supported options: *mode*, *theme*, *minlines* and *maxlines*
*media* - db storage type: text (handles for media-library), can hold multiple media files with sorting. Supported options: *remove\_delay* - pause in ms before media file will be removed (after clicking remove button).
*date* - db storage type: date
*checkbox* - db storage type: tinyint, supported options: see the example above
*radio* - db storage type: text, supported options: see the example above
*select* - db storage type: text, supported options: see the example above

Each field also can have additional common options:
*class* - a wrapper class, to organize the layout inside the set. *attrs* - a list of any you need html attributes for the field.

> Retrieving stored data from the field:

Prepare your model and add *InlineSetTrait* trait:

```
...
use MonstreX\VoyagerExtension\Traits\InlineSetTrait;
...
class Page extends Model
{
    use InlineSetTrait;
    ...
}
```

Then just use trait method:

```
$data = $post->getInlineSet('news_sections');
```

Where *news\_sections* is the field name keeps inline fields set.

Also, the trait is necessary to remove related sources data in corresponding table during model delete.

> ### Field: VE Page Layout
>
> [](#field-ve-page-layout)

The special content field type. Available only if [Voyager Site](https://github.com/MonstreX/voyager-site) package is installed. Provides a subsystem to organize the layout of content fields, blocks, and forms on a page.

[![VE Page Layout](/docs/images/page-layout.png)](/docs/images/page-layout.png)

BREAD Json Option for this field:

```
{
    "layout_fields": {
        "content": "Content"
    },
    "block_model": "MonstreX\\VoyagerSite\\Models\\Block",
    "form_model": "MonstreX\\VoyagerSite\\Models\\Form",
    "style_classes": "col-md-3"
}
```

**layout\_fields** - list of model (bread) fields available for a selection.

**block\_model** - block model class used for retrieve block content records. If param is not present, the block model select input will not be displayed on the edit/add views.

**form\_model** - form model class used for retrieve form content records. If param is not present, the form model select input will not be displayed on the edit/add views;

**style\_classes** - additional style classes to be applied to the select input fields on the edit/add views. Default value: `col-md-4`.

Rendering the field:

```
{!! render_layout($page->layout_field, $page) !!}
```

> ### New BREAD Browse modes and options
>
> [](#new-bread-browse-modes-and-options)

### Dropdown browse filters

[](#dropdown-browse-filters)

Needed for filtering data in a browse mode. Uses on relationship "belongs to" field type only.

```
{
    "browse_filter": true
}
```

[![Browse filter](/docs/images/browse-filter.png)](/docs/images/browse-filter.png)

### Tree mode

[](#tree-mode)

New TREE browse mode implemented. If you have the field **parent\_id** you can add option **browse\_tree** for it and then TREE browse mode will enabled :

```
{
    "browse_tree": true
}
```

The tree mode looks similar to the menu tree view.

[![Tree mode](/docs/images/tree-view.png)](/docs/images/tree-view.png)

You can use option **browse\_tree\_push\_right** to push browsed fields to the right part of the view line.

```
{
    "browse_tree_push_right": true
}
```

All browsed fields after this field will push right.

### Alternate browse title

[](#alternate-browse-title)

Just replaces default bread field title with a provided option title:

```
{
    "browse_title": "Short title"
}
```

### Inline checkbox switcher

[](#inline-checkbox-switcher)

Using **browse\_inline\_editor** you can enable an inline switcher in a browse view mode. After that you can change the field value directly (by clicking on it) from a browse mode without entering an edit mode.

[![Inline checkbox switcher](/docs/images/inline-checkbox.png)](/docs/images/inline-checkbox.png)

```
{
    "browse_inline_editor": true,
    "on": "Active",
    "off": "Disabled",
    "checked": true
}
```

### Inline text, number editors

[](#inline-text-number-editors)

Using **browse\_inline\_editor** you can also enable an inline editors in a browse view mode for text and number types. After that you can change the field value directly from a browse mode without entering to edit mode.

```
{
    "browse_inline_editor": true
}
```

### Action on a field click

[](#action-on-a-field-click)

If you add this option *url* you will be able to call appropriate action for the record using just a click on it. For an instance let it be field **Title**

```
{
    "url": "edit"
}
```

### Column width, align and font size

[](#column-width-align-and-font-size)

Sets width, align and font-size for the column in browse mode:

```
{
    "browse_width": "15px",
    "browse_align": "right",
    "browse_font_size": "0.8em"
}
```

### Column order

[](#column-order)

Set browse order you need in the Extra Options of BREAD Builder.

```
{
    "browse_order": [
        "status",
        "id",
        "title",
        "block_belongsto_block_region_relationship",
        "urls",
        "created_at"
    ]
}
```

> Notice: a voyager relation field should use their own naming convention like **block\_belongsto\_block\_region\_relationship**.

Also you can change the column order in a browse mode using this option:

```
{
    "browse_order": 1
}
```

### Image max height in a row

[](#image-max-height-in-a-row)

Sets maximal height of thumbnail images:

```
{
    "browse_image_max_height": "30px"
}
```

### Section separator

[](#section-separator)

This option makes a visual section separator line.

```
{
    "section": "Media files"
}
```

### Tabs layout for add-edit mode

[](#tabs-layout-for-add-edit-mode)

In add-edit BREAD mode you can use Tabbed layout. Just put the option **tab\_title** where you want to start a new TAB.

[![Inline checkbox switcher](/docs/images/tabs.png)](/docs/images/tabs.png)

```
{
    "tab_title": "Media"
}
```

You don't need to make the first TAB, it'll be created automatically.

Localizations
-------------

[](#localizations)

New types of fields don't provide localization service used in Voyager. However, you can use built-in localization helper and retrieve translated substring from a field content:

```
$field_data = '{{en}}English title {{ru}}Russian title';
// or
$field_data = '[[en]]English title [[ru]]Russian title';
...
$field_title_en = str_trans($field_data);
$field_title_ru = str_trans($field_data,'ru');
```

Security
--------

[](#security)

If you discover any security related issues, please email author email instead of using the issue tracker.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance62

Regular maintenance activity

Popularity8

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 84.7% 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 ~2 days

Total

3

Last Release

237d ago

### Community

Maintainers

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

---

Top Contributors

[![MonstreX](https://avatars.githubusercontent.com/u/1912698?v=4)](https://github.com/MonstreX "MonstreX (282 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (40 commits)")[![eddielee394](https://avatars.githubusercontent.com/u/7989605?v=4)](https://github.com/eddielee394 "eddielee394 (3 commits)")[![yellow-three](https://avatars.githubusercontent.com/u/39539862?v=4)](https://github.com/yellow-three "yellow-three (2 commits)")[![krausenspb](https://avatars.githubusercontent.com/u/17198710?v=4)](https://github.com/krausenspb "krausenspb (2 commits)")[![Hebrahimzadeh](https://avatars.githubusercontent.com/u/38420287?v=4)](https://github.com/Hebrahimzadeh "Hebrahimzadeh (1 commits)")[![n1kk0](https://avatars.githubusercontent.com/u/174255?v=4)](https://github.com/n1kk0 "n1kk0 (1 commits)")[![sanater](https://avatars.githubusercontent.com/u/5594035?v=4)](https://github.com/sanater "sanater (1 commits)")[![EmilioBravo](https://avatars.githubusercontent.com/u/544288?v=4)](https://github.com/EmilioBravo "EmilioBravo (1 commits)")

---

Tags

laravellaravel 12adminvoyager

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/kupidonkhv-voyager-extension/health.svg)

```
[![Health](https://phpackages.com/badges/kupidonkhv-voyager-extension/health.svg)](https://phpackages.com/packages/kupidonkhv-voyager-extension)
```

###  Alternatives

[slowlyo/owl-admin

基于 laravel、amis 开发的后台框架~

61214.2k26](/packages/slowlyo-owl-admin)[sebastienheyd/boilerplate

Laravel Boilerplate based on AdminLTE 3 with blade components, user management, roles, permissions, logs viewer, ...

28618.2k3](/packages/sebastienheyd-boilerplate)[lokielse/laravel-admin-generator

An Admin Panel Generator for Laravel 5

712.0k](/packages/lokielse-laravel-admin-generator)[joy/voyager-datatable

joy voyager datatable

1538.1k43](/packages/joy-voyager-datatable)[serverfireteam/blog

A nice blog system with laravel and laravelpanel

523.1k](/packages/serverfireteam-blog)

PHPackages © 2026

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