Giter Club home page Giter Club logo

acf-composer's Introduction

ACF Composer

Latest Stable Version Total Downloads Build Status

ACF Composer is the ultimate tool for creating fields, blocks, widgets, and option pages using ACF Builder alongside Sage 10.

Screenshot

Features

  • 🔧 Encourages clean structuring for creating fields with Sage 10 and ACF.
  • 🚀 Instantly generate working fields, blocks, widgets, partials, and option pages using CLI. Batteries included.
  • 🖼️ Fully rendered blocks and widgets using Blade with a native Sage 10 feel for passing view data.
  • ⚡ Seamlessly cache blocks to block.json and field groups to a manifest.
  • 📦 Automatically hooks legacy widgets with WP_Widget making them instantly ready to use.
  • 🛠️ Automatically sets field location on blocks, widgets, and option pages.
  • 🌐 Globally define default field type and field group settings. No more repeating ['ui' => 1] on every select field.

Requirements

Installation

Install via Composer:

$ composer require log1x/acf-composer

Usage

Getting Started

Start by publishing the config/acf.php configuration file using Acorn:

$ wp acorn vendor:publish --tag="acf-composer"

Generating a Field Group

To create your first field group, start by running the following generator command from your theme directory:

$ wp acorn acf:field Example

This will create src/Fields/Example.php which is where you will create and manage your first field group.

Taking a glance at the generated Example.php stub, you will notice that it has a simple list configured.

<?php

namespace App\Fields;

use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Field;

class Example extends Field
{
    /**
     * The field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = Builder::make('example');

        $example
            ->setLocation('post_type', '==', 'post');

        $example
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $example->build();
    }
}

Proceed by checking the Add Post for the field to ensure things are working as intended – and then get to work.

Generating a Field Partial

A field partial consists of a field group that can be re-used and/or added to existing field groups.

To start, let's generate a partial called ListItems that we can use in the Example field we generated above.

$ wp acorn acf:partial ListItems
<?php

namespace App\Fields\Partials;

use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Partial;

class ListItems extends Partial
{
    /**
     * The partial field group.
     *
     * @return array
     */
    public function fields()
    {
        $listItems = Builder::make('listItems');

        $listItems
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $listItems;
    }
}

Looking at ListItems.php, you will see out of the box it consists of an identical list repeater as seen in your generated field.

A key difference to note compared to an ordinary field is the omitting of ->build() instead returning the FieldsBuilder instance itself.

This can be utilized in our Example field by passing the ::class constant to ->addPartial():

<?php

namespace App\Fields;

use App\Fields\Partials\ListItems;
use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Field;

class Example extends Field
{
    /**
     * The field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = Builder::make('example');

        $example
            ->setLocation('post_type', '==', 'post');

        $example
            ->addPartial(ListItems::class);

        return $example->build();
    }
}

Generating a Block

Generating a block is generally the same as generating a field as seen above.

Start by creating the block field using Acorn:

$ wp acorn acf:block Example
<?php

namespace App\Blocks;

use Log1x\AcfComposer\Block;
use Log1x\AcfComposer\Builder;

class Example extends Block
{
    /**
     * The block name.
     *
     * @var string
     */
    public $name = 'Example';

    /**
     * The block description.
     *
     * @var string
     */
    public $description = 'Lorem ipsum...';

    /**
     * The block category.
     *
     * @var string
     */
    public $category = 'common';

    /**
     * The block icon.
     *
     * @var string|array
     */
    public $icon = 'star-half';

    /**
     * Data to be passed to the block before rendering.
     *
     * @return array
     */
    public function with()
    {
        return [
            'items' => $this->items(),
        ];
    }

    /**
     * The block field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = Builder::make('example');

        $example
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $example->build();
    }

    /**
     * Return the items field.
     *
     * @return array
     */
    public function items()
    {
        return get_field('items') ?: [];
    }
}

You may also pass --construct to the command above to generate a stub with the block properties set within an attributes method. This can be useful for localization, etc.

$ wp acorn acf:block Example --construct

When running the block generator, one difference to a generic field is an accompanied View is generated in the resources/views/blocks directory.

@if ($items)
  <ul>
    @foreach ($items as $item)
      <li>{{ $item['item'] }}</li>
    @endforeach
  </ul>
@else
  <p>No items found!</p>
@endif

<div>
  <InnerBlocks />
</div>

Like the field generator, the example block contains a simple list repeater and is working out of the box.

Block Preview View

While $block->preview is an option for conditionally modifying your block when shown in the editor, you may also render your block using a seperate view.

Simply duplicate your existing view prefixing it with preview- (e.g. preview-example.blade.php).

Generating a Widget

Important

With WordPress 5.8, Blocks can now be used as widgets making this feature somewhat deprecated as you would just make a block instead.

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.

Creating 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.

Start by creating a widget using Acorn:

$ wp acorn acf:widget Example
<?php

namespace App\Widgets;

use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Widget;

class Example extends Widget
{
    /**
     * The widget name.
     *
     * @var string
     */
    public $name = 'Example';

    /**
     * The widget description.
     *
     * @var string
     */
    public $description = 'Lorem ipsum...';

    /**
     * Data to be passed to the widget before rendering.
     *
     * @return array
     */
    public function with()
    {
        return [
            'items' => $this->items(),
        ];
    }

    /**
     * The widget title.
     *
     * @return string
     */
    public function title() {
        return get_field('title', $this->widget->id);
    }

    /**
     * The widget field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = Builder::make('example');

        $example
            ->addText('title');

        $example
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $example->build();
    }

    /**
     * Return the items field.
     *
     * @return array
     */
    public function items()
    {
        return get_field('items', $this->widget->id) ?: [];
    }
}

Similar to blocks, widgets are also accompanied by a view generated in resources/views/widgets.

@if ($items)
  <ul>
    @foreach ($items as $item)
      <li>{{ $item['item'] }}</li>
    @endforeach
  </ul>
@else
  <p>No items found!</p>
@endif

Out of the box, the Example widget is ready to go and should appear in the backend.

Generating an Options Page

Creating 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.)

Start by creating an option page using Acorn:

$ wp acorn acf:options Example
<?php

namespace App\Options;

use Log1x\AcfComposer\Builder;
use Log1x\AcfComposer\Options as Field;

class Example extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Example';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Example | Options';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = Builder::make('example');

        $example
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $example->build();
    }
}

Optionally, you may pass --full to the command above to generate a stub that contains additional configuration examples.

$ wp acorn acf:options Options --full

Once finished, you should see an Options page appear in the backend.

All fields registered will have their location automatically set to this page.

Caching Blocks & Fields

As 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.

This 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.

Note

Making changes to blocks or fields once cached will not take effect until cleared or re-cached.

The best time to do this is during deployment and can be done using the acf:cache command:

$ wp acorn acf:cache [--status]

Cache can then be cleared using the acf:clear command:

$ wp acorn acf:clear

The ACF Composer cache status can be found using --status on acf:cache as seen above or by running wp acorn about.

Custom Stub Generation

To customize the stubs generated by ACF Composer, you can easily publish the stubs directory using Acorn:

$ wp acorn acf:stubs

The 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.

Default Field Settings

One of my personal favorite features of 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.

Global

Taking a look at config/acf.php, you will see a few pre-configured defaults:

'defaults' => [
    'trueFalse' => ['ui' => 1],
    'select' => ['ui' => 1],
],

