PHPackages                             marshmallow/nova-flexible - 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. marshmallow/nova-flexible

ActiveLibrary[Admin Panels](/categories/admin)

marshmallow/nova-flexible
=========================

Flexible Content &amp; Repeater Fields for Laravel Nova base on the flexible package from WhiteCube.

v5.5.1(1mo ago)419.8k↑131.3%1[2 PRs](https://github.com/marshmallow-packages/nova-flexible/pulls)5MITPHPPHP ^8.2CI failing

Since Mar 5Pushed 1mo ago1 watchersCompare

[ Source](https://github.com/marshmallow-packages/nova-flexible)[ Packagist](https://packagist.org/packages/marshmallow/nova-flexible)[ RSS](/packages/marshmallow-nova-flexible/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (10)Versions (130)Used By (5)

[![alt text](https://camo.githubusercontent.com/f5450f299f5713ce2f04dd5a1ba7ce9960ed4568b3574e4c4ee3cddc75477253/68747470733a2f2f6d617273686d616c6c6f772e6465762f63646e2f6d656469612f6c6f676f2d7265642d3233377834362e706e67 "marshmallow.")](https://camo.githubusercontent.com/f5450f299f5713ce2f04dd5a1ba7ce9960ed4568b3574e4c4ee3cddc75477253/68747470733a2f2f6d617273686d616c6c6f772e6465762f63646e2f6d656469612f6c6f676f2d7265642d3233377834362e706e67)

Marshmallow Nova Flexible
=========================

[](#marshmallow-nova-flexible)

Important

This package was originally forked from whitecube/nova-flexible-content. Since we were making many opinionated changes, we decided to continue development in our own version rather than submitting pull requests that might not benefit all users of the original package. You’re welcome to use this package—we’re actively maintaining it. If you encounter any issues, please don’t hesitate to reach out.

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

[](#installation)

```
composer require marshmallow/nova-flexible
php artisan vendor:publish --provider="Marshmallow\Nova\Flexible\FieldServiceProvider"
```

To use the MarshmallowMediaLayout, this packages requires 'spatie/laravel-medialibrary', see the insturctions for installation on the [spatie website](https://spatie.be/docs/laravel-medialibrary/v10/installation-setup)For Nova use 'marshmallow/advanced-nova-media-library' and follow the instructions on the [github page](https://github.com/marshmallow-packages/advanced-nova-media-library)

Table of Contents
-----------------

[](#table-of-contents)

- [Prepare](#Prepare)
    - [Nova Resource](#Prepare)
    - [Models](#Models)
- [Commands](#Commands)
- [Customize](#Customize)
    - [Title on Layout classes](#Customize)
    - [Title on custom layouts](#Customize)
    - ['Config methods'](#ConfigMethods)
- [Helpers](#Helpers)

Commands
--------

[](#commands)

### Create layout

[](#create-layout)

To create a new layout you can run the command below.

```
php artisan make:flex Element\\Counter --livewire
```

### Create templates

[](#create-templates)

```
php artisan make:flex Forms\\Newsletter --template=newsletter
php artisan make:flex Forms\\Contact --template=form
```

Prepare
-------

[](#prepare)

### Nova Resource

[](#nova-resource)

You can use the `getFlex()` method to get all the layouts that are provided with this package and the layouts that you created yourself. If you want to manualy add flexibles to your Nova resource, please reference the manual usage section of this readme.

```
class Page extends Resource
{
	use \Marshmallow\Nova\Flexible\Nova\Traits\HasFlexable;

	public function fields(Request $request)
	{
		return [
			// ...
			$this->getFlex(),
			// ...
		];
	}
}
```

### Models

[](#models)

Make sure your model will cast this data correctly by adding this to the field of your model.

```
class Page extends Model
{
	use \Marshmallow\Nova\Flexible\Concerns\HasFlexible;

	protected $casts = [
		/**
		 * 'layout' in the example below references the field
		 * in the model where the json is stored.
		 */
		'layout' => \Marshmallow\Nova\Flexible\Casts\FlexibleCast::class,
	];
}
```

Customize
---------

[](#customize)

### Title on Layout classes

[](#title-on-layout-classes)

Sometimes its very hard to see which group is what because all items look the same. It is possible to get a value from one of the fields to be displayed in the group overview. By default the `title` field will be used but it can be overriten.

```
// Layout class
// In a layout class you just set the $titleFromContent property to the field name you
// wish it shows.
protected $titleFromContent = 'title';
```

### Title on custom layouts

[](#title-on-custom-layouts)

```
/**
 * For custom layout, we need to add a 4th parameter. This should be a callable and call the setTitleFromContent method.
 */
->addLayout(
	'Mr. Mallow',
	'mr_mallow', [
        Text::make('Title', 'title'),
        Text::make('Sub title', 'sub_title'),
        // ...
	],
	function ($layout) {
		return $layout->setTitleFromContent('sub_title');
    }
)

/**
 * You can also use a callback to build your title.
 */
->addLayout(
	'Mr. Mallow',
	'mr_mallow', [
        Text::make('Title', 'title'),
        Date::make('Date', 'date'),
        Textarea::make('Content', 'content'),
        // ...
	],
	function ($layout) {
		return $layout->resolveTitleUsing(function ($title, $date, $content) {
            return $title . ' ' . Carbon::parse($date)->format('Y-m-d');
        });
    }
)
```

### Translatable Columns

[](#translatable-columns)

When working with the [Marshmallow Translatable package](https://github.com/marshmallow-packages/translatable), you can specify which fields should be shown when translating content. By default, all fields are shown, but you can limit this to only the translatable fields.

```
// Layout class
// In a layout class you can define which fields should be visible during translation
protected function translatableColumns(): array
{
    return [
        'title',
        'content',
        'description',
        // Only these fields will be shown when translating
    ];
}
```

Config Methods
--------------

[](#config-methods)

You can call a load config method once you've created your flexible field to change the behaviour of the flexible field. Below you will find some examples.

```
$this->getFlex(__('Layout'), 'layout')
    ->loadConfig([
        'simpleView' => null,
        'allowedToCreate' => ['allowed' => true|false],
        'allowedToDelete' => ['allowed' => true|false],
        'allowedToChangeOrder' => ['allowed' => true|false],
        'simpleMenu' => null,
        'button' => ['label' => 'Button Label'],
        'fullWidth' => ['fullWidth' => true|false],
        'limit' => ['limit' => 3],
    ]),
```

Helpers
-------

[](#helpers)

You can overrule a lot of defaults with the methods below.

```
Flexible::make(__('Marshmallow'), 'marshmallow')
    ->addLayout(__('Mr. Mallow'), 'mr_mallow', [
        //
    ])

    // Don't use the component selector but a simple dropdown menu
    ->simpleMenu()

    // Use the full with of the nova container
    ->fullWidth()

    // Collapse all layouts when they are loaded
    ->collapsed()

    // Change the text in the add more layouts button
    ->button(__('Add comment'))

    // Disable deleting items
    ->deletionNotAllowed();
```

---

Credits
-------

[](#credits)

See  - [Whitecube](https://github.com/whitecube)

Copyright (c) 2020 marshmallow.

License
-------

[](#license)

#### The Layouts Collection

[](#the-layouts-collection)

Collections returned by the `FlexibleCast` cast and the `HasFlexible` trait extend the original `Illuminate\Support\Collection`. These custom layout collections expose a `find(string $name)` method which returns the first layout having the given layout `$name`.

#### The Layout instance

[](#the-layout-instance)

Layouts are some kind of *fake models*. They use Laravel's `HasAttributes` trait, which means you can define accessors &amp; mutators for the layout's attributes. Furthermore, it's also possible to access the Layout's properties using the following methods:

##### `name()`

[](#name)

Returns the layout's name.

##### `title()`

[](#title)

Returns the layout's title (as shown in Nova).

##### `key()`

[](#key)

Returns the layout's unique key (the layout's unique identifier).

Going further
-------------

[](#going-further)

When using the Flexible Content field, you'll quickly come across of some use cases where the basics described above are not enough. That's why we developed the package in an extendable way, making it possible to easily add custom behaviors and/or capabilities to Field and its output.

### Custom Layout Classes

[](#custom-layout-classes)

Sometimes, `addLayout` definitions can get quite long, or maybe you want them to be shared with other `Flexible` fields. The answer to this is to extract your Layout into its own class. [See the docs for more information on this](https://Marshmallow.github.io/nova-flexible-content/#/?id=custom-layout-classes).

### Predefined Preset Classes

[](#predefined-preset-classes)

In addition to reusable Layout classes, you can go a step further and create `Preset` classes for your Flexible fields. These allow you to reuse your whole Flexible field anywhere you want. They also make it easier to make your Flexible fields dynamic, for example if you want to add Layouts conditionally. And last but not least, they also have the added benefit of cleaning up your Nova Resource classes, if your Flexible field has a lot of `addLayout` definitions. [See the docs for more information on this](https://Marshmallow.github.io/nova-flexible-content/#/?id=predefined-preset-classes).

### Custom Resolver Classes

[](#custom-resolver-classes)

By default, the field takes advantage of a **JSON column** on your model's table. In some cases, you'd really like to use this field, but for some reason a JSON attribute is just not the way to go. For example, you could want to store the values in another table (meaning you'll be using the Flexible Content field instead of a traditional BelongsToMany or HasMany field). No worries, we've got you covered!

Tell the field how to store and retrieve its content by creating your own Resolver class, which basically just contains two simple methods: `get` and `set`. [See the docs for more information on this](https://Marshmallow.github.io/nova-flexible-content/#/?id=custom-resolver-classes).

### Usage with nova-page

[](#usage-with-nova-page)

Maybe you heard of one of our other packages, [nova-page](https://github.com/Marshmallow/nova-page), which is a Nova Tool that allows to edit static pages such as an *"About"* page (or similar) without having to declare a model for it individually. More often than not, the Flexible Content Field comes in handy. Don't worry, both packages work well together! First create a [nova page template](https://github.com/Marshmallow/nova-page#creating-templates) and add a [flexible content](https://github.com/Marshmallow/nova-flexible-content#adding-layouts) to the template's fields.

As explained in the documentation, you can [access nova-page's static content](https://github.com/Marshmallow/nova-page#accessing-the-data-in-your-views) in your blade views using `{{ Page::get('attribute') }}`. When requesting the flexible content like this, it returns a raw JSON string describing the flexible content, which is of course not very useful. Instead, you can simply implement the `Marshmallow\Nova\Flexible\Concerns\HasFlexible` trait on your page Templates, which will expose the `Page::flexible('attribute')` facade method and will take care of the flexible content's transformation.

```
namespace App\Nova\Templates;

// ...
use Marshmallow\Nova\Flexible\Concerns\HasFlexible;

class Home extends Template
{
    use HasFlexible;

    // ...
}
```

💖 Sponsorships
--------------

[](#-sponsorships)

If you are reliant on this package in your production applications, consider [sponsoring us](https://github.com/sponsors/Marshmallow)! It is the best way to help us keep doing what we love to do: making great open source software.

Contributing
------------

[](#contributing)

Feel free to suggest changes, ask for new features or fix bugs yourself. We're sure there are still a lot of improvements that could be made, and we would be very happy to merge useful pull requests.

Thanks!

### Unit tests

[](#unit-tests)

When adding a new feature or fixing a bug, please add corresponding unit tests. The current set of tests is limited, but every unit test added will improve the quality of the package.

Run PHPUnit by calling `composer test`.

Made with ❤️ for open source
----------------------------

[](#made-with-️-for-open-source)

At [Marshmallow](https://www.Marshmallow.be) we use a lot of open source software as part of our daily work. So when we have an opportunity to give something back, we're super excited!

We hope you will enjoy this small contribution from us and would love to [hear from you](mailto:hello@Marshmallow.be) if you find it useful in your projects. Follow us on [Twitter](https://twitter.com/Marshmallow_be) for more updates!

###  Health Score

63

—

FairBetter than 99% of packages

Maintenance90

Actively maintained with recent releases

Popularity32

Limited adoption so far

Community28

Small or concentrated contributor base

Maturity90

Battle-tested with a long release history

 Bus Factor3

3 contributors hold 50%+ of commits

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 ~21 days

Recently: every ~38 days

Total

124

Last Release

56d ago

Major Versions

v1.8.2 → v2.3.02022-10-25

v1.8.3 → v2.4.22022-12-02

v2.11.0 → v5.0.02025-01-05

v2.13.0 → v5.1.12025-02-27

v2.x-dev → v5.2.12025-08-01

PHP version history (6 changes)v0.1.0PHP &gt;=7.1.0

v1.2.2PHP ^7.1|^8.0

v0.2.9PHP &gt;=7.2.5

v2.0.0PHP ^8.0

v0.2.12PHP ^7.3|^8.0

v5.1.2PHP ^8.2

### Community

Maintainers

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

---

Top Contributors

[![stefvanesch](https://avatars.githubusercontent.com/u/46725619?v=4)](https://github.com/stefvanesch "stefvanesch (230 commits)")[![toonvandenbos](https://avatars.githubusercontent.com/u/5635557?v=4)](https://github.com/toonvandenbos "toonvandenbos (160 commits)")[![voidgraphics](https://avatars.githubusercontent.com/u/9298484?v=4)](https://github.com/voidgraphics "voidgraphics (131 commits)")[![LTKort](https://avatars.githubusercontent.com/u/2412670?v=4)](https://github.com/LTKort "LTKort (101 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (63 commits)")[![GarethSomers](https://avatars.githubusercontent.com/u/5942607?v=4)](https://github.com/GarethSomers "GarethSomers (19 commits)")[![Jubeki](https://avatars.githubusercontent.com/u/15707543?v=4)](https://github.com/Jubeki "Jubeki (15 commits)")[![Tarpsvo](https://avatars.githubusercontent.com/u/2018660?v=4)](https://github.com/Tarpsvo "Tarpsvo (11 commits)")[![harmenjanssen](https://avatars.githubusercontent.com/u/803176?v=4)](https://github.com/harmenjanssen "harmenjanssen (6 commits)")[![chrisneal](https://avatars.githubusercontent.com/u/1110269?v=4)](https://github.com/chrisneal "chrisneal (6 commits)")[![Saifallak](https://avatars.githubusercontent.com/u/6053156?v=4)](https://github.com/Saifallak "Saifallak (5 commits)")[![mikaelpopowicz](https://avatars.githubusercontent.com/u/5689944?v=4)](https://github.com/mikaelpopowicz "mikaelpopowicz (4 commits)")[![happyDemon](https://avatars.githubusercontent.com/u/38573?v=4)](https://github.com/happyDemon "happyDemon (4 commits)")[![lucienversendaal](https://avatars.githubusercontent.com/u/76224741?v=4)](https://github.com/lucienversendaal "lucienversendaal (4 commits)")[![slackernrrd](https://avatars.githubusercontent.com/u/1019496?v=4)](https://github.com/slackernrrd "slackernrrd (3 commits)")[![ngiraud](https://avatars.githubusercontent.com/u/12152071?v=4)](https://github.com/ngiraud "ngiraud (3 commits)")[![martijngastkemper](https://avatars.githubusercontent.com/u/250662?v=4)](https://github.com/martijngastkemper "martijngastkemper (3 commits)")[![zareismail](https://avatars.githubusercontent.com/u/23401061?v=4)](https://github.com/zareismail "zareismail (2 commits)")[![bernhardh](https://avatars.githubusercontent.com/u/642292?v=4)](https://github.com/bernhardh "bernhardh (2 commits)")[![danieleugoletti](https://avatars.githubusercontent.com/u/115441?v=4)](https://github.com/danieleugoletti "danieleugoletti (2 commits)")

---

Tags

laravellayoutfieldFlexiblenovagrouprepeat

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/marshmallow-nova-flexible/health.svg)

```
[![Health](https://phpackages.com/badges/marshmallow-nova-flexible/health.svg)](https://phpackages.com/packages/marshmallow-nova-flexible)
```

###  Alternatives

[whitecube/nova-flexible-content

Flexible Content &amp; Repeater Fields for Laravel Nova.

8053.0M25](/packages/whitecube-nova-flexible-content)[digital-creative/nova-dashboard

The missing dashboard for nova.

7169.3k1](/packages/digital-creative-nova-dashboard)[outl1ne/nova-simple-repeatable

A Laravel Nova simple repeatable rows field.

74356.3k](/packages/outl1ne-nova-simple-repeatable)[optimistdigital/nova-simple-repeatable

A Laravel Nova simple repeatable rows field.

74151.2k](/packages/optimistdigital-nova-simple-repeatable)

PHPackages © 2026

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