Giter Site home page Giter Site logo

acf-codifier's Introduction

geniem-github-banner

ACF Codifier

Description

A helper class to make defining ACF field groups and fields easier in the code.

A complete documentation of the classes can be found here.

Installation

The recommended way to install ACF Codifier is by Composer:

$ composer require devgeniem/acf-codifier

OR add it in your composer.json:

{
  "require": {
    "devgeniem/acf-codifier": "*"
  }
}

Installing the plugin with Composer requires Bedrock's autoloader. It installs as an mu-plugin and doesn't need to be activated.

You can, however, install it also as an ordinary plugin. It can be done in two ways:

  • Clone this repository into your plugins directory and run composer install --no-dev in the repository folder.

  • Download the latest release here and just extract the archive in your plugins directory.

Usage

All classes of the Codifier are under the namespace Geniem\ACF. For easiness, it's better to put your declarations in separate file(s) and declare namespace Geniem\ACF; on top of them. Rest of this ReadMe supposes you have done that.

Creating a field group.

Field groups live in a class called Group. New group is thus created with:

$field_group = new Group( 'Field Group' );

This will create a new field group with Field Group as its title and field-group as the key.

If you want to define the key yourself, you can either give it as the second parameter to the constructor or use:

$field_group->set_key( 'new_key' );

You can also change the title of the group later with set_title() method.

There are methods for defining all the other properties of a field group as well. All the field group commands can be chained. For example:

$field_group->set_position( 'side' )         // Set the field group to be shown in the side bar of the edit screen.
            ->set_style( 'seamless' )        // Set the field group to show as seamless.
            ->hide_element( 'the_content' ); // Hide the native WP content field.

Very rarely anyone wants their field group to be shown in every edit screen of a WordPress installation. The visibility rules are handled with their own class RuleGroup. A rule group is created and linked with a group like this:

$rule_group = new RuleGroup();
$rule_group->add_rule( 'post_type', '==', 'page' );

$field_group->add_rule_group( $rule_group );

You can add multiple rules to a rule group, and each rule within a group is considered an 'and'. If you add multiple rule groups to a field group, they are considered an 'or'.

Field group is registered to use with register method:

$field_group->register();

Obviously your new field group wouldn't have any fields at this point, but don't worry, we get to them later.

Comprehensive documentation of the class can be found here.

Creating fields

Like field groups, fields are also objects of their own. They live in classes named for their field types. For example a text field can be created with:

$text = new Field\Text( 'Text field' );

Now the $text variable is populated with a text field with Text field as its label and text-field with both as its key and its name.

The key and the name can also be given to the constructor as its second and third parameters respectively. Obviously there are set_key() and set_name() methods also available like there were with the groups as well.

The plugin checks that the field key is unique within the project and triggers a notice if there is a collision.

Every property a field type has is defined with its own method. Like the field groups, they can be chained with the fields as well.

$text->set_placeholder( 'Placeholder text' ) // Set a placeholder text.
     ->set_append( 'Appendable' )            // Set an appending text.
     ->set_maxlength( 30 );                  // Set the maxlength.

ACF's conditional logic groups work very similarly to groups' location rules. First you need to create an object from ConditionalLogicGroup and add the rule there:

$conditional_logic = new ConditionalLogicGroup();
$conditional_logic->add_rule( 'another_field', '==', true );

$text->add_conditional_logic( $conditional_logic );

The logic between 'ands' and 'ors' is the same than it is with the groups' location rules.

Fields are added to field groups with the add_field method:

$field_group->add_field( $text );

Normally add_field adds the field to the end of the field group. If you want the field to be inserted first, append a second parameter with first as its value:

$field_group->add_field( $text, 'first' );

You can also insert the field into the field group after or before another field with following methods:

$field_group->add_field_before( $text, 'target_field_key' );
$field_group->add_field_after( $text, $target_field_object );

You can use either the field key or the field object with both methods.

There are also methods like add_fields() that can be used to add an array of fields at once, and add_fields_from() that takes another groupable object (for example a field group, group field, repeater or a flexible layout) as its first parameter and copies its fields to the calling object.

$field_group->add_fields_from( $repeater );

List of all field types and their methods can be found here.

Grouping field types

There are several special field types that can have subfields within them.

Group and repeater

The group and the repeater fields are the simplest of the grouping field types. They are very straightforward:

$group = new Field\Group( 'Field name' );