When setting trueFalse and select to have their ui set to 1 by default, it is no longer necessary to repeatedly set 'ui' => 1 on your fields. This takes effect globally and can be overridden by simply setting a different value on a field.

Field Group

It is also possible to define defaults on individual field groups. This is done by simply defining $defaults in your field class.

/**
 * Default field type settings.
 *
 * @return array
 */
protected $defaults = ['ui' => 0];

My Defaults

Here are a couple defaults I personally use. Any prefixed with acfe_ are related to ACF Extended.

'defaults' => [
    'fieldGroup' => ['instruction_placement' => 'acfe_instructions_tooltip'],
    'repeater' => ['layout' => 'block', 'acfe_repeater_stylised_button' => 1],
    'trueFalse' => ['ui' => 1],
    'select' => ['ui' => 1],
    'postObject' => ['ui' => 1, 'return_format' => 'object'],
    'accordion' => ['multi_expand' => 1],
    'group' => ['layout' => 'table', 'acfe_group_modal' => 1],
    'tab' => ['placement' => 'left'],
    'sidebar_selector' => ['default_value' => 'sidebar-primary', 'allow_null' => 1]
],

Bug Reports

If you discover a bug in ACF Composer, please open an issue.

Contributing

Contributing whether it be through PRs, reporting an issue, or suggesting an idea is encouraged and appreciated.

License

ACF Composer is provided under the MIT License.

acf-composer's People

Contributors

alwaysblank avatar androlax2 avatar aon21 avatar broskees avatar chrillep avatar davideprevosto avatar djaevlen avatar dsturm avatar galatanovidiu avatar gianlucacesari avatar huubl avatar jellycode avatar johanmolen avatar joshuafredrickson avatar juvojustin avatar kupoback avatar log1x avatar lucasdemea avatar marcbelletre avatar marijoo avatar mike-sheppard avatar mrmadhat avatar noonanwebgroup avatar pauguri avatar rleecrewmp avatar sanderdv avatar themosaad avatar twansparant avatar tylerwiegand avatar valeriomonti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

acf-composer's Issues

$block data

Hi,

I can get $block->classes and $block->align, but can't get $block->id. Shouldn't it be available?

Composer incorrectly resolving paths on Windows

Hey there, firstly thanks for this awesome package! I installed it, generated an example block and field as per the docs and I didn't see it being registered on the site. I spent a couple of hours scratching my head and wondered what I was doing wrong. I checked out the docs multiple times to see if there was something I was missing, but apparently not.

As I jumped into the source code, I realised that the composer was incorrectly resolving the path for Windows. It seems as though AcfComposer.php:95 is the issue. Rather than searching for the string '/' you could replace it with DIRECTORY_SEPARATOR to get the correct separator for that OS. After changing it, blocks and fields were registering perfectly.

Options: children

Hello,

I would like to organize our ACF Pro options pages in a simple tree, using the parent functionality:

-- Sections (without fields)
---- First Option (with fields)
---- Second Option (with fields)

Unfortunately it seems something wrong, the generated links are:

https://test.lndo.site/wp-admin/admin.php?page=first (right)
https://test.lndo.site/wp-admin/second (wrong, 404. It should be https://test.lndo.site/wp-admin/admin.php?page=second)

image

I have created a brand new Sage 10 project, excluding any other plugin or custom code, I have just used wp acorn commands.

Sections.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Sections extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Sections';

    /**
     * The option page menu slug.
     *
     * @var string
     */
    public $slug = 'sections';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Sections | Options';

    /**
     * The option page permission capability.
     *
     * @var string
     */
    public $capability = 'edit_theme_options';

    /**
     * The option page menu position.
     *
     * @var int
     */
    public $position = PHP_INT_MAX;

    /**
     * The slug of another admin page to be used as a parent.
     *
     * @var string
     */
    public $parent = null;

    /**
     * The option page menu icon.
     *
     * @var string
     */
    public $icon = null;

    /**
     * Redirect to the first child page if one exists.
     *
     * @var boolean
     */
    public $redirect = true;

    /**
     * The post ID to save and load values from.
     *
     * @var string|int
     */
    public $post = 'options';

    /**
     * The option page autoload setting.
     *
     * @var bool
     */
    public $autoload = true;

    /**
     * Localized text displayed on the submit button.
     *
     * @return string
     */
    public function updateButton()
    {
        return __('Update', 'acf');
    }

    /**
     * Localized text displayed after form submission.
     *
     * @return string
     */
    public function updatedMessage()
    {
        return __('Sections Updated', 'acf');
    }

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
    }
}

First.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class First extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'First';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'First | Options';

    /**
     * @var string
     */
    public $parent = 'sections';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $first = new FieldsBuilder('first');

        $first
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $first->build();
    }
}

Second.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Second extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Second';

    /**
     * The option page menu slug.
     *
     * @var string
     */
    public $slug = 'second';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Second | Options';

    /**
     * The option page permission capability.
     *
     * @var string
     */
    public $capability = 'edit_theme_options';

    /**
     * The option page menu position.
     *
     * @var int
     */
    public $position = PHP_INT_MAX;

    /**
     * The slug of another admin page to be used as a parent.
     *
     * @var string
     */
    public $parent = 'sections';

    /**
     * The option page menu icon.
     *
     * @var string
     */
    public $icon = null;

    /**
     * Redirect to the first child page if one exists.
     *
     * @var boolean
     */
    public $redirect = true;

    /**
     * The post ID to save and load values from.
     *
     * @var string|int
     */
    public $post = 'options';

    /**
     * The option page autoload setting.
     *
     * @var bool
     */
    public $autoload = true;

    /**
     * Localized text displayed on the submit button.
     *
     * @return string
     */
    public function updateButton()
    {
        return __('Update', 'acf');
    }

    /**
     * Localized text displayed after form submission.
     *
     * @return string
     */
    public function updatedMessage()
    {
        return __('Second Updated', 'acf');
    }

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $second = new FieldsBuilder('second');

        $second
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $second->build();
    }
}

Is anyone experiencing the same issue?

Thank you!

Add-ons support?

Hi there,

Great plugin! Can't wait to use it in every project now.
I've got one simple question though, if you're using any 3rd party add-on, like for instance the Font Awesome Field.

How would I add a field for that with your builder?
I can see the field type for that is font-awesome, but using addFontAwesome does not work:

->addFontAwesome('icon', [
	'label'           => 'Icon',
	'instructions'    => 'Select an icon',
	'required'        => 1,
	'save_format'     => 'class',
	'allow_null'      => 0,
	'show_preview'    => 1,
	'enqueue_fa'      => 1,
	'fa_live_preview' => ''
])

and results in an error:

"No such function: addFontAwesome"

Do I need to define this somewhere?
Thanks a lot!

Wrong case slug

@Log1x

I found that the slug generates invalid when creating a new block with 'multiple words':

wp acorn acf:block TestBlock --construct

$this->slug = 'DummySnake';

Results in test_block.

I tried replacing DummySnake with DummySlug, which gives: testblock. This works, but I think adding it as test-block is beter.

I found that DummyKebab isn't present in Acorn.

I'm not sure if this required changes in Acorn or can be done an other way. What do you think?

Require fails, if "doctrine/inflector":"^2.0"

Hi Brandon,

