{"id":15626361,"url":"https://github.com/log1x/acf-composer","last_synced_at":"2025-05-14T08:06:16.571Z","repository":{"id":37276212,"uuid":"209605684","full_name":"Log1x/acf-composer","owner":"Log1x","description":"Compose ACF Fields, Blocks, Widgets, and Option Pages with ACF Builder on Sage 10.","archived":false,"fork":false,"pushed_at":"2025-05-07T18:31:10.000Z","size":349,"stargazers_count":454,"open_issues_count":7,"forks_count":62,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-07T19:17:18.834Z","etag":null,"topics":["acf","acf-block","acf-builder","acf-field","acorn","advanced-custom-fields","sage","sage-theme","sage10"],"latest_commit_sha":null,"homepage":"https://github.com/Log1x/acf-composer","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Log1x.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"Log1x"}},"created_at":"2019-09-19T16:55:26.000Z","updated_at":"2025-05-06T13:53:24.000Z","dependencies_parsed_at":"2023-11-17T00:05:39.085Z","dependency_job_id":"36b219f6-8333-42e3-81cf-4a11d4b40973","html_url":"https://github.com/Log1x/acf-composer","commit_stats":{"total_commits":236,"total_committers":36,"mean_commits":6.555555555555555,"dds":"0.22457627118644063","last_synced_commit":"6c22d9f83a44ad5df7a1423ac2f200b3ae5c0346"},"previous_names":[],"tags_count":98,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Log1x%2Facf-composer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Log1x%2Facf-composer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Log1x%2Facf-composer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Log1x%2Facf-composer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Log1x","download_url":"https://codeload.github.com/Log1x/acf-composer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101615,"owners_count":22014909,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acf","acf-block","acf-builder","acf-field","acorn","advanced-custom-fields","sage","sage-theme","sage10"],"created_at":"2024-10-03T10:12:05.945Z","updated_at":"2025-05-14T08:06:11.559Z","avatar_url":"https://github.com/Log1x.png","language":"PHP","funding_links":["https://github.com/sponsors/Log1x"],"categories":[],"sub_categories":[],"readme":"# ACF Composer\n\n![Latest Stable Version](https://img.shields.io/packagist/v/log1x/acf-composer.svg?style=flat-square)\n![Total Downloads](https://img.shields.io/packagist/dt/log1x/acf-composer.svg?style=flat-square)\n![Build Status](https://img.shields.io/github/actions/workflow/status/log1x/acf-composer/main.yml?branch=master\u0026style=flat-square)\n\nACF Composer is the ultimate tool for creating fields, blocks, widgets, and option pages using [ACF Builder](https://github.com/stoutlogic/acf-builder) alongside [Sage 10](https://github.com/roots/sage).\n\n![Screenshot](https://i.imgur.com/7e7w3U9.png)\n\n## Features\n\n- 🔧 Encourages clean structuring for creating fields with Sage 10 and ACF.\n- 🚀 Instantly generate working fields, blocks, widgets, partials, and option pages using CLI. Batteries included.\n- 🖼️ Fully rendered blocks and widgets using Blade with a native Sage 10 feel for passing view data.\n- ⚡ Seamlessly [cache](#caching-blocks--fields) blocks to `block.json` and field groups to a manifest.\n- 📦 Automatically hooks legacy widgets with `WP_Widget` making them instantly ready to use.\n- 🛠️ Automatically sets field location on blocks, widgets, and option pages.\n- 🌐 Globally define default field type and field group settings. No more repeating `['ui' =\u003e 1]` on every select field.\n\n## Requirements\n\n- [Sage](https://github.com/roots/sage) \u003e= 10.0\n- [Acorn](https://github.com/roots/acorn) \u003e= 3.0\n- [ACF Pro](https://www.advancedcustomfields.com/) \u003e= 5.8.0\n\n## Installation\n\nInstall via Composer:\n\n```bash\n$ composer require log1x/acf-composer\n```\n\n## Usage\n\n### Getting Started\n\nStart by publishing the `config/acf.php` configuration file using Acorn:\n\n```bash\n$ wp acorn vendor:publish --tag=\"acf-composer\"\n```\n\n### Generating a Field Group\n\nTo create your first field group, start by running the following generator command from your theme directory:\n\n```bash\n$ wp acorn acf:field ExampleField\n```\n\nThis will create `src/Fields/ExampleField.php` which is where you will create and manage your first field group.\n\nTaking a glance at the generated `ExampleField.php` stub, you will notice that it has a simple list configured.\n\n```php\n\u003c?php\n\nnamespace App\\Fields;\n\nuse Log1x\\AcfComposer\\Builder;\nuse Log1x\\AcfComposer\\Field;\n\nclass ExampleField extends Field\n{\n    /**\n     * The field group.\n     *\n     * @return array\n     */\n    public function fields()\n    {\n        $fields = Builder::make('example_field');\n\n        $fields\n            -\u003esetLocation('post_type', '==', 'post');\n\n        $fields\n            -\u003eaddRepeater('items')\n                -\u003eaddText('item')\n            -\u003eendRepeater();\n\n        return $fields-\u003ebuild();\n    }\n}\n```\n\nProceed by checking the `Add Post` for the field to ensure things are working as intended.\n\n### Field Builder Usage\n\nTo assist with development, ACF Composer comes with a `usage` command that will let you search for registered field types. This will provide basic information about the field type as well as a usage example containing all possible options.\n\n```sh\n$ wp acorn acf:usage\n```\n\nFor additional usage, you may consult the [ACF Builder Cheatsheet](https://github.com/Log1x/acf-builder-cheatsheet).\n\n### Generating a Field Partial\n\nA field partial consists of a field group that can be re-used and/or added to existing field groups.\n\nTo start, let's generate a partial called _ListItems_ that we can use in the _Example_ field we generated above.\n\n```bash\n$ wp acorn acf:partial ListItems\n```\n\n```php\n\u003c?php\n\nnamespace App\\Fields\\Partials;\n\nuse Log1x\\AcfComposer\\Builder;\nuse Log1x\\AcfComposer\\Partial;\n\nclass ListItems extends Partial\n{\n    /**\n     * The partial field group.\n     *\n     * @return array\n     */\n    public function fields()\n    {\n        $fields = Builder::make('listItems');\n\n        $fields\n            -\u003eaddRepeater('items')\n                -\u003eaddText('item')\n            -\u003eendRepeater();\n\n        return $fields;\n    }\n}\n```\n\nLooking at `ListItems.php`, you will see out of the box it consists of an identical list repeater as seen in your generated field.\n\nA key difference to note compared to an ordinary field is the omitting of `-\u003ebuild()` instead returning the `FieldsBuilder` instance itself.\n\nThis can be utilized in our _Example_ field by passing the `::class` constant to `-\u003eaddPartial()`:\n\n```php\n\u003c?php\n\nnamespace App\\Fields;\n\nuse App\\Fields\\Partials\\ListItems;\nuse Log1x\\AcfComposer\\Builder;\nuse Log1x\\AcfComposer\\Field;\n\nclass Example extends Field\n{\n    /**\n     * The field group.\n     *\n     * @return array\n     */\n    public function fields()\n    {\n        $fields = Builder::make('example');\n\n        $fields\n            -\u003esetLocation('post_type', '==', 'post');\n\n        $fields\n            -\u003eaddPartial(ListItems::class);\n\n        return $fields-\u003ebuild();\n    }\n}\n```\n\n### Generating a Block\n\nGenerating a block is generally the same as generating a field as seen above.\n\nStart by creating the block field using Acorn:\n\n```bash\n$ wp acorn acf:block ExampleBlock\n```\n\n```php\n\u003c?php\n\nnamespace App\\Blocks;\n\nuse Log1x\\AcfComposer\\Block;\nuse Log1x\\AcfComposer\\Builder;\n\nclass ExampleBlock extends Block\n{\n    /**\n     * The block name.\n     *\n     * @var string\n     */\n    public $name = 'Example Block';\n\n    /**\n     * The block description.\n     *\n     * @var string\n     */\n    public $description = 'Lorem ipsum...';\n\n    /**\n     * The block category.\n     *\n     * @var string\n     */\n    public $category = 'common';\n\n    /**\n     * The block icon.\n     *\n     * @var string|array\n     */\n    public $icon = 'star-half';\n\n    /**\n     * Data to be passed to the block before rendering.\n     *\n     * @return array\n     */\n    public function with()\n    {\n        return [\n            'items' =\u003e $this-\u003eitems(),\n        ];\n    }\n\n    /**\n     * The block field group.\n     *\n     * @return array\n     */\n    public function fields()\n    {\n        $fields = Builder::make('example_block');\n\n        $fields\n            -\u003eaddRepeater('items')\n                -\u003eaddText('item')\n            -\u003eendRepeater();\n\n        return $fields-\u003ebuild();\n    }\n\n    /**\n     * Return the items field.\n     *\n     * @return array\n     */\n    public function items()\n    {\n        return get_field('items') ?: [];\n    }\n}\n```\n\nYou may also pass `--localize` to the command above to generate a block stub with the name and description ready for translation.\n\n```bash\n$ wp acorn acf:block Example --localize\n```\n\nWhen running the block generator, one difference to a generic field is an accompanied `View` is generated in the `resources/views/blocks` directory.\n\n```php\n@if ($items)\n  \u003cul\u003e\n    @foreach ($items as $item)\n      \u003cli\u003e{{ $item['item'] }}\u003c/li\u003e\n    @endforeach\n  \u003c/ul\u003e\n@else\n  \u003cp\u003eNo items found!\u003c/p\u003e\n@endif\n\n\u003cdiv\u003e\n  \u003cInnerBlocks /\u003e\n\u003c/div\u003e\n```\n\nLike the field generator, the example block contains a simple list repeater and is working out of the box.\n\n#### Block Preview View\n\nWhile `$block-\u003epreview` is an option for conditionally modifying your block when shown in the editor, you may also render your block using a seperate view.\n\nSimply duplicate your existing view prefixing it with `preview-` (e.g. `preview-example.blade.php`).\n\n### Generating a Widget\n\n\u003e [!IMPORTANT]\n\u003e With WordPress 5.8, Blocks can now be used as widgets making this feature somewhat deprecated as you would just make a block instead.\n\u003e\n\u003e If you are on the latest WordPress and would like to use the classic widget functionality from ACF Composer, you will need to [opt-out of the widget block editor](https://developer.wordpress.org/block-editor/how-to-guides/widgets/opting-out/).\n\nCreating a sidebar widget using ACF Composer is extremely easy. Widgets are automatically loaded and rendered with Blade, as well as registered with `WP_Widget` which is usually rather annoying.\n\nStart by creating a widget using Acorn:\n\n```bash\n$ wp acorn acf:widget ExampleWidget\n```\n\n```php\n\u003c?php\n\nnamespace App\\Widgets;\n\nuse Log1x\\AcfComposer\\Builder;\nuse Log1x\\AcfComposer\\Widget;\n\nclass ExampleWidget extends Widget\n{\n    /**\n     * The widget name.\n     *\n     * @var string\n     */\n    public $name = 'Example Widget';\n\n    /**\n     * The widget description.\n     *\n     * @var string\n     */\n    public $description = 'Lorem ipsum...';\n\n    /**\n     * Data to be passed to the widget before rendering.\n     *\n     * @return array\n     */\n    public function with()\n    {\n        return [\n            'items' =\u003e $this-\u003eitems(),\n        ];\n    }\n\n    /**\n     * The widget title.\n     *\n     * @return string\n     */\n    public function title() {\n        return get_field('title', $this-\u003ewidget-\u003eid);\n    }\n\n    /**\n     * The widget field group.\n     *\n     * @return array\n     */\n    public function fields()\n    {\n        $fields = Builder::make('example_widget');\n\n        $fields\n            -\u003eaddText('title');\n\n        $fields\n            -\u003eaddRepeater('items')\n                -\u003eaddText('item')\n            -\u003eendRepeater();\n\n        return $fields-\u003ebuild();\n    }\n\n    /**\n     * Return the items field.\n     *\n     * @return array\n     */\n    public function items()\n    {\n        return get_field('items', $this-\u003ewidget-\u003eid) ?: [];\n    }\n}\n```\n\nSimilar to blocks, widgets are also accompanied by a view generated in `resources/views/widgets`.\n\n```php\n@if ($items)\n  \u003cul\u003e\n    @foreach ($items as $item)\n      \u003cli\u003e{{ $item['item'] }}\u003c/li\u003e\n    @endforeach\n  \u003c/ul\u003e\n@else\n  \u003cp\u003eNo items found!\u003c/p\u003e\n@endif\n```\n\nOut of the box, the Example widget is ready to go and should appear in the backend.\n\n### Generating an Options Page\n\nCreating an options page is similar to creating a regular field group in additional to a few configuration options available to customize the page (most of which, are optional.)\n\nStart by creating an option page using Acorn:\n\n```bash\n$ wp acorn acf:options ExampleOptions\n```\n\n```php\n\u003c?php\n\nnamespace App\\Options;\n\nuse Log1x\\AcfComposer\\Builder;\nuse Log1x\\AcfComposer\\Options as Field;\n\nclass ExampleOptions extends Field\n{\n    /**\n     * The option page menu name.\n     *\n     * @var string\n     */\n    public $name = 'Example Options';\n\n    /**\n     * The option page document title.\n     *\n     * @var string\n     */\n    public $title = 'Example Options | Options';\n\n    /**\n     * The option page field group.\n     *\n     * @return array\n     */\n    public function fields()\n    {\n        $fields = Builder::make('example_options');\n\n        $fields\n            -\u003eaddRepeater('items')\n                -\u003eaddText('item')\n            -\u003eendRepeater();\n\n        return $fields-\u003ebuild();\n    }\n}\n```\n\nOptionally, you may pass `--full` to the command above to generate a stub that contains additional configuration examples.\n\n```bash\n$ wp acorn acf:options Options --full\n```\n\nOnce finished, you should see an Options page appear in the backend.\n\nAll fields registered will have their location automatically set to this page.\n\n## Caching Blocks \u0026 Fields\n\nAs of v3, ACF Composer now has the ability to cache registered blocks to native `block.json` files and field groups to a flat file JSON manifest automatically using CLI.\n\nThis can lead to a **dramatic increase** in performance in projects both small and large, especially when loading a post in the editor containing multiple custom blocks.\n\n\u003e [!NOTE]\n\u003e Making changes to blocks or fields once cached will not take effect until cleared or re-cached.\n\nThe best time to do this is during deployment and can be done using the `acf:cache` command:\n\n```bash\n$ wp acorn acf:cache [--status]\n```\n\nCache can then be cleared using the `acf:clear` command:\n\n```bash\n$ wp acorn acf:clear\n```\n\nThe ACF Composer cache status can be found using `--status` on `acf:cache` as seen above or by running `wp acorn about`.\n\n## Custom Stub Generation\n\nTo customize the stubs generated by ACF Composer, you can easily publish the `stubs` directory using Acorn:\n\n```bash\n$ wp acorn acf:stubs\n```\n\nThe publish command generates all available stubs by default. However, each stub file is optional. When a stub file doesn't exist in the `stubs/acf-composer` directory, the default stub provided by the package will be used.\n\n## Default Field Settings\n\nA useful feature unique to ACF Composer is the ability to set field type as well as field group defaults. Any globally set default can of course be over-ridden by simply setting it on the individual field.\n\n### Global\n\nTaking a look at `config/acf.php`, you will see a few pre-configured defaults:\n\n```php\n'defaults' =\u003e [\n    'trueFalse' =\u003e ['ui' =\u003e 1],\n    'select' =\u003e ['ui' =\u003e 1],\n],\n```\n\nWhen setting `trueFalse` and `select` to have their `ui` set to `1` by default, it is no longer necessary to repeatedly set `'ui' =\u003e 1` on your fields. This takes effect globally and can be overridden by simply setting a different value on a field.\n\n### Field Group\n\nIt is also possible to define defaults on individual field groups. This is done by simply defining `$defaults` in your field class.\n\n```php\n/**\n * Default field type settings.\n *\n * @return array\n */\nprotected $defaults = ['ui' =\u003e 0];\n```\n\n### My Defaults\n\nHere are a couple defaults I personally use. Any prefixed with `acfe_` are related to [ACF Extended](https://www.acf-extended.com/).\n\n```php\n'defaults' =\u003e [\n    'fieldGroup' =\u003e ['instruction_placement' =\u003e 'acfe_instructions_tooltip'],\n    'repeater' =\u003e ['layout' =\u003e 'block', 'acfe_repeater_stylised_button' =\u003e 1],\n    'trueFalse' =\u003e ['ui' =\u003e 1],\n    'select' =\u003e ['ui' =\u003e 1],\n    'postObject' =\u003e ['ui' =\u003e 1, 'return_format' =\u003e 'object'],\n    'accordion' =\u003e ['multi_expand' =\u003e 1],\n    'group' =\u003e ['layout' =\u003e 'table', 'acfe_group_modal' =\u003e 1],\n    'tab' =\u003e ['placement' =\u003e 'left'],\n    'sidebar_selector' =\u003e ['default_value' =\u003e 'sidebar-primary', 'allow_null' =\u003e 1]\n],\n```\n\n## Bug Reports\n\nIf you discover a bug in ACF Composer, please [open an issue](https://github.com/log1x/acf-composer/issues).\n\n## Contributing\n\nContributing whether it be through PRs, reporting an issue, or suggesting an idea is encouraged and appreciated.\n\n## License\n\nACF Composer is provided under the [MIT License](LICENSE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flog1x%2Facf-composer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flog1x%2Facf-composer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flog1x%2Facf-composer/lists"}