$group->set_layout( 'table' )
      ->add_field( $some_field )
      ->add_field( $another_field );

$field_group->add_field( $group );
Flexible content

Flexible content fields consist of layouts which contain the fields.

$flexible_content = new Field\FlexibleContent( 'Flexible field' );

$layout = new Field\Flexible\Layout( 'Layout label' );

$layout->set_display_mode( 'row' )
       ->add_field( $some_field )
       ->add_field( $another_field );

$flexible_content->add_layout( $layout );

Like fields, layouts can also take key and name as their second and third parameters.

Clone

Clone field is a special case in that its class name is not the same than the field slug. Clone is a reserved word in PHP so the class name of the field is CloneField.

You can clone both fields and field groups, so the field's add_clone() method can take both as a parameter. It can also be given just the key of the desired field or field group as a string.

$clone = new Field\CloneField( 'Clone' );

$clone->set_label_prefix()        // Set label prefix setting as true
      ->add_clone( $some_field )  // Add a field object
      ->add_clone( $some_group )  // Add a field group object.
      ->add_clone( 'field-key' ); // Add a field by its key

$field_group->add_field( $clone );
Tab and Accordion

With ACF Codifier the tab and accordion field types are treated like they had subfields. Otherwise they works just the same as native ACF fields would.

$tab = new Field\Tab( 'My Very First Tab' );

$tab->set_placement( 'left' )
    ->set_endpoint()
    ->add_field( $some_field )
    ->add_field( $another_field );

$field_group->add_field( $tab );
Pseudo group

Pseudo group is like a group field, but it doesn't affect the data tree or the admin view. It only acts as a container for multiple fields, which then appear as independents fields when viewing the edit page or looking at the data tree.

$pseudo = new Field\Pseudo( 'pseudo-group' );

$pseudo->add_field( $some_field )
       ->add_field( $another_field );

Bidirectional relationships

Codifier supports bidirectional relationships for the field types ACF is supporting the feature (currently PostObject, Relationship, Taxonomy and User).

$field->set_bidirectional()
      ->set_bidirectional_targets( [ 'field_name_or_key' ] );

Gutenberg

Codifier has a feature to register Gutenberg blocks using ACF's register block feature internally. It works in a very similar fashion than the basic field creation in Codifier as well.

Block's constructor takes two mandatory parameters: the title and the name (or key) of the block. The properties are then set for the block with appropriate methods.

$block = new \Geniem\ACF\Block( 'Some block', 'some_block' );
$block->set_category( 'common' );
$block->add_post_type( 'post' );
$block->set_mode( 'edit' );

The rendering of the block happens with a Renderer class. Codifier includes three renderers by default: CallableRenderer that uses a simple method for rendering; PHP that renders a normal PHP file with the given data and Dust that uses DustPHP templates for rendering.

The following uses the print_r() method to output a list of the data from the fields.

$renderer = new \Geniem\ACF\Renderer\CallableRenderer( function( $data ) {
  return print_r( $data, true );
});

$block->set_renderer( $renderer );

The ACF fields themselves are added to the block as they would to any other groupable type object with methods like add_field() and set_fields().

To register the block for Gutenberg, just use the register() method.

$block->register();

If you need, the abovementioned method returns the output of ACF's register_block() function.

Additional features

Prevent Flexible Content layouts from showing in some post types or page templates

If you want to prevent some Flexible Content layouts from showing in some post types or page templates, you can do so with exclude_post_type or exclude_template methods:

$layout->exclude_post_type( 'post' );
$layout->exclude_template( 'page-frontpage.php' );

There are also set_exclude_post_types and set_exclude_templates methods with which you can set multiple excludes at once with an array.

Hide field label

With the Codifier you can hide a field's label on the admin side. It might be useful for example with flexible content fields or a group field.

You achieve this simply by calling hide_label() for your field.

$field->hide_label();

There are also show_label() and get_label_visibility() methods.

Additional field types

PHP field

The PHP field is an ACF field type that can only be used with the Codifier. It allows the developer to run his own code within the field area in the admin side and print anything between the ordinary fields.

The field type shows up in the ACF admin as well, but there are no functionality that can be used from there.

Usage of the field type is very straightforward. You can just run your own code like this:

$php = new Field\PHP( __( 'My PHP field' ) );
$php->run( function() {
    global $post;

    echo '<pre>';
    print_r( $post );
    echo '</pre>';
});

Multisite Relationship