using a new roots/sage install, composer installs "doctrine/inflector":"2.0.1". Therefor the installation fails, since stoutlogic/acf-builder requires "doctrine/inflector": "^1.1". Should this package require "doctrine/inflector": "^1.4" until stoutlogic/acf-builder is compatible with "doctrine/inflector":"^2.0"?

Best,
Daniel

Problem with field partials

Hey @Log1x really appreciate all the libraries you've put together for roots/sage.

I'm having an issue where Partial fields aren't being included. Probably something silly my side, but I've tried the example a bunch of times with no luck yet.


Steps to reproduce

$ wp acorn acf:block Example
$ wp acorn acf:partial ExampleListItems

./app/Blocks/Example.php

namespace App\Blocks;

use Log1x\AcfComposer\Block;
use StoutLogic\AcfBuilder\FieldsBuilder;
use App\Fields\Partials\ExampleListItems;


class Example extends Block
{
    /**
     * The block name.
     *
     * @var string
     */
    public $name = 'Example';

    /**
     * The block description.
     *
     * @var string
     */
    public $description = 'Lorem ipsum...';

    /**
     * The block category.
     *
     * @var string
     */
    public $category = 'common';

    /**
     * The block icon.
     *
     * @var string|array
     */
    public $icon = 'star-half';

    /**
     * Data to be passed to the block before rendering.
     *
     * @return array
     */
    public function with()
    {
        return [
            'items' => $this->items(),
        ];
    }

    /**
     * The block field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = new FieldsBuilder('example');

        $example
        ->addText('test')
        ->addFields(ExampleListItems::class);

        return $example->build();
    }

    /**
     * Return the items field.
     *
     * @return array
     */
    public function items()
    {
        return get_field('items') ?: [];
    }
}

./app/Fields/Partials/ExampleListItems.php

namespace App\Fields\Partials;

use Log1x\AcfComposer\Partial;

class ExampleListItems extends Partial
{
    /**
     * The partial field group.
     *
     * @return array
     */
    public function fields()
    {
        $exampleListItems = new FieldsBuilder('example_list_items');

        $exampleListItems
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $exampleListItems;
    }
}

Note: using the standard StoutLogic\AcfBuilder\FieldsBuilder way works ok ie.

$exampleListItems = new FieldsBuilder('list_items');

$listItems
    ->addRepeater('items')
        ->addText('item')
    ->endRepeater();

$example
    ->addText('test')
    ->addFields($listItems);

Problem after update ACF to version 5.11 - get_field() return null

After the last update of ACF PRO to version 5.11, there was a problem with reading the fields.
I cannot read the values ​​of some fields. The return is NULL.

example in functions.php

$account_page = (is_array($account_page)) ? $account_page['url'] : $home_url;
define('ACCOUNT_PAGE', $account_page);

The same is the case with the php script that handles the form

session_start();

include 'vendor/autoload.php';
use Hybridauth\Hybridauth;

$google_login = (get_field('google-login-api', 'option')) ?? null;

How to fix this in acf-composer?

Issue in ACF GH - get_field returns null after upgrading to v5.11 · Issue #570 · AdvancedCustomFields/acf

I tried to change the priority in the register() function on acf composer, but unfortunately to no avail.

$loop variable not working

Hi,

It seem like the $loop variable isn't available. I can't figure out why, shouldn't it be available?

@if ($items)
  <ul>
    @foreach ($items as $item)
      {{$loop->count}}
    @endforeach
  </ul>
@else
  <p>No items found!</p>
@endif

Poet with ACF Composer Block Category Issues

Using Poet to register items and custom block categories on v2.0.0

Block categories looks like:

'block_categories' => [
    'customer_blocks' => [
        'title' => 'Customer Blocks',
        'icon' => 'star-filled',
    ],
],

In ACF Composer v2.0.2 the blocks I've created have this defined under the category variable:

/**
* The block category.
*
* @var string
*/
public $category = 'customer_blocks';

However everything just shows up under the text block category in the WordPress (5.6.2) admin. The other items from poet register properly so I'm probably missing something in translation here. Any thoughts?

Using with a custom plugin for a multisite install

I'm building a WP multisite for a client on top of Sage 10. They'll have some common ACF fields,and views but also some that are site specific. Is there a way to get this to work so I can load via a plugin instead of sage theme dirs? Ideally I'd like to have plugins that are activate per site to give that site its specific functionality but I'm having a hard time figuring out best way to do that with ACFBuilder and composers. Hoping this plugin will actually help if I can sort things out.

Moving fields to visual editor...

So, basically, all I'm trying to do is put some of the fields in the visual editor instead of all of them in the sidebar. I know it's possible out of the box with ACF (latest), but for some reason I'm not sure what option needs to be put where to get this functionality with this repo.

https://ibb.co/MkQDZs7

In the above screenshot, where it says "Main Alert" under the heading of "Test". I want to move the fields there. Here's the code (What am I missing?):

<?php
 
namespace App\Blocks;
 
use Log1x\AcfComposer\Block;
use StoutLogic\AcfBuilder\FieldsBuilder;
 
class Alert extends Block
{
    /**
     * The block name.
     *
     * @var string
     */
    public $name = 'Alert';
 
    /**
     * The block description.
     *
     * @var string
     */
    public $description = 'A custom alert box that utilizes Bootstrap 5 components.';
 
    /**
     * The block category.
     *
     * @var string
     */
    public $category = 'vpm-block-category';
 
    /**
     * The block icon.
     *
     * @var string|array
     */
    public $icon = 'info-outline';
 
    /**
     * The block keywords.
     *
     * @var array
     */
    public $keywords = ['alert', 'alertbox' ];
 
    /**
     * The block post type allow list.
     *
     * @var array
     */
    public $post_types = [];
 
    /**
     * The parent block type allow list.
     *
     * @var array
     */
    public $parent = [];
 
    /**
     * The default block mode.
     *
     * @var string
     */
    public $mode = 'preview';
 
    /**
     * The default block alignment.
     *
     * @var string
     */
    public $align = '';
 
    /**
     * The default block text alignment.
     *
     * @var string
     */
    public $align_text = '';
 
    /**
     * The default block content alignment.
     *
     * @var string
     */
    public $align_content = '';
 
    /**
     * The supported block features.
     *
     * @var array
     */
    public $supports = [
        'align' => false,
        'align_text' => false,
        'align_content' => false,
        'anchor' => false,
        'mode' => false,
        'multiple' => true,
        'jsx' => true,
    ];
 
    /**
     * The block styles.
     *
     * @var array
     */
    public $styles = [];
 
    /**
     * The block preview example data.
     *
     * @var array
     */
    public $example = [
        // 'title' => 'Alert Title',
        // 'additional_content' => "Some additional content",
        // 'alert_type' => 'alert-primary',
        // 'is_dismissible' => true
    ];
 
    /**
     * Data to be passed to the block before rendering.
     *
     * @return array
     */
    public function with()
    {
        return [
            // 'title' => $this->title(),
            // 'additional_content' => $this->additional_content(),
            // 'alert_type' => $this->alert_type(),
            // 'is_dismissible' => $this->is_dismissible()
        ];
    }
 
