WordPress Advanced Custom Fields - markhowellsmead/helpers GitHub Wiki
Advanced Custom Fields is a powerful plugin which allows the addition and customization of complex custom fields. These fields allow an extensively customized editorial interface which works alongside – or as a replacement of – the standard content field.
By using the plugin's import and export functions, you can easily create reusable configuration files in JSON format, which can defined once and then copied between projects.
Unlock a form
For example, when bailing from an unsuccessful custom validation within the success
callback on acf.validateForm
. (Remember to pass the jQuery form object, not the DOM element.)
Lock it before the custom checks.
acf.lockForm($form);
Then unlock it again as appropriate.
acf.unlockForm($form);
Field types for PHP
Clone
In a simple installation, individual fields can be added to a specific page or post type. However, if all of the fields are defined in a single configuration (“field group”), it can be difficult to reuse a particular set of fields in a different project. This reuse makes sense if the configuration is particularly complex.
For example, you want to have a “Content elements” field group which contains a series of optional content elements for pages and posts. One of the content element types is a multimedia gallery, in which each gallery item can be an image or video.
Firstly, create a single field group for the multimedia gallery called Module: Multimedia Gallery. This contains the configuration for the gallery and its fields. The multimedia gallery contains a single Flexible Content field, in which various layout types are defined. (Image, video.) Set the active status of this field to “No”, so that it can't be added directly to the page.
Now use the special Clone field type within the “Rows” field group. This field can then reference Module: Multimedia Gallery, which draws in the fields from the other field group.
In this way, you can start collating a series of modular configuration field groups, then implement them in a field group for the specific project you're working on.
Add ACF options page in wp-admin
Add the following PHP to your theme (or plugin) through a function hooked to 'init'
. Then add the settings fields to the custom settings page using an ACF Field Group.
Use a float value for position
to ensure that the new page is specifically next to the required main options page. Here, as the very first page after Settings (Einstellungen), which has the position
80. (Ref.)
// Site options
if (function_exists('acf_add_options_page')) {
add_action('init', function(){
acf_add_options_page(array(
'page_title' => __('Custom Options'),
'menu_title' => '',
'menu_slug' => 'custom-options',
'post_id' => 'custom_options',
'capability' => 'edit_theme_options',
'icon_url' => 'dashicons-admin-settings',
'position' => '80.01'
));
});
}
Custom colours in the colour picker
Enqueue this in the footer of the admin page using the admin_enqueue_scripts
action hook.
acf.add_filter('color_picker_args', function( args, $field ){
args.palettes = ['#5ee8bf', '#2f353e', '#f55e4f']
return args;
});
Import/Export ACF fields using WP CLI
Add styling to backend radio buttons
Add date column to ACF Field Group list page in WordPress Admin
https://github.com/markhowellsmead/helpers/blob/master/wordpress/ACF/CustomAdminColumns.php
Content fields aren't being copied over when using Polylang
Ensure that the individual field groups are translated. Enable this in Polylang Settings » Custom post types and Taxonomies.
Sort Post Object entries by menu order
e.g. if the Post Types Order plugin is being used.
add_filter('acf/fields/post_object/query', function ($args) {
$args['orderby'] = 'menu_order';
$args['order'] = 'ASC';
return $args;
}, 10, 1);
Important: Synchronization for Field Groups in the Polylang settings must remain deactivated.
ACF Form
Use the ACF form technology in the frontend.
Use with select2
The select2 library is loaded automatically. Initialize it in your own JavaScript. Note that the field Modernes Auswahlfeld configuration must be active, or the field will throw odd JavaScript errors like b is not defined
or Uncaught TypeError: Cannot read property 'slice' of undefined
.
Translate field labels in frontend
This code is intended for use with Polylang. It adds the field labels to the Polylang string translations screen.
add_action('init', function () {
foreach (acf_get_field_groups() as $group) {
$fields = acf_get_fields($group['ID']);
if (is_array($fields) && count($fields)) {
foreach ($fields as &$field) {
pll_register_string('form_field_group'.$group['ID'].'_label_'.$field['name'], $field['label'], 'acf_form_fields');
}
}
}
});
add_filter('acf/prepare_field', function ($field) {
if (!is_admin()) {
$field['label'] = pll__($field['label']);
}
return $field;
}, 10, 1);
User email validation
For use with acf_form
. (This belongs in my usual PHP class structure.)
add_filter('acf/validate_value/name=user_email', [$this, 'userEmailExists'], 10, 2);
…
public function userEmailExists($valid, $value)
{
if (!$valid) {
return $valid;
}
return !empty($value) && !email_exists($value) ? true : _x('That email address is already associated with an existing user.', 'Error message for existing email address', 'myPluginKey');
}
Dynamically populate fieldgroup select field
/**
* Using the relation field to select ACF field groups only
* works when these are created via the ACF editor and therefore
* available in the database. This alternative for a
* dynamically-populated select field gets ALL field groups,
* including those registered via PHP.
*
* [email protected] 25.2.2021
*
* @param array $field
* @return array
*/
add_filter('acf/load_field/name=sht_selected_fieldgroup', [$this, 'fieldGroupSelect']);
…
public function fieldGroupSelect($field)
{
$field['choices'] = [
'' => _x('Bitte auswählen', 'Form field placeholder', 'sht'),
];
$field_groups = acf_get_local_field_groups();
array_multisort(array_column($field_groups, 'title'), $field_groups);
foreach ($field_groups as $id => $data) {
$field['choices'][$id] = $data['title'];
}
return $field;
}