The Multisite Relationship is an ACF field type that can only be used with the Codifier. It is a clone of the original Relationship field but with the ability to define the blog from which the posts can be picked.

The usage is otherwise exactly the same as with the Relationship field, but there is a new set_blog_id() method.

$ms_relationship = new Field\MultisiteRelationship( __( 'My Multisite Relationship field', 'multisite_relationship', 'multisite_relationship' ) );
$ms_relationship->set_blog_id( 2 );

Multitaxonomy

The Multitaxonomy is an ACF field type that can only be used with the Codifier. It is a clone of the original Taxonomy field but with the ability to define multiple taxonomies to select the terms from. It supports all features defined for the Taxonomy field except the ability to add a new term with the field input. It also has an additional feature for setting the field disabled, which is not possible with the original Taxonomy field.

Usage

Define the field and set the taxonomy slugs to enable selecting terms from multiple taxonomies.

$categories_and_tags = new Field\Multitaxonomy( __( 'Select a category or a tag', 'multitaxonomy_test', 'multitaxonomy_test' ) );
$categories_and_tags->set_taxonomies( [ 'category', 'post_tag' ] );

To enable selecting multiple terms, change the field type to multi_select.

$categories_and_tags->set_field_type( 'multi_select' );

Multisite Taxonomy

The Multisite Taxonomy is an ACF field type that can only be used with the Codifier. It extends the abilities of the Multitaxonomy field by allowing the developer to set a multisite blog id from which the taxonomy terms can be chosen.

Usage

$multisite_taxonomy = new Field\MultisiteTaxonomy( __( 'Select a category or a tag from blog 2', 'multisite_tax', 'multisite_tax' ) );
$multisite_taxonomy->set_taxonomies( [ 'category', 'post_tag' ] );
$multisite_taxonomy->set_blog_id( 2 );

Extended Wysiwyg

The Extended Wysiwyg is an ACF field type that can only be used with the Codifier. It extends the abilities of the Wysiwyg field by allowing the developer to set the height of the TinyMCE editor.

$extended_wysiwyg = new Field\ExtendedWysiwyg( __( 'Extended Wysiwyg', 'extended_wysiwyg', 'extended_wysiwyg' ) );
$extended_wysiwyg->set_height( 150 );

Multisite Post Object

The Multisite Post Object is an ACF field type that can only be used with the Codifier. It is a clone of the original Post Object field but with the ability to define the blog from which the post object can be picked.

The usage is similar to the Post Object field, but there is a new set_blog_id() method for selecting the blog.

$ms_object = new Field\MultisitePostObject( __( 'My Multisite Post Object field', 'multisite_object', 'multisite_object' ) );
$ms_object->set_blog_id( 2 );

Support for external field types

There are also some field types that are created in the ACF Codifier that are not built-in in the ACF itself. These fields require a plugin to work. The plugins should be linked in the docblock comment of the field type class.

If you use some ACF field type plugin, you can either request it to be included in the Codifier by creating an issue on GitHub or creating the field type class yourself and filing a pull request for it.

List of included additional field types

Tips & Tricks

Translations

If translated strings are used as field labels, instructions etc., the Codifier declarations should be run inside an appropriate hook - for example init is fine.

acf-codifier's People

Contributors

ahmis avatar godbone avatar hpiirainen avatar ivuorinen avatar jaakkolehtonen avatar jjfer avatar liblastic avatar nco-webdev avatar nomafin avatar ogorzalka avatar samiharju avatar szepeviktor avatar tim0haapala 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

acf-codifier's Issues

Change composer installation location

Now that ACF supports installing via composer (yay), when installing it you can specify a path to where the plugin is installed to. This is great because if you require it from a composer file within your theme, you can change the path to correctly install in wp-content/plugins

It seems with this plugin, you can't change the path. So if i install this plugin within a theme, it always puts the plugin inside wp-content/themes/my-theme/wp-content/mu-plugin

Is it possible to change this installation path?

Block settings and attributes in block template

Is there a way to get block settings and attributes in the block template when using PHP renderer (or CallableRenderer)? Currently, PHP renderer extracts only $fields['data'], but I would like to have $block variable too ($fields['block'] in this case) to get, for example, block align or ID.

add_field( $field, 'first' ) doesn't work when there isn't any other fields.

In my code there's a case where I need to add a field at the end of the code block and it always has to come first. Before the adding there is conditional code that either adds other fields or doesn't.