    /**
     * The block field group.
     *
     * @return array
     */
    public function fields()
    {
        $alert = new FieldsBuilder('alert');
 
        $alert->addText('title', [
            'label' => 'Alert Title',
            'instructions' => '',
            'required' => 1,
            'default_value' => '',
            'placeholder' => 'Untitled',
            'prepend' => '',
            'append' => '',
            'maxlength' => '',
        ]);
        $alert->addWysiwyg('additional_content', [
            'label' => 'Additional Content',
            'instructions' => 'You can supply additional content below the alert title by entering it into this field. <a href="https://getbootstrap.com/docs/5.0/components/alerts/#additional-content" target="_blank">More Information.</a>',
            'required' => 0,
            // 'conditional_logic' => 0,
            'default_value' => '',
            'tabs' => 'all',
            'toolbar' => 'full',
            'media_upload' => 1,
            'delay' => 0,
        ]);
 
 
        $alert->addSelect('alert_type', [
            'label' => 'Alert Type',
            'instructions' => 'These options correspond to the Bootstrap 5 alert options. <a href="https://getbootstrap.com/docs/5.0/components/alerts/#examples" target="_blank">Alert Examples</a>.',
            'required' => 1,
            // 'conditional_logic' => 0,
            'choices' => [
                "alert-primary" => "Primary Alert",
                "alert-secondary" => "Secondary Alert",
                "alert-success" => "Success Alert",
                "alert-danger" => "Danger Alert",
                "alert-warning" => "Warning Alert",
                "alert-info" => "Informational Alert",
                "alert-light" => "Light Alert",
                "alert-dark" => "Dark Alert",
            ],
            'default_value' => ["alert-primary"],
            'allow_null' => 0,
            'multiple' => 0,
            'ui' => 1,
            'ajax' => 0,
            'return_format' => 'value',
            'placeholder' => '',  
        ]);
        $alert->addTrueFalse('is_dismissable', [
            'label' => 'Is Dismissable?',
            'instructions' => 'Check this box to allow for dismissing the alert box. <a href="https://getbootstrap.com/docs/5.0/components/alerts/#dismissing" target="_blank">For more information.</a>',
            'required' => 0,
            // 'conditional_logic' => 0,
            'message' => '',
            'default_value' => 0,
            'ui' => 0,
            'ui_on_text' => '',
            'ui_off_text' => '',
        ]);
 
        $alert->setLocation('post_type', '==', 'page')->or('post_type', '==', 'post');
 
        $alert->setGroupConfig('position', 'normal');
                // dd($alert->build());
        return $alert->build();
    }
 
    /**
     * Return the items field.
     *
     * @return array
     */
    public function title()
    {
        return get_field('title') ?: 'Alert';
    }
 
    public function additional_content()
    {
        return get_field('additional_content') ?: 'Additional content for this alert...';
    }
 
    public function alert_type()
    {
        return get_field('alert_type') ?: 'alert-primary';
    }
 
    public function is_dismissable()
    {
        return get_field('is_dismissable') ?: true;
    }
 
    /**
     * Assets to be enqueued when rendering the block.
     *
     * @return void
     */
    public function enqueue()
    {
        //
    }
}

Running yarn build:production breaks gutenberg preview width

Brandon if I run a yarn build, the gutenberg container is correct at the fixed size I've created for the block eg:

.wp-block {
  max-width: 896px;
}

Screenshot 2021-02-24 at 23 44 43

but when I run a yarn production:build, I'm only getting container width of 580px - any ideas why this might happen?

Screenshot 2021-02-24 at 23 44 07

(FYI its Sage 10)

Thanks,

Fabian

Add Support + Compatibility with experimental JSX blocks

https://www.advancedcustomfields.com/blog/acf-5-9-exciting-new-features/#InnerBlocks

Edit: I just tested this and it is working as intended in the current ACF Composer.

Simply add the $supports variable to your existing Block.php classes as seen in the full stub and then set __experimental_jsx to true.

/**
 * Features supported by the block.
 *
 * @var array
 */
public $supports = ['__experimental_jsx' => true, 'mode' => false];

After that you're free to throw an <InnerBlocks /> in your view and have the same functionality seen in the release blog post.

Limit for Option Pages?

I have a problem with Options Pages. I added two pages via wp acorn:

wp acorn acf:options Options wp acorn acf:options FredPromocje
I want to add another Option Page

wp acorn acf:options FredOpinie

And now i have only two pages in admin panel - Options and FredOpinie. FredPromocje page is gone.

My files:

Option.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;
use App\Fields\Partials\Api;
use App\Fields\Partials\Cookiebar;
use App\Fields\Partials\Scripts;
use App\Fields\Partials\Seo;
use App\Fields\Partials\SMTP;

class Option extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Zarządzanie motywem';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Zarządzanie motywem';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $option = new FieldsBuilder('option');

        $url = get_stylesheet_directory_uri() . '/screenshots/';

        $option
            ->addTab('general-options', ['label' => __('Treści', THEME_SLUG)])
                ->setConfig('placement', 'left')
                    ->addAccordion('brand-accord', ['label' => __('Identyfikacja wizualna', THEME_SLUG)])
                        ->addImage('logo', ['label' => __('Logo', THEME_SLUG)])
                    ->addAccordion('brand-accord-end')->endpoint()
                    ->addAccordion('contact-accord', ['label' => __('Dane kontaktowe', THEME_SLUG)])
//                        ->addMessage('scr', '<img style="max-width: 100%" src="'.$url.'topbar.png">' , ['label' => 'Dane w Topbar'])
                        ->addRepeater('contact-repeater', ['label' => 'Lokalizacje', 'button_label' => 'Dodaj lokalizacje', 'min' => 1, 'max' => 2, 'layout' => 'row'])
                            ->addText('city', ['label' => 'Miejscowość'])
                            ->addText('street', ['label' => 'Ulica'])
                            ->addText('postal', ['label' => 'Kod pocztowy'])
                            ->addText('tel-number', ['label' => 'Telefon kontaktowy'])
                            ->addText('hours', ['label' => 'Godziny otwarcia - format dla topbaru'])
                            ->addWysiwyg('hours-full', ['label' => 'Godziny otwarcia'])
                            ->addNumber('map-lat', ['label' => 'Szerokość geograficzna'])
                            ->addNumber('map-long', ['label' => 'Długość geograficzna'])
                        ->endRepeater()
                        ->addUrl('brand-facebook', ['label' => 'Profil FB'])
                    ->addAccordion('contact-accord-end')->endpoint()
            ->addAccordion('main-menu', ['label' => __('Meu główne', THEME_SLUG)])
                ->addMessage('main-menu-scr', '<img style="max-width: 100%" src="'.$url.'menu-addons.png">' , ['label' => 'Elementy dodatkowe w menu'])
                ->addRepeater('menu-addons', ['label' => 'Elementy dodatkowe menu'])
                    ->addImage('image', ['label' => 'Obraz/Logo'])
                    ->addText('text', ['label' => 'Krótki tekst', 'required' => true])
                    ->addUrl('url', ['label' => 'Odnośnik', 'required' => true])
                    ->addSelect('text-position', ['label' => 'Pozycja tekstu'])
                        ->addChoices(['flex-row' =>'Przed obrazem'], ['flex-row-reverse' => 'Za obrazem'])
                ->endRepeater()
            ->addAccordion('main-menu-end')->endpoint()
            ->addAccordion('cookiebar-accord', ['label' => __('Cookiebar', THEME_SLUG)])
            ->addFields($this->get(Cookiebar::class))
            ->addAccordion('cookiebar-accord-end')->endpoint()

            ->addAccordion('seo-accord', ['label' => __('Ustawienia SEO', THEME_SLUG)])
            ->addFields($this->get(Seo::class))
            ->addAccordion('seo-accord-end')->endpoint()
            ->addTab('config-options',['label' => __('Konfiguracja', THEME_SLUG)] )
            ->addAccordion('scripts-accord', ['label' => __('Własne skrypty', THEME_SLUG)])
            ->addFields($this->get(Scripts::class))
            ->addAccordion('scripts-accord-end')->endpoint()
            ->addAccordion('api-keys-accord', ['label' => __('Klucze API', THEME_SLUG)])
            ->addFields($this->get(Api::class))
            ->addAccordion('api-keys-accord-end')->endpoint()
            ->addTab('advanced-options',['label' => __('Zaawansowane', THEME_SLUG)] )
            ->setConfig('placement', 'left')
            ->addAccordion('smtp-accord', ['label' => __('Ustawienia SMTP', THEME_SLUG)])
            ->addFields($this->get(SMTP::class))
            ->addAccordion('smtp-accord-end')->endpoint()
        ;

        return $option->build();
    }
}

