Place this to your function.php
/**
ACF Select field: Fix for Safari Browser
*/
add_action('admin_footer', 'my_admin_add_js');
function my_admin_add_js() {
?>
<script>
$(document).ajaxStop(function() {
$('select.select2-hidden-accessible').on('select2:closing', function() {
$('body > span.select2-container.select2-container--default.select2-container--open').hide();
});
$('select.select2-hidden-accessible').on('select2:open', function() {
$('body > span.select2-container.select2-container--default.select2-container--open').css('display','inline-block');
});
});
</script>
<?php
}
I digged into it a little deeper myself because I had to get it fixed for a customer…
There seems to be a bug in select2 libary since latest Safari release which is not really getting fixed, I found some topics on it, i.e.:
https://stackoverflow.com/questions/54666878/page-jumps-to-bottom-after-making-a-selection
https://github.com/select2/select2/issues/5427
For me this seems to be a good workaround for the moment without modifying the select2 js code:
$(document).ajaxStop(function() {
$('select.select2-hidden-accessible').on('select2:closing', function() {
$('body > span.select2-container.select2-container--default.select2-container--open').hide();
});
$('select.select2-hidden-accessible').on('select2:open', function() {
$('body > span.select2-container.select2-container--default.select2-container--open').css('display','inline-block');
});
});
Just add the code to your scripts and it should work… Background:
It is a safari specific problem, that the page scrolls to bottom where the dropdown html element is placed and removed, at the end of <body>… I can’t really figure out why in detail, but if the element is not visible when getting removed the bug does not occur. So I basicly hust hook the libarys events and toogle display!
The whole reason to do this is to not edit them on the sub sites. All field groups added this way should be accessible to anything that needs them. The field groups exist the same as they would exist if loaded from the DB. The only difference is where they are loaded from. If there is some code that cannot access them you’d need to give me more details on this because that should not be the case. If other plugins cannot access the field it’s likely because they are not doing it properly.
“I am also experiencing the second issue on multiple sites. Reverting to 5.7.10 fixes it immediately. I’ve sent in a support ticket just now. Specifically when I have a repeater inside Flexible Content, the functions have_rows() and get_sub_field() return NULL for the repeater. The data IS accessible if I get the FC field with get_field then move through the array. But that takes major rewriting to fix the PHP template files.”
Ah, I commented on another post about this issue but this confirms it’s no just me – repeaters inside Flexible Content are just completely broken. I’m using this as a fundamental field group of dozens and dozens of sites so this is a critical issue for me. Thankfully I found it in dev sites first so will hold-off any updates beyond 5.7.10. Seems the latest couple of updates have really caused some problems, highly unusual for ACF.
I am also experiencing the second issue on multiple sites. Reverting to 5.7.10 fixes it immediately. I’ve sent in a support ticket just now. Specifically when I have a repeater inside Flexible Content, the functions have_rows() and get_sub_field() return NULL for the repeater. The data IS accessible if I get the FC field with get_field then move through the array. But that takes major rewriting to fix the PHP template files.
I have the same problem. I am using ACF to add a couple of custom fields to our Woocommerce product records. As of last week, we can no longer see the custom fields. They are still in the database, but are not accessible to edit.
Any help on how to restore their view would be greatly appreciated, as this is causing a real problem with website maintenance.
I just wrote a plugin to solve some of this without hacking the core. Please see:
https://github.com/owlwatch/acf-multisite-options
This allows you to create network options pages with the same ACF API, you just need to add a network
attribute to the options when using acf_add_options_page
or acf_add_options_sub_page
. For example:
acf_add_options_page([
'network' => true,
'post_id' => 'acf_network_options',
'page_title' => 'Network Options',
'menu_title' => 'Network Options'
]);
I’m not sure what happened to my reply on this thread, so pardon me if this is a duplicate post.
The values are stored in the ‘sitemeta’ table, so they are accessible across sites without needing to use the switch_to_blog function.
@elliot – There is a lot of extra code that could be reduced if there were a filters in place in the acf_get_metadata
, acf_update_metadata
and acf_delete_metadata
functions. Alternatively, this functionality could be built into the core fairly easily. If you are interested, I could create a pull request, but I would need to do so in the Pro repo.
Hope this helps some people. I am using in a production site now and will make this plugin available on the WordPress directory once I’ve tested a bit more.
I just wrote a plugin to solve some of this without hacking the core. Please see:
https://github.com/owlwatch/acf-multisite-options
This allows you to create network options pages with the same ACF API, you just need to add a network
attribute to the options when using acf_add_options_page
or acf_add_options_sub_page
. For example:
acf_add_options_page([
'network' => true,
'post_id' => 'acf_network_options',
'page_title' => 'Network Options',
'menu_title' => 'Network Options'
]);
The values are stored in the ‘sitemeta’ table, so they are accessible across sites without needing to use the switch_to_blog function.
@elliot – There is a lot of extra code that could be reduced if there were a filters in place in the acf_get_metadata
, acf_update_metadata
and acf_delete_metadata
functions. Alternatively, this functionality could be built into the core fairly easily. If you are interested, I could create a pull request, but I would need to do so in the Pro repo.
Hope this helps some people. I am using in a production site now and will make this plugin available on the WordPress directory once I’ve tested a bit more.
Thanks John,
I’m defining the fields in the php, which I will include below. The taxonomy list is generated from a taxonomy defined on the root site. On subsites, I use the query and results hooks to switch to the root site for the query then back to the originating site after the query. I can also include the php and js hooks I’m using. The fields in question are ‘peopletype_taxonomy_list` which filters ‘people_by_type’.
acf_add_local_field_group(array(
'key' => 'group_59d53ce54567f',
'title' => 'People Group',
'fields' => array(
array(
'key' => 'field_59dd3068b24e6',
'label' => 'Copy',
'name' => 'copy',
'type' => 'wysiwyg',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'default_value' => '',
'tabs' => 'all',
'toolbar' => 'full',
'media_upload' => 1,
'delay' => 0,
),
array(
'key' => 'field_5c27f7a668daf',
'label' => 'Add By Individual',
'name' => 'add_by_individual',
'type' => 'true_false',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'message' => '',
'default_value' => 0,
'ui' => 1,
'ui_on_text' => '',
'ui_off_text' => '',
),
array(
'key' => 'field_5c27f7d868db0',
'label' => 'Add By People Type',
'name' => 'add_by_people_type',
'type' => 'true_false',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'message' => '',
'default_value' => 0,
'ui' => 1,
'ui_on_text' => '',
'ui_off_text' => '',
),
array(
'key' => 'field_5c27f7eb68db1',
'label' => 'Add By Site',
'name' => 'add_by_site',
'type' => 'true_false',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'message' => '',
'default_value' => 0,
'ui' => 1,
'ui_on_text' => '',
'ui_off_text' => '',
),
array(
'key' => 'field_59d53cee6770e',
'label' => 'People as Individuals',
'name' => 'people_as_individuals',
'type' => 'repeater',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c27f7a668daf',
'operator' => '==',
'value' => '1',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 0,
'layout' => 'table',
'button_label' => '',
'sub_fields' => array(
array(
'key' => 'field_59d53d266770f',
'label' => 'Person',
'name' => 'person',
'type' => 'post_object',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'post_type' => array(
0 => 'furman-person',
),
'taxonomy' => '',
'allow_null' => 0,
'multiple' => 0,
'return_format' => 'object',
'ui' => 1,
),
),
),
array(
'key' => 'field_5c2d0d1860d0f',
'label' => 'Select People Type',
'name' => 'peopletype_taxonomy_list',
'type' => 'taxonomy',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c27f7d868db0',
'operator' => '==',
'value' => '1',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'taxonomy' => 'furman-person-type',
'field_type' => 'select',
'allow_null' => 0,
'add_term' => 1,
'save_terms' => 0,
'load_terms' => 0,
'return_format' => 'id',
'multiple' => 0,
),
array(
'key' => 'field_5c27fa0480c21',
'label' => 'People by Type',
'name' => 'people_by_type',
'type' => 'repeater',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c27f7d868db0',
'operator' => '==',
'value' => '1',
),
array(
'field' => 'field_5c2d0d1860d0f',
'operator' => '!=empty',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 0,
'layout' => 'table',
'button_label' => '',
'sub_fields' => array(
array(
'key' => 'field_5c27fa0480c22',
'label' => 'Person',
'name' => 'person',
'type' => 'post_object',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'post_type' => '',
'taxonomy' => '',
'allow_null' => 0,
'multiple' => 0,
'return_format' => 'object',
'ui' => 1,
),
),
),
array(
'key' => 'field_5c2d0d734763e',
'label' => 'Select Site',
'name' => 'site_taxonomy_list',
'type' => 'taxonomy',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c27f7eb68db1',
'operator' => '==',
'value' => '1',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'taxonomy' => 'furman-site',
'field_type' => 'select',
'allow_null' => 0,
'add_term' => 1,
'save_terms' => 0,
'load_terms' => 0,
'return_format' => 'id',
'multiple' => 0,
),
array(
'key' => 'field_5c28136b1102f',
'label' => 'People by Site',
'name' => 'people_by_site',
'type' => 'repeater',
'instructions' => '',
'required' => 0,
'conditional_logic' => array(
array(
array(
'field' => 'field_5c27f7eb68db1',
'operator' => '==',
'value' => '1',
),
array(
'field' => 'field_5c2d0d734763e',
'operator' => '!=empty',
),
),
),
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 0,
'layout' => 'table',
'button_label' => '',
'sub_fields' => array(
array(
'key' => 'field_5c28136b11030',
'label' => 'Person',
'name' => 'person',
'type' => 'post_object',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'post_type' => '',
'taxonomy' => '',
'allow_null' => 0,
'multiple' => 0,
'return_format' => 'object',
'ui' => 1,
),
),
),
),
'location' => array(
array(
array(
'param' => 'post_type',
'operator' => '==',
'value' => 'post',
),
),
),
'menu_order' => 0,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => 1,
'description' => '',
));
Here are the hooks being used.
/*
* Action hooks to modify query arguments within the People Group module
*/
/*
* Sets query args for Individual People Field
*/
function individualPeopleQuery( $args, $field, $post_id ) {
$args['post_type'] = \Furman\PostTypes\People::POST_TYPE;
return $args;
}
add_filter('acf/fields/post_object/query/key=field_59d53d266770f', 'individualPeopleQuery', 10, 3);
/*
* Ensures that the title is correct when querying from child sites
*/
function individualPeopleResult( $title, $post ) {
if ( strpos( $title, 'no title' ) ) {
$title = $post->post_title;
}
return $title;
}
add_filter('acf/fields/post_object/result/key=field_59d53d266770f', 'individualPeopleResult', 10, 3);
function peopleTypeTaxonomyQuery( $args, $field, $post_id ) {
if ( ! Site::isRoot() ) {
$currentSite = get_current_blog_id();
switch_to_blog( Site::getRootBlogId() );
set_transient( 'peopleTypeTaxonomyQuery', $currentSite );
}
return $args;
}
add_filter('acf/fields/taxonomy/query/key=field_5c2d0d1860d0f', 'peopleTypeTaxonomyQuery', 10, 3);
function peopleTypeTaxonomyResult( $title ) {
$originatingSite = get_transient( 'peopleTypeTaxonomyQuery' );
if ( Site::isRoot() && $originatingSite ) {
delete_transient( 'peopleTypeTaxonomyQuery' );
switch_to_blog( $originatingSite );
}
return $title;
}
add_filter('acf/fields/taxonomy/result/key=field_5c2d0d1860d0f', 'peopleTypeTaxonomyResult', 10, 3);
//add_filter('acf/load_field/key=field_5c2d0d1860d0f', 'peopleType');
/*
* Set up custom query args received from AJAX requests.
*/
function peopleByTypeQuery( $args, $field, $post_id ) {
if ( ! Site::isRoot() ) {
$currentSite = get_current_blog_id();
switch_to_blog( Site::getRootBlogId() );
set_transient( 'peopleByTypeQuery', $currentSite );
}
$args['post_type'] = \Furman\PostTypes\People::POST_TYPE;
if ( isset( $_POST['query-args'] ) ) {
$termId = $_POST['query-args']['term_id'];
$args['tax_query'] = array(
array(
'taxonomy' => \Furman\Taxonomies\PeopleTypes::TAXONOMY,
'field' => 'term_id',
'terms' => $termId
)
);
}
return $args;
}
add_filter('acf/fields/post_object/query/key=field_5c27fa0480c22', 'peopleByTypeQuery', 10, 3);
function peopleByTypeResult($title) {
$originatingSite = get_transient( 'peopleByTypeQuery' );
if ( Site::isRoot() && $originatingSite ) {
delete_transient( 'peopleByTypeQuery' );
switch_to_blog( $originatingSite );
}
return $title;
}
add_filter('acf/fields/post_object/result/key=field_5c27fa0480c22', 'peopleByTypeResult', 10, 3);
function peopleSiteTaxonomyQuery( $args, $field, $post_id ) {
if ( ! Site::isRoot() ) {
$currentSite = get_current_blog_id();
switch_to_blog( Site::getRootBlogId() );
set_transient( 'peopleSiteTaxonomyQuery', $currentSite );
}
return $args;
}
add_filter('acf/fields/taxonomy/query/key=field_5c2d0d734763e', 'peopleSiteTaxonomyQuery', 10, 3);
function peopleSiteTaxonomyResult( $title ) {
$originatingSite = get_transient( 'peopleSiteTaxonomyQuery' );
if ( Site::isRoot() && $originatingSite ) {
delete_transient( 'peopleSiteTaxonomyQuery' );
switch_to_blog( $originatingSite );
}
return $title;
}
add_filter('acf/fields/taxonomy/result/key=field_5c2d0d734763e', 'peopleSiteTaxonomyResult', 10, 3);
function peopleBySiteQuery( $args, $field, $post_id ) {
if ( ! Site::isRoot() ) {
$currentSite = get_current_blog_id();
switch_to_blog( Site::getRootBlogId() );
set_transient( 'peopleBySiteQuery', $currentSite );
}
$args['post_type'] = \Furman\PostTypes\People::POST_TYPE;
if ( isset( $_POST['query-args'] ) ) {
$termId = $_POST['query-args']['term_id'];
$args['tax_query'] = array(
array(
'taxonomy' => \Furman\Taxonomies\Sites::TAXONOMY,
'field' => 'term_id',
'terms' => $termId
)
);
}
return $args;
}
add_filter('acf/fields/post_object/query/key=field_5c28136b11030', 'peopleBySiteQuery', 10, 3);
function peopleBySiteResult($title) {
$originatingSite = get_transient( 'peopleBySiteQuery' );
if ( Site::isRoot() && $originatingSite ) {
delete_transient( 'peopleBySiteQuery' );
switch_to_blog( $originatingSite );
}
return $title;
}
add_filter('acf/fields/post_object/result/key=field_5c27fa0480c22', 'peopleBySiteResult', 10, 3);
Here are the JS API hooks in use
document.addEventListener('DOMContentLoaded', () => {
acf.add_action('select2_init', function( $select, args, settings, field ){
console.log('SELECT2_SELECT:', $select);
console.log('SELECT2_ARGS:', args);
console.log('SELECT2_SETTINGS:', settings);
console.log('SELECT2_FIELD:', field);
// $select (jQuery) select element
// args (object) args given to the select2 function
// settings (object) settings given to the acf.select2 function
// field (object) field instance
});
/*
Uses the ACF JS API. These filters allow the post object fields to be filtered based on a separate acf taxonomy field.
*/
acf.add_filter('select2_ajax_data', function (data, args, $input, field, instance) {
//People Type filter
if (field[0].dataset.key === 'field_5c27fa0480c22') {
let taxonomySelect = $('.acf-field-5c2d0d1860d0f').find('.select2-hidden-accessible').select2('data');
data['query-args'] = {
'taxonomy': 'furman-person-type',
'term_id': taxonomySelect[0].id,
'term_title': taxonomySelect[0].text
};
}
//Site filter
if (field[0].dataset.key === 'field_5c28136b11030') {
let taxonomySelect = $('.acf-field-5c2d0d734763e').find('.select2-hidden-accessible').select2('data');
data['query-args'] = {
'taxonomy': 'furman-site',
'term_id': taxonomySelect[0].id,
'term_title': taxonomySelect[0].text
};
}
// return
return data;
});
});
The only advice I can give you is to look in the code of the site and make sure that someone hasn’t done something to hide the admin or make it otherwise not accessible https://www.advancedcustomfields.com/resources/how-to-hide-acf-menu-from-clients/
Hi, thanks for pointing to acf_maybe_get_POST()
! As I don’t want to edit core files, I wrote a helper which works for me so far within the block template:
function my_acf_post_id() {
if ( is_admin() && function_exists( 'acf_maybe_get_POST' ) ) :
return intval( acf_maybe_get_POST( 'post_id' ) );
else :
global $post;
return $post->ID;
endif;
}
Definitely, I agree that a block instance should contain the post ID or it should be accessible in another elegant way.
So yesterday, I added the max_input_vars to my .htaccess file. No change. I then contacted my host about adding it to my php.ini file. Which is only accessible via SSH. Something I don’t work in. After much hand holding from my host’s tech support, I was able, through Mac Terminal to get into the php.ini file and change the commented out max_input_vars to uncommented and changed the 1000 to 5000. After all that, the plugin still says the max vars is 1000 and my ACF repeater will not save. Not sure what else to do. Not sure if rebuilding my ACF form in a different way would make a difference. For instance, I could make the parent repeater, not a repeater and instead make each of those individual repeaters. So that their is no nesting. But they are still all on the same page. It might make fewer vars but I think I would still hit 1000 pretty quickly.
I had multiple things going on but in the end this was the code that worked for me. Feel free to dissect out of this what you need. In my case the client wanted the featured projects to be at the top and then added the criteria that they would also like to exclude some posts from displaying in the list but still wanted them accessible as single posts. With this my featured posts were at the top and my excluded posts did not display. And if a user clicked both boxes it defaulted to not display.
'post_type' => 'work',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_key' => 'featured_project',
'orderby' => 'meta_value date',
'order' => 'DSC',
'meta_query' => array(
'relation' => 'OR',
'exclude_posts' => array(
'relation' => 'OR',
array(
'key' => 'exclude_project',
'compare' => '!=',
'value' => '1'
),
array(
'key' => 'exclude_project',
'type' => 'BOOLEAN',
'value' => false
),
array(
'key' => 'exclude_project',
'compare' => 'NOT EXISTS'
),
),
'featured_posts' => array(
'relation' => 'AND',
array(
'key' => 'featured_project',
'value' => '1',
'compare' => '='
),
array(
'key' => 'exclude_project',
'compare' => '!=',
'value' => '1'
),
),
),
);
Hi @rob1969
1. Yes, the gallery field would be the best approach to implement he carousel using ACF.
2. The repeater would also be the best option for the frontend listing.
Please note that ACF only works to make sure that the field values are accessible from the frontend using the API. The design and the layout is dependent on your sites design and implementation.
Hope this helps.
This is an important bug to get fixed. We have been working on enhancements to CKEditor to help people author content more accessible to people with disabilities. Many WordPress installations use your plug-ins, so I encourage you to fix this as soon as possible.
More information on a11yFirst project:
https://a11yfirst.library.illinois.edu/
WooCommerce Product Variations are *all* saved via a single POST request.
To differentiate between product variation fields, WooCommerce names each field field_name[variation_id]
so that it is accessible as $_POST['field_name'][$variation_id]
.
ACF field data is located in $_POST['acf'][...]
and can only have one of each field.
ACF’s acf()->input->save_post( $post_id )
method uses $_POST['acf']
data, so it cannot contain fields for another variation.
We need to allow duplicate ACF fields to exist within a single <form>
without having them overwrite each other’s value within $_POST['acf']
.
We can achieve this by renaming the field name prefix acf[...]
to acf_varation[variation_id][...]
and then set $_POST['acf']
to $_POST['acf_varation'][$variation_id]
when saving.
$GLOBALS['wc_loop_variation_id'] = null;
function is_field_group_for_variation($field_group, $variation_data, $variation_post) {
return (preg_match( '/Variation/i', $field_group['title'] ) == true);
}
add_action( 'woocommerce_product_after_variable_attributes', function( $loop_index, $variation_data, $variation_post ) {
$GLOBALS['wc_loop_variation_id'] = $variation_post->ID;
foreach ( acf_get_field_groups() as $field_group ) {
if ( is_field_group_for_variation( $field_group, $variation_data, $variation_post ) ) {
acf_render_fields( $variation_post->ID, acf_get_fields( $field_group ) );
}
}
$GLOBALS['wc_loop_variation_id'] = null;
}, 10, 3 );
add_action( 'woocommerce_save_product_variation', function( $variation_id, $loop_index ) {
if ( !isset( $_POST['acf_variation'][$variation_id] ) ) {
return;
}
$_POST['acf'] = $_POST['acf_variation'][$variation_id];
acf()->input->save_post( $variation_id );
}, 10, 2 );
add_filter( 'acf/prepare_field', function ( $field ) {
if ( !$GLOBALS['wc_loop_variation_id'] ) {
return $field;
}
$field['name'] = preg_replace( '/^acf\[/', 'acf_variation[' . $GLOBALS['wc_loop_variation_id'] . '][', $field['name'] );
return $field;
}, 10, 1);
This is an older question but I thought I’d chime in with what I believe was the issue here and this question ranks high in the searches.
In a multi-site situation where you’re hardcoding the fields via PHP you need to make sure those options are being initialized on all the sub sites as well. If you have a global options page on the primary site within a Multisite network but those options aren’t also initialized on the sub sites, you’ll get the above behavior. Specifically the data for the field is accessible but it doesn’t bring in any of the ACF-specific formatting. For example, a repeater field will just return the number of sub-items, not the actual content of the sub-items.
if i dont missunderstood what @semlohj wish it is already possible:
at backend primary with the help of the clone-field.
for the frontend with help of includes that contains the reusable block.
with help of that, you can update the original fieldgroup and the changes apply to the clones
i do for example:
fieldgroup teaserbox = text,textarea,image,link
fieldgroup halfcolum = flexible-field with a layout, that include clone-field:teaserbox
fieldgroup fullcolumn = flexible-field with a layout, that include a repeater with clone-field:teaserbox inside
fieldgroup content = flexible-field with 2 layout, one inlude clone-field:fullcolum || the other include prefixed clone-field: halfcolumn, prefixed clone-field: halfcolumn
now i can add another field to teaserbox and fullcolumn, left_halfcolumn, right_halfcolumn where updated
hope that help. else may @acf-support can reproduce what i say and give a more detailed answer
Thanks for the info @jenwachter .
FWIW, I’ll post here the fix to somewhat unrelated bugs I was experiencing with revisions that arose from trying to set the title of posts dynamically (based on ACF fields) on save.
If you try to set native WP fields in a save_post hook (or even acf_save_post), you’ll end up with “extra” bogus revisions, often which don’t restore properly, or restore but ignore ACF changed fields.
My fix was to listen for the wp_insert_post_data event, which I think ACF itself rides on, and make my change there, only referring to ACF fields by their ID since they wouldn’t be accessible via get_field at this point.
// Update dynamic title on save.
function bio_dynamic_title( $data, $postarr ) {
// Bail if this isn't the right post type or if ACF wasn't submitted.
if ( $data['post_type'] !== 'bio' || !array_key_exists( 'acf', $postarr ) ) {
return $data;
}
$title = sanitize_text_field( full_name(
$postarr['acf']['field_587e607692f49'], // first_name
$postarr['acf']['field_589a17cb1cdd3'], // middle_initial
$postarr['acf']['field_587e609192f4a'], // last_name
$postarr['acf']['field_587e6ee94602b'] // suffix
));
$data['post_title'] = $title;
$data['post_name'] = sanitize_title( $title );
return $data;
}
add_filter( 'wp_insert_post_data', 'bio_dynamic_title', 10, 2 );
After some searching, ACF doesn’t make this possible out of the box. Wouldn’t be a terrible idea to add it but I understand why they don’t. Or at the very least, give the thickbox left-hand menu options ( like “Add Media” does ) so you can add in objects with URLs or compatible with External Media Library plugins ( which automagically pull videos from channels for you to use ).
Anyway, the idea is that you need the oembed objects ( vimeo / youtubes ) as Media Objects so they’re accessible from the media library. This is not a common gripe but luckily there are a few plugins out there that make it happen.
Add External Media is a relative small, not used very much plugin which does exactly that at which point I was able to add the video to the gallery, get it, and display it as normal.
The only caveat is, since the “Add to Gallery” button doesn’t give us access to the normal media left-hand links, add it using a separate method like the posts “Add Media” button before you have access to add it to The Gallery. It is kind of a hassle but not as much as creating a bunch of secondary fields and interweaving them with the gallery.
Hopefully this helps future readers!
Sorry – I may not have made myself clear – I want to grab the terms/categories from within the if ($post_object->ID == $currentPageID) so only the documents connected to the post object display on the respective page.
The method you have sent me grabs ALL of the terms/categories and displays it on all pages…
Just to reiterate, the client wants the document uploader to be accessible through one page (options) rather than on a page by page basis, as it is too difficult for them to organise.
Big bump here….does anyone have an update on where this is at for a fix? It does seem like we really need an ACF setting for a site’s Google Map API key. This key would allow the maps to work on /wp-admin/ but then also be accessible to developers for use on front end implementations as well.
Is this approach something that others see as a solution?
Got it. Thanks.
The flexible content field is really powerful but a little more complex than ordinary fields. In terms of documentation, DIY developers like myself (i.e., people building or modifying themes for their own sites) might benefit from a few videos that talk you through setting up the fields in the ACF editor, using them in the WordPress editor, and then getting output through a page template.
ACF Pro is brilliant — especially for building landing pages — but it requires a bit of work to get it going in a theme. A few video tutorials would go a long way toward making it more accessible to the DIY developer crowd — especially if you could target it to users of particular development frameworks, like Genesis.
When I open the frontend page with the ACF Form, then click the submit button, a new post is created. If I go on the backend to that post, there are ACF fields with data copied over to them the way I would expect. This part is all fine and good. I tried the two suggestions you made, and there was no difference between the the results of what I was doing and the two methods you suggested, unfortunately.
I’m not sure if I’m being really dense and not getting your point, but I’ve been through the forums and resources 100x times, I could recite the content of the acf/save_post and update_field.
During the “saving” process, the fields I copy over (via the first block of code in the first post) are not accessible to the code in the second set of code; however after the “saving” process is completed and the page loads up, the fields are there. I’m trying to understand why the calculations actions that are scheduled (priority 50) to occur after the fields are filled in (priority 30) aren’t working. I either need to figure out why the priorities aren’t working like I’d expect, or an action to execute after a post save, or a hack to force the post to save twice.
Hi @blairw,
Thanks for the post.
You can make the Repeater field content accessible site wide and then call the values on all the pages on your site by mapping the repeater on an ACF options page.
Here is more info on this: https://www.advancedcustomfields.com/resources/acf_add_options_page/
Welcome to the Advanced Custom Fields community forum.
Browse through ideas, snippets of code, questions and answers between fellow ACF users
Helping others is a great way to earn karma, gain badges and help ACF development!
We use cookies to offer you a better browsing experience, analyze site traffic and personalize content. Read about how we use cookies and how you can control them in our Privacy Policy. If you continue to use this site, you consent to our use of cookies.