In a case where no other fields are added before I try to make the last addition, the code breaks saying that I can't operate with an empty array, etc.

Could you make an adjustment where the addition with 'first' would be possible even though there are no other fields?

hide_label() has no effect for fields in media library

When registering fields for attachments, hide_label() has no effect. The resulting CSS for hiding the label is

div.acf-field.acf-field-{field-key} > div.acf-label > label { display: none; }

but the media library meta fields use table markup. div.acf-label could be changed to .acf-label to target all elements.

Conditional logic not working properly with groupable fields

If you pass for example a true/false field object for the add_condition_logic() method to control visibility of a groupable field, a repeater in this case, the condition will hide the subfields of the groupable field but not the field itself. If you change the add_condition_logic() method parameter to a field key of a true/false field, then the whole repeater field is hidden if the condition is met.

Here are screenshots of the condition logic functionality when using the object as the parameter. The repeater should be hidden if the true/false is set to "Ei".

Condition not met:
nayttokuva 2018-10-16 kello 16 26 39

Condition met:
nayttokuva 2018-10-16 kello 16 26 47

Sanitizing the field key may cause unwanted behavior

The inner_set_key() method is used for all keys set through the Field constructor. It sanitizes keys with the WP sanitize_title() function. This is necessary when the key is created out of a label text, but it might not be wanted if the user sets the key explicitly.

Could the sanitizing be done only if the key is created out of a label text?

Hide label on cloned fields

the hide label status is lost if a field is cloned with the clone() function of the Field class as the key will be different after cloning

Custom fields and group parameters

Hi !

Sometimes ACF plugins add their own configuration keys in fields or field groups. is there a way to extend the Field or Group class to add additional properties?

thank you and congratulations for your great class ๐Ÿ™‚

Tabs are created twice

It seems that if I create new tab field, it is always created twice. If I add multiple tabs, all of them are duplicated. The fields are displayed in the duplicated tab. First tab remains empty.

image

Here is the code I am using:

$tab = new Field\Tab( 'First Tab' );
$tab->set_placement( 'top' )
->add_field( $example1 )
->add_field( $example2 );
$group_field->add_field( $tab );

$tab2 = new Field\Tab( 'Second Tab' );
$tab2->set_placement( 'top' )
->add_field( $example3 )
->add_field( $example4 );
$group_field->add_field( $tab2 );

WordPress: 4.9.8
ACF Pro: 5.7.7
ACF Codifier: 1.14.4

Add possible parameter values for the field function documentation and error message

docblock example
@param string $new_lines New line handling way. Possible values: 'wpautop', 'br', ''.

Error message suggestion:
For example ( new Textarea( 'test' ) )->set_new_lines( 'wrong-parameter-value' ) could return error message:

throw new \Geniem\ACF\Exception( 'Geniem\ACF\Textarea: set_new_lines() does not accept argument "' . $new_lines . ' Possible values' . implode( $possible_values, ', ' ) . '"' );

Warning while adding a field into a group

I'm getting a PHP Warning while trying to add a new field into a group.

The code i'm using:

<?php

namespace Geniem\ACF;

$field_group = new Group( 'Test Group' );

$rule_group = new RuleGroup();
$rule_group->add_rule( 'post_type', '==', 'page' );
$field_group->add_rule_group( $rule_group );

$textarea = new Field\Textarea( 'Textarea' );
$field_group->add_field( $textarea );

$field_group->register();

And the error i'm getting in the edit post view just before the field title:

Warning: trim() expects parameter 1 to be string, array given in /xxx/wp-content/plugins/advanced-custom-fields-pro/includes/api/api-helpers.php on line 665

Versions:

ACF PRO 5.7.3
ACF Codifier 1.3.0
WordPress 4.9.8
PHP 7.2.5

The WordPress is just a fresh install with only ACF PRO and ACF Codifier installed.

Any ideas on why this is happening?

Please let me know if you need any further information about my dev environment.

Error with Advanced Custom Fields Pro < 6.3.0

Fatal error: Declaration of Geniem\ACF\Fields\Multitaxonomy::get_term_title($term, $field, $post_id = 0) must be compatible with acf_field_taxonomy::get_term_title($term, $field, $post_id = 0, $unescape = false) in .../mu-plugins/acf-codifier/src/Fields/Multitaxonomy.php on line 141

This error occurs in all versions after 6.3.0.

acf-codifier version in use: 1.41.1.

Repeater data in ACF Options not displayed