FredPromocje.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class FredPromocje extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Fred Promocje';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Fred Promocje | Options';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $fredPromocje = new FieldsBuilder('fred-promocje');
        $url = get_stylesheet_directory_uri() . '/screenshots/';
        $fredPromocje
           ->addMessage('scr', '<img style="max-width: 100%" src="'.$url.'promocja.png">' , ['label' => 'Przykład'])
            ->addRepeater('promos', ['label' => 'Promocje', 'button_label' => 'Dodaj promocje', 'layout' => 'block'])
                ->addText('title', ['label' => 'Tytuł'])
                ->addTextarea('desc', ['label' => 'Tekst'])
                ->addImage('image', ['label' => 'Zdjęcie 560x300'])
            ->endRepeater();

        return $fredPromocje->build();
    }
}

FredOpinie.php

<?php

namespace App\Options;

use Log1x\AcfComposer\Options as Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class FredOpinie extends Field
{
    /**
     * The option page menu name.
     *
     * @var string
     */
    public $name = 'Fred Opinie';

    /**
     * The option page document title.
     *
     * @var string
     */
    public $title = 'Fred Opinie | Options';

    /**
     * The option page field group.
     *
     * @return array
     */
    public function fields()
    {
        $fredOpinie = new FieldsBuilder('fred-opinie');

        $fredOpinie
            ->addRepeater('items22222')
                ->addText('item2222')
            ->endRepeater();

        return $fredOpinie->build();
    }
}

Installing gives me `Unable to locate publishable resources.`

Hi!
I'm unable to install this package.

  • composer require log1x/acf-composer (no errors)
  • wp acorn vendor:publish --provider="Log1x\AcfComposer\Providers\AcfComposerServiceProvider" (returns error)

The console renders:

Unable to locate publishable resources.
Publishing complete.

I can see the folder in vendor/

I cannot filter the blocks by custom category

I don't want all Gutenberg blocks to be available, so I use the following function:

add_filter( 'allowed_block_types_all', function ($allowed_blocks) {
    // Get widget blocks and registered by plugins blocks
    $registered_blocks = \WP_Block_Type_Registry::get_instance()->get_all_registered();
    // var_dump($registered_blocks);
    // wp_die();

    // Now $registered_blocks contains only blocks registered by plugins, but we need keys only of acf ones
    $registered_blocks = array_filter(array_keys($registered_blocks), function($block) {
        return strpos($block, 'acf/') !== false;
    });

    // Merge allowed core blocks with plugins blocks
    return array_merge([
        // 'core/image',
        'core/paragraph',
        'core/separator',
        // 'core/heading',
        // 'core/list'
    ], $registered_blocks);
});

But taking a look at all registered blocks, all of the acf created blocks don't specify category (block category appears as null) although it appears correctly in the editor.

I would like to filter by category instead of "acf/" as I have now. Is there a way to do it? Is this "null" category situation a consequence of acf composer or is it an advanced custom fields issue?

Multiple partials instances on same post ?

Hi,
is it possible to have multiple instances of a partial on the same post ?
I tried to but it seems the generated fields are using and overwriting the same metas.

Fields/Partials/CTA.php

namespace App\Fields\Partials;

use Log1x\AcfComposer\Partial;
use StoutLogic\AcfBuilder\FieldsBuilder;

class CTA extends Partial {

	/**
	 * The partial field group.
	 *
	 * @return \StoutLogic\AcfBuilder\FieldsBuilder
	 */
	public function fields() {
		$cTA = new FieldsBuilder(
			'c_t_a'
		);

		$cTA
			->addText(
				'accroche_cta', [
					'label' => 'Accroche',
				]
			)

	         //....

			->addText(
				'info_cta', [
					'label' => 'Information additionnelle',
					'placeholder' => 'Service sans engagement',
				]
			);
		return $cTA;
	}
}

LP_CTA_1.php

namespace App\Fields;

use Log1x\AcfComposer\Field;
use StoutLogic\AcfBuilder\FieldsBuilder;
use App\Fields\Partials\CTA;

class LP_CTA_1 extends Field {

	/**
	 * The field group.
	 *
	 * @return array
	 */
	public function fields() {
		$cTA = new FieldsBuilder(
			'cta_1', [
				'label' => 'Appel à action',
				[ 'menu_order' => 10 ],
			]
		);

		$cTA
			->setLocation( 'post_type', '==', 'service' );

		$cTA
			->addFields( $this->get( CTA::class ) );

		return $cTA->build();
	}
}

LP_CTA_2.php

namespace App\Fields;

use Log1x\AcfComposer\Field;
use StoutLogic\AcfBuilder\FieldsBuilder;
use App\Fields\Partials\CTA;

class LP_CTA_2 extends Field {

	/**
	 * The field group.
	 *
	 * @return array
	 */
	public function fields() {
		$cTA = new FieldsBuilder(
			'cta_2', [
				'label' => 'Appel à action',
				[ 'menu_order' => 50 ],
			]
		);

		$cTA
			->setLocation( 'post_type', '==', 'service' );

		$cTA
			->addFields( $this->get( CTA::class ) );

		return $cTA->build();
	}
}

and so on...

Error locating `app/helpers.php` for inclusion.

~/Desktop/wordpress/dataprotocol/wp-content/themes/dataprotocol git:(master) ✗ wp acorn acf:block Testing
Warning: Use of undefined constant STYLESHEETPATH - assumed 'STYLESHEETPATH' (this will throw an Error in a future version of PHP) in /Users/edward/Desktop/wordpress/dataprotocol/wp-includes/template.php on line 663
Warning: Use of undefined constant TEMPLATEPATH - assumed 'TEMPLATEPATH' (this will throw an Error in a future version of PHP) in /Users/edward/Desktop/wordpress/dataprotocol/wp-includes/template.php on line 666
Error: Error locating `app/helpers.php` for inclusion.

Everytime I try to run an acorn acf command, this error pops up. The files are there and the permissions seem correct, so not sure what the issue is. Thanks.

Widget ID & ACF data missing

Hey @Log1x, thanks again for the awesome package. I've just moved onto generating a few widgets but can't seem to access any ACF field data, it looks like the widget id is blank.

Steps to reproduce

  1. $ wp acorn acf:widget Example
  2. Add the widget, title & list items

Output: Missing title & No items found!


