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

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

kayacekovic/nova-flexible-content
=================================

Flexible Content &amp; Repeater Fields for Laravel Nova.

v1.0.6(3y ago)04MITPHPPHP ^7.3|^8.0

Since Mar 5Pushed 2y agoCompare

[ Source](https://github.com/kayacekovic/nova-flexible-content)[ Packagist](https://packagist.org/packages/kayacekovic/nova-flexible-content)[ GitHub Sponsors](https://github.com/whitecube)[ RSS](/packages/kayacekovic-nova-flexible-content/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (5)Versions (44)Used By (0)

[![Laravel Nova Flexible Content](https://github.com/whitecube/nova-flexible-content/raw/master/title.png)](https://github.com/whitecube/nova-flexible-content/raw/master/title.png)
====================================================================================================================================================================================

[](#)

[![](https://camo.githubusercontent.com/d5920ea0ca86262cbdae12dfe33404790733f6fc020b678916be2baf796b20da/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f7768697465637562652f6e6f76612d666c657869626c652d636f6e74656e742e7376673f7374796c653d666c6174)](https://camo.githubusercontent.com/d5920ea0ca86262cbdae12dfe33404790733f6fc020b678916be2baf796b20da/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f7768697465637562652f6e6f76612d666c657869626c652d636f6e74656e742e7376673f7374796c653d666c6174)[![](https://camo.githubusercontent.com/6e2257a85125644e5ea918a29d36208e942e13d820b9d2c98c5c3fbabae9cdb5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f7768697465637562652f6e6f76612d666c657869626c652d636f6e74656e742e7376673f636f6c6f72423d677265656e267374796c653d666c6174)](https://packagist.org/packages/whitecube/nova-flexible-content)[![](https://camo.githubusercontent.com/73aef93f50e1b2e2d60ed31812b40bbdb24282f3192ff32530c3aa81773029b2/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7768697465637562652f6e6f76612d666c657869626c652d636f6e74656e742e7376673f7374796c653d666c6174)](https://github.com/whitecube/nova-flexible-content/blob/master/LICENSE)

An easy &amp; complete Flexible Field for Laravel Nova, perfect for repeated and flexible field groups.

[![Laravel Nova Flexible Content in action](https://user-images.githubusercontent.com/9298484/164532562-6e4e4179-8a53-470c-97c8-237e9a2c2ebb.gif)](https://user-images.githubusercontent.com/9298484/164532562-6e4e4179-8a53-470c-97c8-237e9a2c2ebb.gif)

Quick start
-----------

[](#quick-start)

Here's a very condensed guide to get you started asap. See the full docs at

### Install

[](#install)

```
composer require whitecube/nova-flexible-content

```

### Usage

[](#usage)

A flexible field allows easy management of repeatable and orderable groups of fields. As opposed to the few existing solutions for Laravel Nova, this one does not have constraints on which fields you are allowed to use within these groups. That means you can use all Laravel Nova field types, and also any community-made fields.

#### Adding layouts

[](#adding-layouts)

A layout represents a group of fields that can be repeated inside the Flexible field. You can add as many layouts as you wish. If only one layout is defined the field will behave like a simple Repeater and by adding more layouts you'll obtain a Flexible Content. Both concepts are similar to [their cousins in Wordpress' ACF Plugin](https://www.advancedcustomfields.com/add-ons/).

Layouts can be added using the following method on your Flexible fields:

```
 addLayout(string $title, string $name, array $fields)
```

The `$name` parameter is used to store the chosen layout in the field's value. Choose it wisely, you'll probably use it to identify the layouts in your application.

```
use Whitecube\NovaFlexibleContent\Flexible;

/**
 * Get the fields displayed by the resource.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function fields(Request $request)
{
    return [
        // ...

        Flexible::make('Content')
            ->addLayout('Simple content section', 'wysiwyg', [
                Text::make('Title'),
                Markdown::make('Content')
            ])
            ->addLayout('Video section', 'video', [
                Text::make('Title'),
                Image::make('Video Thumbnail', 'thumbnail'),
                Text::make('Video ID (YouTube)', 'video'),
                Text::make('Video Caption', 'caption')
            ])
    ];
}
```

[![Example of Flexible layouts](https://user-images.githubusercontent.com/9298484/164533823-1b1b4934-75b8-49f2-92a0-a54812ccf463.png)](https://user-images.githubusercontent.com/9298484/164533823-1b1b4934-75b8-49f2-92a0-a54812ccf463.png)

#### Customizing the button label

[](#customizing-the-button-label)

You can change the default "Add layout" button's text like so:

```
Flexible::make('Content')
    ->button('Add something amazing!');
```

[![Add something amazing](https://user-images.githubusercontent.com/9298484/164544726-2a2b1ce5-aa19-489c-abee-b877e7e8d445.png)](https://user-images.githubusercontent.com/9298484/164544726-2a2b1ce5-aa19-489c-abee-b877e7e8d445.png)

### Using Flexible values in views

[](#using-flexible-values-in-views)

If you are using Laravel 6 and under, or don't want to use casts, please [use an accessor on your model with the HasFlexible trait](https://whitecube.github.io/nova-flexible-content/#/?id=with-the-hasflexible-trait).

Laravel 7 brings custom casts to the table, and flexible content fields are the perfect use case for them. The field stores its values as a single JSON string, meaning this string needs to be parsed before it can be used in your application. This can be done trivially by using the `FlexibleCast` class in this package:

```
namespace App;

use Illuminate\Database\Eloquent\Model;
use Whitecube\NovaFlexibleContent\Value\FlexibleCast;

class MyModel extends Model
{
    protected $casts = [
        'flexible-content' => FlexibleCast::class
    ];
}
```

By default, the `FlexibleCast` class will collect basic `Layout` instances. If you want to map the layouts into [Custom Layout instances](https://github.com/whitecube/nova-flexible-content#custom-layout-classes), it is also possible. First, create a custom flexible cast by running `php artisan flexible:cast MyFlexibleCast`. This will create the file in the `App\Casts` directory.

Then easily map your custom layout classes to the proper keys:

```
namespace App\Casts;

class MyFlexibleCast extends FlexibleCast
{
    protected $layouts = [
        'wysiwyg' => \App\Nova\Flexible\Layouts\WysiwygLayout::class,
        'video' => \App\Nova\Flexible\Layouts\VideoLayout::class,
    ]
}
```

If you need more control, you can [override the `getLayoutMappings` method](https://whitecube.github.io/nova-flexible-content/#/?id=having-more-control-over-the-layout-mappings) instead.

#### 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://whitecube.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://whitecube.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://whitecube.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/whitecube/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/whitecube/nova-page#creating-templates) and add a [flexible content](https://github.com/whitecube/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/whitecube/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 `Whitecube\NovaFlexibleContent\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 Whitecube\NovaFlexibleContent\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/whitecube)! 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 [Whitecube](https://www.whitecube.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@whitecube.be) if you find it useful in your projects. Follow us on [Twitter](https://twitter.com/whitecube_be) for more updates!

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity3

Limited adoption so far

Community19

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor2

2 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 ~34 days

Recently: every ~18 days

Total

41

Last Release

1234d ago

Major Versions

v0.2.10 → v1.0.02022-04-21

v0.2.12 → v1.0.52022-10-11

v0.2.13 → v1.0.62022-12-02

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

v0.2.9PHP &gt;=7.2.5

v1.0.0PHP ^7.3|^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/8a728b47a1ee9fd11f949888a6de60971bbeaf3057d022eab6a6e50491089b4b?d=identicon)[kayacekovic](/maintainers/kayacekovic)

---

Top Contributors

[![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 (149 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (26 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)")[![chrisneal](https://avatars.githubusercontent.com/u/1110269?v=4)](https://github.com/chrisneal "chrisneal (6 commits)")[![KasparRosin](https://avatars.githubusercontent.com/u/33309407?v=4)](https://github.com/KasparRosin "KasparRosin (6 commits)")[![harmenjanssen](https://avatars.githubusercontent.com/u/803176?v=4)](https://github.com/harmenjanssen "harmenjanssen (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)")[![Nks](https://avatars.githubusercontent.com/u/349293?v=4)](https://github.com/Nks "Nks (4 commits)")[![happyDemon](https://avatars.githubusercontent.com/u/38573?v=4)](https://github.com/happyDemon "happyDemon (4 commits)")[![martijngastkemper](https://avatars.githubusercontent.com/u/250662?v=4)](https://github.com/martijngastkemper "martijngastkemper (3 commits)")[![ngiraud](https://avatars.githubusercontent.com/u/12152071?v=4)](https://github.com/ngiraud "ngiraud (3 commits)")[![HenriqueSPin](https://avatars.githubusercontent.com/u/12719645?v=4)](https://github.com/HenriqueSPin "HenriqueSPin (3 commits)")[![slackernrrd](https://avatars.githubusercontent.com/u/1019496?v=4)](https://github.com/slackernrrd "slackernrrd (3 commits)")[![chrispage1](https://avatars.githubusercontent.com/u/2487374?v=4)](https://github.com/chrispage1 "chrispage1 (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)")

---

Tags

laravellayoutfieldFlexiblenovagrouprepeat

###  Code Quality

TestsPHPUnit

Code StyleLaravel Pint

### Embed Badge

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

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

###  Alternatives

[whitecube/nova-flexible-content

Flexible Content &amp; Repeater Fields for Laravel Nova.

8053.0M25](/packages/whitecube-nova-flexible-content)[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)[alexwenzel/nova-dependency-container

A Laravel Nova 4 form container for grouping fields that depend on other field values.

461.0M2](/packages/alexwenzel-nova-dependency-container)[sbine/route-viewer

A Laravel Nova tool to view your registered routes.

57215.9k](/packages/sbine-route-viewer)[markwalet/nova-modal-response

A Laravel Nova asset for Modal responses on an action.

14720.0k](/packages/markwalet-nova-modal-response)

PHPackages © 2026

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