PHPackages                             carbon/eel - 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. carbon/eel

ActiveNeos-carbon[Utility &amp; Helpers](/categories/utility)

carbon/eel
==========

Some nice Eel helper for Neos.io

2.26.0(2mo ago)7292.5k↓15%220MITPHPPHP ^8.1CI passing

Since Jun 4Pushed 1mo ago3 watchersCompare

[ Source](https://github.com/CarbonPackages/Carbon.Eel)[ Packagist](https://packagist.org/packages/carbon/eel)[ Fund](https://www.paypal.me/Jonnitto/20eur)[ GitHub Sponsors](https://github.com/jonnitto)[ RSS](/packages/carbon-eel/feed)WikiDiscussions main Synced 2d ago

READMEChangelog (10)Dependencies (10)Versions (71)Used By (20)

[![Latest stable version](https://camo.githubusercontent.com/6b94f2ea001ccd07ed30ad341130732647f464ffd0ec7dd8b406764f5c871d9d/68747470733a2f2f706f7365722e707567782e6f72672f636172626f6e2f65656c2f762f737461626c65)](https://packagist.org/packages/carbon/eel) [![Total downloads](https://camo.githubusercontent.com/6c6bca217089e7f4d8618f2069fbb057e6fa945a05ed1530591d10e38ea2c83d/68747470733a2f2f706f7365722e707567782e6f72672f636172626f6e2f65656c2f646f776e6c6f616473)](https://packagist.org/packages/carbon/eel) [![License](https://camo.githubusercontent.com/743a866d3b7f106f88b632e3684f016f6ed9de54e733537c232fb2697836cb6b/68747470733a2f2f706f7365722e707567782e6f72672f636172626f6e2f65656c2f6c6963656e7365)](LICENSE) [![GitHub forks](https://camo.githubusercontent.com/949cd68d3d882c8db9c58182c2e4e4e61daae11dab697dda92074b044fc55d4e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f666f726b732f436172626f6e5061636b616765732f436172626f6e2e45656c2e7376673f7374796c653d736f6369616c266c6162656c3d466f726b)](https://github.com/CarbonPackages/Carbon.Eel/fork) [![GitHub stars](https://camo.githubusercontent.com/ddb0d320bbe91f949d8208174f4bda6e41c7012441d499e1da65a99178041a0e/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f436172626f6e5061636b616765732f436172626f6e2e45656c2e7376673f7374796c653d736f6369616c266c6162656c3d5374617273)](https://github.com/CarbonPackages/Carbon.Eel/stargazers) [![GitHub watchers](https://camo.githubusercontent.com/359f838f753d02c117b27d21f5812eb0822aecf90d73fece4c27695c7065ae94/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f77617463686572732f436172626f6e5061636b616765732f436172626f6e2e45656c2e7376673f7374796c653d736f6369616c266c6162656c3d5761746368)](https://github.com/CarbonPackages/Carbon.Eel/subscription)

Carbon.Eel Package for [Neos CMS](https://www.neos.io)
======================================================

[](#carboneel-package-for-neos-cms)

BEM Helper
----------

[](#bem-helper)

Generates BEM classes. The modifiers property can be a string (for one modifier), an array (e.g. `['one', 'two']`), or an array with keys and values. If you have an array with keys and values (like a Fusion DataStructure) and a value is `true`, the key's name gets used for the modifier.

- `block` (string, required) The name of the block
- `element` (string) The name of the element, optional
- `modifiers` (string|array) The name of the modifiers, optional

### `BEM.array(block, element, modifiers)`

[](#bemarrayblock-element-modifiers)

Shortcut to `Carbon.Array.BEM(block, element, modifiers)`

### `BEM.string(block, element, modifiers)`

[](#bemstringblock-element-modifiers)

Shortcut to `Carbon.String.BEM(block, element, modifiers)`

### `BEM.modifier(class, modifiers)`

[](#bemmodifierclass-modifiers)

Generates a string with BEM classes. The modifiers property can be a string (for one modifier), an array (e.g. `['one', 'two']`), or an array with keys and values. If you have an array with keys and values (like a Fusion DataStructure) and the value is `true`, the key's name gets used for the modifier.

- `class` (string, required) The name of the class
- `modifiers` (string|array) The name of the modifiers, optional

**Return** The string

Array Helper
------------

[](#array-helper)

### `Carbon.Array.BEM(block, element, modifiers)`

[](#carbonarraybemblock-element-modifiers)

Generates an array with BEM classes. The modifiers property can be a string (for one modifier), an array (e.g. `['one', 'two']`), or an array with keys and values. If you have an array with keys and values (like a Fusion DataStructure) and the value is `true`, the key's name gets used for the modifier.

- `block` (string, required) The name of the block
- `element` (string) The name of the element, optional
- `modifiers` (string|array) The name of the modifiers, optional

**Return** The array

### `Carbon.Array.chunk(array, length, preserveKeys)`

[](#carbonarraychunkarray-length-preservekeys)

Chunks an array into arrays with `length` elements. The last chunk may contain less than `length` elements.

- `array` (array, required) The array to work on
- `length` (integer, required) The size of each chunk
- `preserveKeys` (bool) When set to `true`, keys will be preserved. Default is `false`, which will reindex the chunk numerically

### `Carbon.Array.join(array, separator)`

[](#carbonarrayjoinarray-separator)

Join the given array recursively using the given separator.

```
${Carbon.Array.join(array, ',')}
```

- `array` (array) The array that should be processed
- `separator` (string, optional) The separator between the values defaults to `,`

**Return** The converted array as a string

### `Carbon.Array.extractSubElements(array, preserveKeys)`

[](#carbonarrayextractsubelementsarray-preservekeys)

This method extracts sub-elements to the parent level.

An input array of type:

```
[
 element1 => [
   0 => 'value1'
 ],
 element2 => [
   0 => 'value2'
   1 => 'value3'
 ],

```

will be converted to:

```
[
   0 => 'value1'
   1 => 'value2'
   2 => 'value3'
]

```

- `array` (array) The array that should be processed
- `preserveKeys` (boolean, optional) Option if the key should be preserved, defaults to `false`

**Return** The converted array

### `Carbon.Array.intersect(array1, array2, array_)`

[](#carbonarrayintersectarray1-array2-array_)

- `array1` (iterable|mixed) First array or value
- `array2` (iterable|mixed) Second array or value
- `array_` (iterable|mixed, optional) Optional variable list of additional arrays / values

Returns an array containing all the values of `array1` that are present in all the arguments.

### `Carbon.Array.length(array)`

[](#carbonarraylengtharray)

The method counts elements of a given array or a countable object. Return `0` if it is not an countable object.

```
count = ${Carbon.Array.length(countable)}
```

### `Carbon.Array.hasKey(array, key)`

[](#carbonarrayhaskeyarray-key)

Returns a boolean if the array has a specific key

```
bool = ${Carbon.Array.hasKey(array, key)}
```

### `Carbon.Array.hasValue(array, value)`

[](#carbonarrayhasvaluearray-value)

Returns a boolean if the array has a specific value

```
bool = ${Carbon.Array.hasValue(array, value)}
```

### `Carbon.Array.getValueByPath(array, path)`

[](#carbonarraygetvaluebypatharray-path)

Returns the value of a nested array by following the specified path.

```
value = ${Carbon.Array.getValueByPath(array, path)}
```

### `Carbon.Array.setValueByPath(array, path, value)`

[](#carbonarraysetvaluebypatharray-path-value)

Sets the given value in a nested array or object by following the specified path.

```
array = ${Carbon.Array.setValueByPath(subject, path, value)}
```

### `Carbon.Array.check(variable)`

[](#carbonarraycheckvariable)

Check if a variable is iterable and has items

**Return** The variable or `null` if it is empty or not an iterable

### `Carbon.Array.isCountable(variable)`

[](#carbonarrayiscountablevariable)

Check if the given variable is countable

**Return** `true` or `false`

### `Carbon.Array.sortByItem(array, key, direction)`

[](#carbonarraysortbyitemarray-key-direction)

- `array` (iterable|mixed) array with arrays to sort
- `key` (string) Key of array to sort
- `direction` (string, optional) `ASC` or `DESC`. Direction of sorting
- `translate` (boolean, optional) If true, the key will be translated using the translation service

**Return** The sorted array

Date Helper
-----------

[](#date-helper)

### `Carbon.Date.secondsUntil(string|DateTime, dateinerval)`

[](#carbondatesecondsuntilstringdatetime-dateinerval)

Return seconds until the given offset or datetime. Very useful for `maximumLifetime` on the `@cache` entry.

- `string` (string|DateTime) DateTime (string or object) or an offset in [`DateInterval` format](https://www.php.net/manual/en/dateinterval.format.php) starting from midnight
- `dateinerval` (boolean, optional) true if interval should be used or first argument should be used for the date, defaults to `true`

In this example, we clear the cache at midnight by adding an offset of 0 hours.

```
@cache {
    mode = 'cached'
    maximumLifetime = ${Carbon.Date.secondsUntil('PT0H')}
    ...
}
```

To get the seconds until next year, you can do it like this:

```
secondUntilNextYear = ${Carbon.Date.secondsUntil('first day of January next year', false)}
```

You can also compare date with this: (In this case, you don't need to set `dateinerval` to `false`)

```
compareDateToNow = ${Carbon.Date.secondsUntil(DateTimeObject)}
```

**Return** The timespan in seconds (integer)

### `Carbon.Date.timeToDateInterval(string)`

[](#carbondatetimetodateintervalstring)

Convert time duration (1:00) into a [`DateInterval`](https://www.php.net/manual/de/class.dateinterval.php)

**Return** The duration as DateInterval

FileContent Helper
------------------

[](#filecontent-helper)

### `Carbon.FileContent.path(string)`

[](#carbonfilecontentpathstring)

Returns the file content of a path. Fails silently.

Examples:

```
Carbon.FileContent.path('resource://Foo.Bar/Private/Assets/Logo.svg')
Carbon.FileContent.path('Foo.Bar/Private/Assets/Logo.svg')
```

- `string` (string) The path to the file

**Return** The content of the file

### `Carbon.FileContent.pathHash(string, length)`

[](#carbonfilecontentpathhashstring-length)

Returns the hash value from the file content of a path. Fails silently.

Examples:

```
Carbon.FileContent.pathHash('resource://Foo.Bar/Private/Assets/Logo.svg') == 1d62f5a5
Carbon.FileContent.pathHash('Foo.Bar/Private/Assets/Logo.svg', 20) == 1d62f5a55ad5e304d60d
```

- `string` (string) The path to the file
- `length` (integer, optional) The length of the hash value defaults to `8`. The maximal value is `40`

**Return** The hash value from the content of the file

### `Carbon.FileContent.resource(resource)`

[](#carbonfilecontentresourceresource)

Returns the file content of a persisted resource. Fails silently.

Example:

```
Carbon.FileContent.resource(q(node).property('file'))
```

- `resource` (resource) The persisted resource to read

**Return** The content of the file

### `Carbon.FileContent.resourceHash(resource, length)`

[](#carbonfilecontentresourcehashresource-length)

Returns the hash value from the file content of a persisted resource. Fails silently.

Example:

ExpressionResult`Carbon.FileContent.resourceHash(q(node).property('file'))``'1d62f5a5'``Carbon.FileContent.resourceHash(q(node).property('file'), 20)``'1d62f5a55ad5e304d60d'`- `resource` (resource) The persisted resource to read
- `length` (integer, optional) The length of the hash value defaults to `8`. The maximal value is `40`

**Return** The hash value from the content of the file

Tailwind Helper
---------------

[](#tailwind-helper)

### `Tailwind.merge(mixed1, mixed2, mixedN)`

[](#tailwindmergemixed1-mixed2-mixedn)

This helper allows you to merge multiple [Tailwind CSS](https://tailwindcss.com) classes and automatically resolves conflicts between them without headaches. Render all arguments as classNames and apply conditions if needed. Merge strings and arrays to a string with unique values, separated by an empty space.

All arguments of the eel helper are evaluated and the following rules are applied:

- falsy values: (`null`, `''`, `[]`, `{}`) are not rendererd
- array: all items that are scalar and truthy are rendered as classname
- object: keys that have a truthy values are rendered as classname
- scalar: is cast to string and rendered as class-name

It is based on [tailwind-merge-php](https://github.com/gehrisandro/tailwind-merge-php).

Examples:

ExpressionResult`Tailwind.merge('w-8 h-8 rounded-full rounded-lg')``'w-8 h-8 rounded-lg'``Tailwind.merge(['w-8 rounded-full'], 'rounded-lg', 'h-8')``'w-8 rounded-lg h-8'``Tailwind.merge(null, null, {}, [])``null``Tailwind.merge('one', ['one', 'two'], {three: true, four: false}``'one two three'`**Return** The merged string

#### Configuration

[](#configuration)

If you are using Tailwind CSS without any extra config, you can use the Eel helper right away. And stop reading here.

If you're using a custom Tailwind config, you may need to configure the Eel helper as well to merge classes properly.

By default it is configured in a way that you can still use it if all the following apply to your Tailwind config:

- Only using color names which don't clash with other Tailwind class names
- Only deviating by number values from number-based Tailwind classes
- Only using font-family classes which don't clash with default font-weight classes
- Sticking to default Tailwind config for everything else

If some of these points don't apply to you, you need to customize the configuration.

This is an example to add a custom font size of `very-large`:

```
Carbon:
  Eel:
    tailwindMergeConfig:
      classGroups:
        "font-size":
          - text: ["very-large"]
```

You can also enable different [validators](https://github.com/gehrisandro/tailwind-merge-php/tree/main/src/Validators), to make everything easier. For instance, if you use the [Tailwind OKLCH Plugin](https://github.com/MartijnCuppens/tailwindcss-oklch), you can set it like that:

```
Carbon:
  Eel:
    tailwindMergeConfig:
      classGroups:
        "fill-lightness":
          - "fill-lightness-offset":
              ["INTEGER_VALIDATOR", "ARBITRARY_NUMBER_VALIDATOR"]
        "border-lightness":
          - "border-lightness-offset":
              ["INTEGER_VALIDATOR", "ARBITRARY_NUMBER_VALIDATOR"]
        "text-lightness":
          - "text-lightness-offset":
              ["INTEGER_VALIDATOR", "ARBITRARY_NUMBER_VALIDATOR"]
        "bg-lightness":
          - "bg-lightness-offset":
              ["INTEGER_VALIDATOR", "ARBITRARY_NUMBER_VALIDATOR"]
```

If you want to use a certain validator, just change it to constant case and add it as a string. So, for examle, if you want to use the `TshirtSizeValidator`, just add `TSHIRT_SIZE_VALIDATOR` to the list.

> The merge service uses a its own cache `Carbon_Eel_Tailwind`. Make sure to clear the cache when you are making changes to the configuration.

AlpineJS Helper
---------------

[](#alpinejs-helper)

### `AlpineJS.object(arg1, arg2, ..argN)`

[](#alpinejsobjectarg1-arg2-argn)

Generate an object for AlpineJS directive [`x-data`](https://alpinejs.dev/directives/data). Supports nested arrays. You could do the same with `Json.stringify()`, but this function is shorter, as AlpineJS accepts objects and easier to write and read. The default magics from Alpine.js will not be converted to string. The same goes with methods (see example below).

Examples:

ExpressionResult`AlpineJS.object({effect: 'slide', spaceBetween: 12, loop: true, navigation: null})``"{effect:'slide',spaceBetween:12,loop:true,navigation:null}"``AlpineJS.object({nested: {value: true, nulled: null'}})``"{nested:{value:true,nulled:null}}"``AlpineJS.object({persistedNumber: '$persist(5)'})``"{persistedNumber:$persist(5)}"``AlpineJS.object({value: 'someValue', log(value): '{console.log(value)}'})``"{value:'someValue',log(value){console.log(value)}}"`Of course you can also pass `DataStructures` to the helper:

```
prototype(Foo.Bar:Example)