Possible solution

I've had a quick look and it seems adding

$this->widget->id = 'widget_' . Arr::get($args, 'widget_id');

within the widget() render method fixes it, but not entirely sure that's the right place to set it?

Also perhaps changing $this->widget->id to $this->id in widget.stub:L43 & widget.stub:L73 ?

Cheers!

Block preview issue while using Alpine.js in Gutenberg

Brandon do you know if there is an issue with using Alpine.js within blocks? I've just added a simple alpine code block to an acf composer block view file eg:

<div class="{{ $block->classes }}">

  <div x-data="{ count: 1 }">
    <p x-text="count"></p>
    <button @click="count++">Count Up</button>
    <button @click="count--">Count Down</button>
  </div>

  <div>
    <InnerBlocks />
  </div>
</div>

It no longer allows the block to preview in Gutenberg?

Screenshot 2021-03-02 at 16 41 08

WP Acorn

Hey Brandon,

I'm trying to install this package for Sage10. I'm testing it locally, but getting a 'command not found' for this:

wp acorn vendor:publish --provider="Log1x\AcfComposer\Providers\AcfComposerServiceProvider"

Is there something else that needs to be installed for wp acorn commands?

Thanks

Basic Example Field

Big thanks to log1x for all of these great WP/Roots helpers.

I am having some trouble getting the basic example repeater field to show up on the front end of my front page. The fields show up great on the page in the back end, and I have some basic text in the fields. I know that I am probably just doing something wrong in one of the steps. Hoping one of you great people can help my dumbass out.

Here is what I have right now:

app > Fields > Example.php

<?php

namespace App\Fields;

use Log1x\AcfComposer\Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Example extends Field
{

    /**
     * The field group.
     *
     * @return array
     */
    public function fields()
    {
        $example = new FieldsBuilder('example');

        $example
            ->setLocation('page_template', '==', 'template-page-home.blade.php');

        $example
            ->addRepeater('items')
                ->addText('item')
            ->endRepeater();

        return $example->build();
    }
}

views > fields > example.blade.php

@if ($items)
  <ul>
    @foreach ($items as $item)
      <li>{{ $item['item'] }}</li>
    @endforeach
  </ul>
@else
  <p>No items found!</p>
@endif

views > template-page-home.blade.php

@include('fields.example')

When including it on my front page, I just get a blank page back. I am thinking it might have to do something with either the namespace (does the field folder need to be outside the view??), or possibly I am not using the fields in the way they are intended?

Any help on this would be much appreciated, been banging my head against the wall for a while now trying to figure it out. Feel like its something super simple and I am just being an idiot.

Thanks!

Partials working locally, but not in production

I've got a couple partials in a field and they work as they should when I'm developing locally.

When I deploy to staging/production, they're not appearing at all. Anything I should look out for?

I've tried with Kinsta and DigitalOcean, but no luck.

Block view not loading if not generated with a single word

Summary
When creating a block with more than a single word, the view is not loaded.

Steps to reproduce

$ wp acorn acf:block NewExampleBlock

Screenshot_2020-07-14_at_13_17_12

Possible fix
I'm not too familiar with the library to fix this, but perhaps if the generated block/widget/partial $name added the spaces, the view would be found. It's not really a problem manually updating it, as I'd edit the name anyways, but it has caught me out a few times! Especially before I knew what the issue was.

# app/Blocks/NewExampleBlock.php
- public $name = 'NewExampleBlock';
+ public $name = 'New Example Block';

There are no commands defined in the "acf" namespace.

Hi there,
I used your package before with Sage 10, but with these versions:

    "log1x/acf-composer": "^1.5",
    "roots/acorn": "^1.1" 

With these:

    "log1x/acf-composer": "^2.0",
    "roots/acorn": "2.0.0-alpha.0"

whenever I want to generate a field with for example wp @development acorn acf:field Example, I get this error:

There are no commands defined in the "acf" namespace.

Any idea what's causing this?
My config/acf.php is in place?

Thanks!

Very strange issue in user profile getting $_GET['user_id']

I created fields located in the user profile, and I wanted to construct a select field based on a user choice.

For retrieving that field, I used $_GET['user_id'].

But as soon as I use $_GET['user_id'] anywhere in the fields file, all the fields stop saving.

I don't know if it's because acf composer, acf builder or acf itself. I searched in all three without success. Any idea why this happens?

To reproduce: create a fields builder and set location a user role:

->setLocation('user_role', '==', 'subscriber');

Then, create any kind of field, and just put the user id in a variable:

$user_id = $_GET['user_id'];

Suddenly the fields stop saving to the database.

Undefiend method when adding any field after ->endRepeater()

When calling any field adding method on ->endRepeater() like the example below

$example
    ->addRepeater('items')
        ->addTextarea('item')
    ->endRepeater()
    ->addText('text');

The Intelephense says Undefined method 'addText'. And it stops prompting the available methods, previewing their documentation, ..etc.

This wasn't the case when using ACF Builder directly with Sage 9.

A workaround I'm currently using is calling the methods on the instance itself as shown below

$example
    ->addRepeater('items')
        ->addTextarea('item')
    ->endRepeater();

$example
    ->addText('text');

However, this gets a little annoying when the variable name is long and I have to copy it every time I add a Repeater. On the other hand, calling methods on ->endGroup() works as expected.

I have the time to contribute to fixing this issue if you're aware of it and/or can direct me to the right path.

Duplicate Widget ID

Hey @Log1x thanks for fixing up those other bits, much appreciated. Just run into this weird one today - not sure if it's the way I'm calling get_field() maybe? But trying out the Example widget it appears to have the same issue.

Summary

Multiple widgets return the same widget_id so ACF data returned is always the last widget added (of the same type).

Example

  1. wp acorn acf:widget Example
  2. Add 2 or more Example widgets with a few unique list items Screenshot 2020-08-04 at 16 11 39
  3. Identical fields will be shown in the view (last added widget) Screenshot 2020-08-04 at 16 07 07

Unable to publish the config/acf.php file

Hello ! I'm exploring Sage 10 and ACF Composer.

Every acorn commands are working fine, it's awesome !

But when i try this one to publish the acf.php config, it gives me this error : "Unable to locate publishable resources."

wp acorn vendor:publish --provider="Log1x\AcfComposer\Providers\AcfComposerServiceProvider"

Unable to locate publishable resources.
Publishing complete.

Any ideas ?

Undefined property: Log1x\AcfComposer\Console\BlockMakeCommand::$app

After installing directly from Composer, I followed the docs and created a new block (wp acorn acf:block Example) and get the following error: In MakeCommand.php line 156: Undefined property: Log1x\AcfComposer\Console\BlockMakeCommand::$app.

As a result, the views don't get created. I'm not sure if there's something that I'm missing, as it looks like the code responsible has been there for some time and no issues have been raised prior. I will create a PR with what got it working for me.

Small problem with create block view

After creating a new block, strange messages appear in the terminal when trying to create a view.

PS C:\laragon\www\fred2\wp-content\themes\fred> wp acorn acf:block FredOpinie

 Where do you want to create the view(s)? [C:\laragon\www\fred2\wp-content\themes\fred\resources\views]:
  [0] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
  [2] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
 > 2