Hey!

since version 1.15.1, repeater fields registered for ACF Options stopped showing their data.

It's caused by switching from acf/init to wp_loaded when registering fields.
What was the reason to change this hook?

I tried this on WP 5.1.1 and ACF both 5.7.13 and 5.8.0.

Thanks

How to support registering ACF blocks with block.json method?

Currently ACF uses "the old way" of acf_register_block for block registration. Some newer features (such as block field validation in ACF 6.3) seem to only be supported for JSON-registered blocks. So blocks registered with Codifier are somewhat missing out on some features, and probably increasingly so.

It should be investigated if Codifier could utilize JSON registering in the future.

Flexible Content only holds 1 layout

Flexible Content Field only holds 1 layout. Every time I try to add a new layout to the Flexible Content Field, it overwrites the previous layout and will only show one. Also any content entered into those fields will not save when I publish/update the page/post. It always shows empty fields on reload.

Maybe its my setup that is incorrect? Any feedback and help would be appreciated.
My code is in the text file below.

page-body-components.txt

Screen Shot 2021-07-08 at 11 13 40 AM

Why require php 7.3?

You have updated composer.json to require php >= 7.3. Is there a specific reason for that? Do you actually use some php 7.3 feature somewhere in your code?

Upgrade from 1.13 to 1.14.x breaks ACF fields

When upgrading to 1.14.x from 1.13 I noticed that conditional logic and format_value method stopped working. There might even be more things that have broken when I upgraded but those are the two things I noticed.

My conditional logic on my project looks like this:

        // Radio buttons
        $product_type = ( new Field\Radio( __( 'Type', 'the-dustpress-theme' ) ) )
            ->set_key( $key . '_product_card_type' )
            ->set_name( 'product_card_type' )
            ->add_choice( __( 'Product', 'the-dustpress-theme' ), 'product' )
            ->add_choice( __( 'Category', 'the-dustpress-theme' ), 'category' )
            ->set_required();
        $this->add_field_before( $product_type, 'list' );

        // Conditional logic based on radio buttons
        $cond_logic_product = ( new ConditionalLogicGroup() )
            ->add_rule( $product_type, '==', 'product' );

        $cond_logic_category = ( new ConditionalLogicGroup() )
            ->add_rule( $product_type, '==', 'category' );

        // Get repeater field and add conditional logic for the whole card field area inside repeater
        $repeater = $this->get_field( 'list' );
        $card_automatic = $repeater->get_field( 'card_automatic' );
        $card_automatic->add_conditional_logic( $cond_logic_product );

        // New cards field used when adding terms
        $autom_card_args = [
            'use_card_style' => $this->use_card_style,
            'card_taxonomy'  => $this->card_taxonomy,
            'use_taxonomy'   => $this->use_taxonomy,
        ];

        $category_cards = new CardAutomatic( $this->card_label, $key . '_prod_term', 'prod_term', $autom_card_args );
        $category_cards->set_wrapper_classes( 'geniem-acf-inline' )
            ->add_conditional_logic( $cond_logic_category );
        $repeater->add_field( $category_cards );

format_value stopped working when code looked like this:

        // Video embed url
        $url = ( new Field\Url( __( 'Url of the video as a whole (Youtube or Vimeo)', 'the-dustpress- 
        theme' ) ) )
            ->set_key( $this->key . '_url' )
            ->set_name( 'url' )
            ->set_required();
        $this->add_field( $url );

        $this->format_value( [ $this, 'format_video_url' ] );

I had to move format_value to $url variable in order to get it to work properly.

All fields do not pass parameters for parent constructor

I noticed that for example the Repeater class constructor does not accept all the parameters that the Field base class does. Currently I can not do the following:

new Field\Repeater( 'My field label', 'my-field-key' );

Could the extending field classes accept all the available parameters and pass them to the parent constructor?

How to use the validate_value method

Hi !

I'm trying to use the validate_value method but I don't understand how it works.

I declare the field like this :

$phone_fld = new Field\Text( __( 'Phone' ), 'phone', 'phone'  );
$phone_fld->validate_value( array( '\Validator', 'phone' ) );

And the validator is called like this :

class Validator {
	public function phone( $str ) {
		return preg_match( '/^(0|\+33)[1-9]([-. ]?[0-9]{2}){4}$/', $str );
	}
}

the problem is that I can not get the value of the field ($ str).

Is this the right way to proceed?

Thanks for your help.

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.