PHPackages                             flyntwp/acf-field-group-composer - 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. flyntwp/acf-field-group-composer

ActiveWordpress-plugin[Utility &amp; Helpers](/categories/utility)

flyntwp/acf-field-group-composer
================================

v1.1.0(2y ago)52155.7k↓48.4%14[2 issues](https://github.com/flyntwp/acf-field-group-composer/issues)[2 PRs](https://github.com/flyntwp/acf-field-group-composer/pulls)PHP

Since Dec 13Pushed 2y ago2 watchersCompare

[ Source](https://github.com/flyntwp/acf-field-group-composer)[ Packagist](https://packagist.org/packages/flyntwp/acf-field-group-composer)[ RSS](/packages/flyntwp-acf-field-group-composer/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (6)Dependencies (4)Versions (10)Used By (0)

acf-field-group-composer
========================

[](#acf-field-group-composer)

[![standard-readme compliant](https://camo.githubusercontent.com/4d148b38f9c13f71b15b80f0bd583698fd5a5ab9bd7dfe61d40e1e30aec35399/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f726561646d652532307374796c652d7374616e646172642d627269676874677265656e2e7376673f7374796c653d666c61742d737175617265)](https://github.com/RichardLitt/standard-readme)[![Build Status](https://camo.githubusercontent.com/c0520c9a1d6f489bd90a8490426a8a922d396eeca05e2394dca150e014095c34/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f666c796e7477702f6163662d6669656c642d67726f75702d636f6d706f7365722e7376673f7374796c653d666c61742d737175617265)](https://travis-ci.org/flyntwp/acf-field-group-composer)[![Code Quality](https://camo.githubusercontent.com/282d6ad612e6323effcd60637248e6aea24b9cbaa321f0410131c268afe7c6ce/68747470733a2f2f696d672e736869656c64732e696f2f7363727574696e697a65722f672f666c796e7477702f6163662d6669656c642d67726f75702d636f6d706f7365722e7376673f7374796c653d666c61742d737175617265)](https://scrutinizer-ci.com/g/flyntwp/acf-field-group-composer)[![Code Coverage](https://camo.githubusercontent.com/34bce23279222ee5fa23d9cfab8061207f7d9962003e0304539645bb9967f480/68747470733a2f2f696d672e736869656c64732e696f2f636f766572616c6c732f666c796e7477702f6163662d6669656c642d67726f75702d636f6d706f7365722e7376673f7374796c653d666c61742d737175617265)](https://coveralls.io/github/flyntwp/acf-field-group-composer)

> Configuration builder for advanced custom fields field groups

This plugin helps you create reusable ACF fields and field groups with code.

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

[](#table-of-contents)

- [Background](#background)
- [Install](#install)
- [Usage](#usage)
- [API](#api)
- [Maintainers](#maintainers)
- [Contribute](#contribute)
- [License](#license)

Background
----------

[](#background)

ACF provides a great interface to create custom meta boxes in WordPress. However, there are to major downsides using it out of the box:

1. Configuring ACF via its GUI can be cumbersome if you have a lot of custom fields. Also fields created via the GUI are only stored in the database. This means that migrating fields between different stages of a development setup can only be done by migrating the database as well.
2. The local JSON feature and `add_local_field_group` are handy for checking the config into SCM and deploying it to different environments, but it lacks some customizability, like reusing previously specified fields in different contexts.

The **acf-field-group-composer** helps circumventing these downsides. It let's you use the build-in `add_local_field_group` function, and automatically adds unique keys to all fields added. Plus, if a field is not an array but a string, it will apply a filter with that name and use the return value as a new field in the config.

Install
-------

[](#install)

TODO: install via WordPress instructions

To install via composer, run:

```
composer require flyntwp/acf-field-group-composer
```

Usage
-----

[](#usage)

To register a field group run:

```
ACFComposer\ACFComposer::registerFieldGroup($config);
```

The `$config` variable should be of the same format as the one you would pass to `acf_add_local_field_group`. There are only two things that are different:

1. You do not have to specify a `key` in any field or group.
2. A field group requires a unique `name` property.

Following the minimal example [from ACF](https://www.advancedcustomfields.com/resources/register-fields-via-php):

```
$config = [
  'name' => 'group1',
  'title' => 'My Group',
  'fields' => [
    [
      'label' => 'Subtitle',
      'name' => 'subtitle',
      'type' => 'text'
    ]
  ],
  'location' => [
    [
      [
      'param' => 'post_type',
      'operator' => '==',
      'value' => 'post'
      ]
    ]
  ]
];
```

In order to make use of the additional functionality of **acf-field-group-composer** you can extract the specified field and return it in a filter. The name of the filter can be anything, but we recommend a meaningful naming scheme. For example:

```
add_filter('MyProject/ACF/fields/field1', function ($field) {
  return [
    'label' => 'Subtitle',
    'name' => 'subtitle',
    'type' => 'text'
  ];
});

$config = [
  'name' => 'group1',
  'title' => 'My Group',
  'fields' => [
    'MyProject/ACF/fields/field1'
  ],
  'location' => [
    [
      [
      'param' => 'post_type',
      'operator' => '==',
      'value' => 'post'
      ]
    ]
  ]
];
```

The same can be done for the location:

```
add_filter('MyProject/ACF/locations/postTypePost', function ($location) {
  return [
    'param' => 'post_type',
    'operator' => '==',
    'value' => 'post'
  ];
});

$config = [
  'name' => 'group1',
  'title' => 'My Group',
  'fields' => [
    'MyProject/ACF/fields/field1'
  ],
  'location' => [
    [
      'MyProject/ACF/locations/postTypePost'
    ]
  ]
];
```

Combining the previous steps will yield the following result:

```
add_filter('MyProject/ACF/fields/field1', function ($field) {
  return [
    'label' => 'Subtitle',
    'name' => 'subtitle',
    'type' => 'text'
  ];
});

add_filter('MyProject/ACF/locations/postTypePost', function ($location) {
  return [
    'param' => 'post_type',
    'operator' => '==',
    'value' => 'post'
  ];
});

$config = [
  'name' => 'group1',
  'title' => 'My Group',
  'fields' => [
    'MyProject/ACF/fields/field1'
  ],
  'location' => [
    [
      'MyProject/ACF/locations/postTypePost'
    ]
  ]
];

ACFComposer\ACFComposer::registerFieldGroup($config);
```

Executing this code will add a field with the **name** `subtitle` to all posts. The **key** will be a combination of the field group name, all parent field names (if the field has parent fields), and the field's name itself. In this case, this is `field_group1_subtitle`.

### Filter arguments

[](#filter-arguments)

There is another caveat when working with reusable components in ACF. While the flexible content field from ACF Pro gives you everything you need for adding multiple components of the same type to one field group, this is not possible for regular field groups.

For example, if you define a set of fields for a simple WYSIWYG component and then want to add it to a field group multiple times, the result will be two Wysiwyg components being displayed, but each one would have the same name, and thus overwrite each other's data.

```
add_filter('MyProject/ACF/fields/wysiwyg', function ($field) {
  return [
    'label' => 'Content',
    'name' => 'content',
    'type' => 'wysiwyg'
  ];
});

$config = [
  'name' => 'group1',
  'title' => 'My Group',
  'fields' => [
    'MyProject/ACF/fields/wysiwyg',
    'MyProject/ACF/fields/wysiwyg'
  ],
  'location' => [
    [
      'MyProject/ACF/locations/postTypePost'
    ]
  ]
];

ACFComposer\ACFComposer::registerFieldGroup($config);
```

This can be fixed by adding a filter argument. All filter arguments must be appended with #. Once this is done, the respective filter will be called with the suffix as a second argument, and the field names will be prefixed with that string.

For example, taking the previous broken code an adding two unique filter names will resolve the problem:

```
add_filter('MyProject/ACF/fields/wysiwyg', function ($field, $componentName) {
  return [
    'label' => 'Content',
    'name' => 'content',
    'type' => 'wysiwyg'
  ];
}, 10, 2);

$config = [
  'name' => 'group1',
  'title' => 'My Group',
  'fields' => [
    'MyProject/ACF/fields/wysiwyg#firstWysiwyg',
    'MyProject/ACF/fields/wysiwyg#secondWysiwyg'
  ],
  'location' => [
    [
      'MyProject/ACF/locations/postTypePost'
    ]
  ]
];

ACFComposer\ACFComposer::registerFieldGroup($config);
```

As a result, the following two fields are added to all posts:

namekey`firstWysiwyg_content``field_group1_firstWysiwyg_content``secondWysiwyg_content``field_group1_secondWysiwyg_content`These field can be accessed as usual through the ACF functions `get_field()` and `get_fields()`.

### Conditional logic

[](#conditional-logic)

Conditional logic can be added to a field in the same way as in ACF. The exception is that we can pass `fieldPath` instead of `field`. The `fieldPath` must reference the name of a field defined in the same config:

```
{
  "label": "Show Content Field",
  "name": "showContentField",
  "type": "true_false"
},
{
  "label": "Content",
  "name": "contentHtml",
  "type": "wysiwyg",
  "conditional_logic": [
    [
      {
        "fieldPath": "showContentField",
        "operator": "==",
        "value": "1"
      }
    ]
  ]
}
```

To reference a field in conditional logic when inside a nested sub field (for example, in a repeater), the `fieldPath` must be passed relative to the current level. For example:

```
{
  "label": "Show Content Field",
  "name": "showContentField",
  "type": "true_false"
},
{
  "label": "Content Repeater",
  "name": "contentRepeater",
  "type": "repeater",
  "sub_fields": [
    {
      "label": "Content",
      "name": "contentHtml",
      "type": "wysiwyg",
      "conditional_logic": [
        [
          {
            "fieldPath": "../showContentField",
            "operator": "==",
            "value": "1"
          }
        ]
      ]
    }
  ]
}
```

API
---

[](#api)

### ACFComposer\\ACFComposer (class)

[](#acfcomposeracfcomposer-class)

#### registerFieldGroup (static)

[](#registerfieldgroup-static)

The main function of this package. Resolves a given field group config and registers an acf field group via `acf_add_local_field_group`.

```
public static function registerFieldGroup(array $config)
```

### ACFComposer\\ResolveConfig (class)

[](#acfcomposerresolveconfig-class)

#### forFieldGroup (static)

[](#forfieldgroup-static)

Validate and generate a field group config from a given config array by adding keys and replacing filter strings with actual content.

```
public static function forFieldGroup(array $config)
```

#### forField (static)

[](#forfield-static)

Validate and generate a field config from a given config array by adding keys and replacing filter strings with actual content.

```
public static function forField(array $config, array $parentKeys = [])
```

#### forLayout (static)

[](#forlayout-static)

Validate and generate a layout config from a given config array by adding keys and replacing filter strings with actual content.

```
public static function forLayout(array $config, array $parentKeys = [])
```

#### forLocation (static)

[](#forlocation-static)

Validate a location config from a given config array.

```
public static function forLocation(array $config)
```

Maintainers
-----------

[](#maintainers)

This project is maintained by [bleech](https://github.com/bleech).

The main people in charge of this repo are:

- [Dominik Tränklein](https://github.com/domtra)
- [Doğa Gürdal](https://github.com/Qakulukiam)

Contribute
----------

[](#contribute)

To contribute, please use GitHub [issues](https://github.com/flyntwp/acf-field-group-composer/issues). Pull requests are accepted. Please also take a moment to read the [Contributing Guidelines](https://github.com/flyntwp/guidelines/blob/master/CONTRIBUTING.md) and [Code of Conduct](https://github.com/flyntwp/guidelines/blob/master/CODE_OF_CONDUCT.md).

If editing the README, please conform to the [standard-readme](https://github.com/RichardLitt/standard-readme) specification.

License
-------

[](#license)

MIT © [bleech](https://www.bleech.de)

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity47

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 86.4% 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 ~494 days

Recently: every ~617 days

Total

6

Last Release

928d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/24416031?v=4)[Flynt – Component Based WordPress Development](/maintainers/flyntwp)[@flyntwp](https://github.com/flyntwp)

---

Top Contributors

[![domtra](https://avatars.githubusercontent.com/u/519908?v=4)](https://github.com/domtra "domtra (57 commits)")[![emcarru](https://avatars.githubusercontent.com/u/2886550?v=4)](https://github.com/emcarru "emcarru (2 commits)")[![vandebled](https://avatars.githubusercontent.com/u/1503670?v=4)](https://github.com/vandebled "vandebled (2 commits)")[![jGRUBBS](https://avatars.githubusercontent.com/u/338605?v=4)](https://github.com/jGRUBBS "jGRUBBS (1 commits)")[![maxduyck](https://avatars.githubusercontent.com/u/20770329?v=4)](https://github.com/maxduyck "maxduyck (1 commits)")[![thomasnavarro](https://avatars.githubusercontent.com/u/36193187?v=4)](https://github.com/thomasnavarro "thomasnavarro (1 commits)")[![usingthesystem](https://avatars.githubusercontent.com/u/1763263?v=4)](https://github.com/usingthesystem "usingthesystem (1 commits)")[![harunbleech](https://avatars.githubusercontent.com/u/52159349?v=4)](https://github.com/harunbleech "harunbleech (1 commits)")

---

Tags

acfadvanced-custom-fieldswordpress

###  Code Quality

TestsPHPUnit

Code StylePHP\_CodeSniffer

### Embed Badge

![Health badge](/badges/flyntwp-acf-field-group-composer/health.svg)

```
[![Health](https://phpackages.com/badges/flyntwp-acf-field-group-composer/health.svg)](https://phpackages.com/packages/flyntwp-acf-field-group-composer)
```

###  Alternatives

[helsingborg-stad/municipio

A bootstrap theme for creating municipality sites.

4028.5k10](/packages/helsingborg-stad-municipio)[mediawiki/maps

Adds various mapping features to MediaWiki

84152.3k3](/packages/mediawiki-maps)[starcitizentools/citizen-skin

A beautiful, usable, responsive MediaWiki skin with in-depth extension support. Originally developed for the Star Citizen Wiki.

3376.6k](/packages/starcitizentools-citizen-skin)[civicrm/civicrm-drupal-8

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

19251.4k3](/packages/civicrm-civicrm-drupal-8)[altis/core

Core module for Altis

19228.0k3](/packages/altis-core)[pfefferle/wordpress-activitypub

The ActivityPub protocol is a decentralized social networking protocol based upon the ActivityStreams 2.0 data format.

5721.7k4](/packages/pfefferle-wordpress-activitypub)

PHPackages © 2026

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