2?[K

 ?[32mWhere do you want to create the view(s)??[39m [?[33mC:\laragon\www\fred2\wp-content\themes\fred\resources\views?[39m]:
  [?[33m0?[39m] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
  [?[33m2?[39m] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
 > 2
2?[K

 ?[32mWhere do you want to create the view(s)??[39m [?[33mC:\laragon\www\fred2\wp-content\themes\fred\resources\views?[39m]:
  [?[33m0?[39m] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
  [?[33m2?[39m] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
 > 2
2?[K


🎉 ?[34;1mFredOpinie?[39;22m block successfully composed.
     ⮑  ?[34mfred\app/Blocks/FredOpinie.php?[39m

 ?[32mWhere do you want to create the view(s)??[39m [?[33mC:\laragon\www\fred2\wp-content\themes\fred\resources\views?[39m]:
  [?[33m0?[39m] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
  [?[33m2?[39m] C:\laragon\www\fred2\wp-content\themes\fred\resources\views
 > 2
2?[K

     ⮑  ?[34mC:\laragon\www\fred2\wp-content\themes\fred\resources\views/blocks/fred-opinie.blade.php?[39m
PS C:\laragon\www\fred2\wp-content\themes\fred>

I have to select "2" five times then create a view.

Sage 10
Node 14.16.0

Post ID not available

Hey @Log1x 👋

Might be an obvious solution I'm missing, but is there a way to get the current $post->ID in the Blocks? It works ok on the frontend but not in the admin preview. It seems acf-composer is hooked pretty early on so not of the post stuff has been populated yet, at a guess?

Bit of context - I'm making a recommended posts section and need to exclude the current post from the query. User can choose between custom selection (relationship) or latest feed from selected categories.

...
    public function with()
    {
        return [
            'query' => $this->get_posts_query(),
        ];
    }

    public function get_posts_query() 
    {
        $feed = get_field('feed');

        $defaults = [
            'posts_per_page'  => 5,
            'post_status'     => 'publish',
        ];

        if ($feed === 'category') {
            if ($cat_ids = get_field('categories')) {
                $args['category__in'] = $cat_ids;
            }

            if ($current_post_id = get_the_id()) { // <-- Need the post ID here, if possible?
                $args['post__not_in'] = [$current_post_id]; // exclude the current post
            }
        }

        if ($feed === 'custom') {...}

        $query_args = wp_parse_args($args, $defaults);
        $query = new \WP_Query($query_args);

        return $query;
    }

Cheers!

Problem with starting ACF-Composer with Sage10

Hi, I have a problem running this tool.
I'm using Sage 10, I have ACF Pro 5.9.5 installed
My installation process:

  1. Run composer require log1x/acf-composer
  2. Run wp acorn vendor:publish and check 1 [[1] Provider: Log1x\AcfComposer\Providers\AcfComposerServiceProvider
    ]
  3. Run wp acorn acf:field Example and wp acorn acf:options Options

Tool create files in app/Options and app/Fields directory but they are not visible in the Wordpress admin panel.

ACF 5.11 (and 5.11.1) introduces breaking changes

I am starting to have a lot of problems with ACF 5.11.

Although a fresh install of wp and acf composer works as expected, one with a lot of fields don't, and the errors point directly to acf composer (development.WARNING: Skipping provider [Log1x\AcfComposer\Providers\AcfComposerServiceProvider] because it encountered an error. {"package":"log1x/acf-composer","provider":"Log1x\AcfComposer\Providers\AcfComposerServiceProvider","error":"acf_get_value s'ha cridat de manera incorrecta. Advanced Custom Fields PRO - We've detected one or more calls to retrieve ACF field values before ACF has been initialized, resulting in missing data. <a href="https://www.advancedcustomfields.com/resources/acf-field-functions/\" target="_blank">Learn how to fix this.).

I am still trying to understand where is everything coming from, but for example, using get_field from a user page no longer works (we have to use get_user_meta instead), and is not a documented breaking change in the acf page, so I am suspecting that more bugs are there to come.

Probably everything is 100% delicious brains fault, but just in case I post it as a bug until everything gets cleared. I will update any other findings.

Priorities issues

I'm trying to setup fields for a certain product category (using WooCommerce) but running into problems because the 'product_cat' taxonomy is not registered by WC yet when the fields are initiated. Not sure if this is a bug per se but would love to hear any idea's on how to tackle such issues.

The fields object I'm trying to get to work looks like this:

class PageModules extends Field {
	/**
	 * The field group.
	 *
	 * @return array
	 */
	public function fields() {
		$accessories_cat = get_field('accessories_cat', 'option');
		$term = get_term($accessories_cat, 'product_cat', 'slug')->slug;

		$post = new FieldsBuilder('page_modules');
		$post
			->setLocation('post_type', '==', 'product')
				->and('post_taxonomy', '==', 'product_cat:'.$term)
			->addFields($this->get(Modules::class));

		return $post->build();
	}
}

isReservedName does not exist

Hi Log1x. Awesome package i must say. Really looking forward to try it out!
I have a problem tho.
When i try setup a field, block, widget etc. with Acorn I get the following error:

In Macroable.php line 103:
Method Log1x\AcfComposer\Console\FieldMakeCommand::isReservedName does not exist. 

Don't really know if it's a problem with acf-composer or any other problem.

Thanks in advance!

some addFlexibleContent options don't work

The below works with sage 9 and "stoutlogic/acf-builder": "1.10.0"
Errs with "log1x/acf-composer": "v1.5.5" which is using the same "stoutlogic/acf-builder" version
location: /vendor/log1x/acf-composer/src/Composer.php : 109

$builder
    ->addFlexibleContent('sections', [
        'acfe_flexible_layouts_thumbnails' => 1, // "array_map(): Expected parameter 2 to be an array, int given"
        'acfe_flexible_layouts_state' => 'collapse', // "array_map(): Expected parameter 2 to be an array, string given"
    ]);

Wanted to check if you have any clues before I give it a shot.

Custom post type ?

Hey,

Do you think it would be a good idea to add custom post type ? something like acf:cpt (I can make a PR if you think it could be useful). Maybe it could works like the Widget, but without the view => I don't know if we can add the view directly with cpt

Localization for name and description

When I create a new block I can use __ function everywhere except for $name and $description public variables. And because of this, I cannot change language to the blocks.

How should I do it? Is there a proper way or would it be a feature request?

Null Coalesce Operator on Array renders false in view

In my experience, ACF tends to return false instead of null. In your stubs you end up passing false to the view instead of the empty array for items. I almost did a pull request, but I thought maybe theres a reason you're doing this, or you handle this differently at some other point.

Anyways, it confused me for awhile since I assumed the

get_field('items) ?? [];

would have worked, but for me

get_field('items) ?: [];

seems to work with ACF more consistently...but it would be nice to have a "ACF didnt find that field" return null instead of false...

I didn't fully realize what was happening until I dumped everything that was being passed to the view

{{ dd(get_defined_vars()['__data']) }}

Anyways, having tons of fun with the package, really dig being able to treat Sage 10 mostly like a laravel project!! =)

How to see Tailwind CSS rendered in block editor?

For anyone wondering how to have the block editor display the Tailwind CSS you have used in your block template, see below!

All you need to do is edit the enqueue_block_editor_assets action (found in app/setup.php). Add a call to wp_enqueue_style with app/setup.php as the parameter.

See the last line of the action below for the correct implementation.

/**
 * Register the theme assets with the block editor.
 *
 * @return void
 */
add_action('enqueue_block_editor_assets', function () {
    if ($manifest = asset('scripts/manifest.asset.php')->load()) {
        wp_enqueue_script('sage/vendor.js', asset('scripts/vendor.js')->uri(), ...array_values($manifest));
        wp_enqueue_script('sage/editor.js', asset('scripts/editor.js')->uri(), ['sage/vendor.js'], null, true);

        wp_add_inline_script('sage/vendor.js', asset('scripts/manifest.js')->contents(), 'before');
    }

    wp_enqueue_style('sage/editor.css', asset('styles/editor.css')->uri(), false, null);
    
    /* Enqueue style to see Tailwind CSS styles applied in the block editor */
    wp_enqueue_style('sage/app.css', asset('styles/app.css')->uri(), false, null);

}, 100);

Troubles with including partials...

First of all, thanks so much for all your hard work with these packages for Sage 10. I am just beginning to dive into your toolsets and I am having an issue with including files.

First of all, I have Gutenberg disabled on purpose. I still prefer the old editor.

I've generated a Page.php file located in app/Fields/Page.php and here's the code:

<?php

namespace App\Fields;

use Log1x\AcfComposer\Field;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Page extends Field
{
    /**
     * The field group.
     *
     * @return array
     */
    public function fields()
    {

        $page = new FieldsBuilder('page');

        $page
            ->setLocation('post_type', '==', 'page');
        
        $page
            ->addFields($this->get(General::class));

        return $page->build();


    }
}

On my home page, this becomes visible:

image

Next, I've generated a General.php page located at app/Fields/Partials/General.php and here's the code:

<?php

namespace App\Fields\Partials;

use Log1x\AcfComposer\Partial;
use StoutLogic\AcfBuilder\FieldsBuilder;

class General extends Partial
{
    /**
     * The partial group.
     *
     * @return array
     */
    public function fields()
    {
        $general = new FieldsBuilder('general');

        $general
            ->addTab('general', ['placement' => 'left'])
                ->addTrueFalse('enable_social_sharing', ['ui' => 1])
                    ->setDefaultValue('1')
                    ->setInstructions('Shows social sharing buttons for various platforms below the title.')
                    
                ->addTrueFalse('enable_featured_image', ['ui' => 1])
                    ->setDefaultValue('1')
                    ->setInstructions('Enables automatically displaying the featured image before the content.');
                    
        return $general;
    }
}

But nothing more appears on the admin pages other than the image I attached above.

The documentation I am following is a mix of these which I am not sure they're all up to date:

https://roots.io/guides/using-acf-builder-with-sage/

https://github.com/Log1x/acf-composer

https://github.com/Log1x/acf-builder-cheatsheet#flexible-content

Returning ACF field data for use with Javascript

First of all, thanks so much for all your hard work with these packages for Sage 10.

I am trying to make some ACF fields data available to Javascript.

I have wp_add_inline_script() set up in enqueue() function in Chart.php( the block ), but It returns:

<script id='sage/app.js-js-before'>
csvURL = null; 
</script>

Steps to reproduce

$ wp acorn acf:block Chart

./app/Blocks/Chart.php

<?php

namespace App\Blocks;

use Log1x\AcfComposer\Block;
use StoutLogic\AcfBuilder\FieldsBuilder;

class Chart extends Block
{
    /**
     * The block name.
     *
     * @var string
     */
    public $name = 'Chart';

    /**
     * The block description.
     *
     * @var string
     */
    public $description = 'A simple Chart block.';

    /**
     * The block category.
     *
     * @var string
     */
    public $category = 'formatting';

    /**
     * The block icon.
     *
     * @var string|array
     */
    public $icon = 'editor-ul';

    /**
     * The block keywords.
     *
     * @var array
     */
    public $keywords = [];

    /**
     * The block post type allow list.
     *
     * @var array
     */
    public $post_types = ['post'];

    /**
     * The parent block type allow list.
     *
     * @var array
     */
    public $parent = [];

    /**
     * The default block mode.
     * preview
     * @var string
     */
    public $mode = 'edit';

    /**
     * The default block alignment.
     *
     * @var string
     */
    public $align = 'wide';

    /**
     * The default block text alignment.
     *
     * @var string
     */
    public $align_text = '';

    /**
     * The default block content alignment.
     *
     * @var string
     */
    public $align_content = '';

    /**
     * The supported block features.
     *
     * @var array
     */
    public $supports = [
        'align' => true,
        'align_text' => false,
        'align_content' => false,
        'anchor' => false,
        'mode' => false,
        'multiple' => true,
        'jsx' => true,
    ];

    /**
     * The block styles.
     *
     * @var array
     */
    public $styles = [
        [
            'name' => 'light',
            'label' => 'Light',
            'isDefault' => true,
        ],
        [
            'name' => 'dark',
            'label' => 'Dark',
        ]
    ];

    /**
     * The block preview chart data.
     *
     * @var array
     */
    public $example = [
        'items' => [
            ['item' => 'Item one'],
            ['item' => 'Item two'],
            ['item' => 'Item three'],
        ],
    ];

    /**
     * Data to be passed to the block before rendering.
     *
     * @return array
     */
    public function with()
    {
        return [
            'csv' => $this->csv(),
        ];
    }

    /**
     * The block field group.
     *
     * @return array
     */
    public function fields()
    {
        $chart = new FieldsBuilder('chart');

        $chart
            ->addFile('csv', [
                'return_format' => 'url',
                'min_size' => '1 KB',
                'max_size' => '5',
                'mime_types' => 'csv'
            ]);

        return $chart->build();
    }

    /**
     * Return the items field.
     *
     * @return array
     */
    public function csv()
    {
        return get_field('csv');
    }

    /**
     * Assets to be enqueued when rendering the block.
     *
     * @return void
     */
    public function enqueue()
    {
        $script  = 'csvURL = '. json_encode($this->csv()) .'; ';
        wp_add_inline_script('sage/app.js', $script, 'before');
    }

Any help on this would be much appreciated.

Enancement: Pass through array of blocks that live in other locations?

Scenario: We build themes that pull from a repo of blocks, that are folders outside the app directory, which are self contained components:

MyBlocks
|- Block.php
|- view.blade.php
|- admin.css
|- style.css
|- script.js
|- config.js

Issue: Currently, the compose method scans folders for php files, which gets tripped up if a blade file also lives in the same directory.

Suggestion: It would be great it we could pass through an array of namespaces to compose as blocks within the AcfComposerServiceProvider.php similar to how the config/views.php file handles an additional composers array/

The config/acf.php file could have something similar to:

    'defaults' => [
        'trueFalse' => ['ui' => 1],
        'select' => ['ui' => 1],
    ],

    'composers' => [       

    ],

Which you could pass your namespaces:

    'defaults' => [
        'trueFalse' => ['ui' => 1],
        'select' => ['ui' => 1],
    ],

    'composers' => [       
        'MyBlocks\Header',
        ...
        'MyBlocks\Features',
    ],

And the AcfComposerServiceProvider.php could have something along the lines of (this is really rough)

        foreach($this->app->config['acf.composers'] as $composer) {
            if (
                is_subclass_of($composer, Composer::class) &&
                ! is_subclass_of($composer, Partial::class) &&
                ! (new ReflectionClass($composer))->isAbstract()
            ) {

                $this->fields[] = (new $composer($this->app))->compose();
            }
        }

Just a thought.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.