Skip to content

Instantly share code, notes, and snippets.

@zackpyle
Last active May 23, 2024 18:33
Show Gist options
  • Save zackpyle/35774c5c394684f054eefdbdc284545e to your computer and use it in GitHub Desktop.
Save zackpyle/35774c5c394684f054eefdbdc284545e to your computer and use it in GitHub Desktop.
Collection of useful ACF snippets #acf

Collection of useful ACF Snippets

  1. Add Field to Body Class
  2. Custom Excerpt Field
  3. Default Image
  4. Google Address Shortcode
  5. Google Map Multiple Marker Shortcode
  6. Numbers with commas
  7. Repeater + Bootstrap Modal + Modal Nav
  8. Repeater with button for Show-Hide
  9. Shortcode for Truncated Field Value
<?php // ignore - for formatting purposes
function add_acf_field_body_class($class) {
if (!function_exists('get_field')) return $class;
$value = get_field('your_acf_field'); // Add your ACF field here
$class[] = $value;
return $class;
}
add_filter('body_class', 'add_acf_body_class');
// same function but for acf checkboxes that returns an array of all options and adds all checked as classes
function add_acf_checkbox_field_body_class($classes) {
if (!function_exists('get_field')) return $classes;
$checked_options = get_field('your_acf_checkbox_field'); // Add your ACF field here
foreach($checked_options as $option) {
$classes[] = $option;
}
return $classes;
}
add_filter('body_class', 'add_acf_checkbox_field_body_class');
// For Taxonomy Archives
function add_acf_field_body_class_tax($class) {
if (!function_exists('get_field')) return $class;
$term = get_queried_object();
$value = get_field('your_acf_field', $term); // Add your ACF field here
$class[] = $value;
return $class;
}
add_filter('body_class', 'add_acf_body_class_tax');
<?php // ignore - for formatting purposes
// Hooks an ACF field into saving into the posts excerpt
add_action('save_post', 'customExcerptSetByACF', 50);
function customExcerptSetByACF() {
global $post;
$post_id = ( $post->ID );
$post_excerpt = get_field( 'post_excerpt', $post_id ); // ACF field here
if ( ( $post_id ) AND ( $post_excerpt ) ) {
$post_array = array(
'ID' => $post_id,
'post_excerpt' => $post_excerpt
);
remove_action('save_post', 'customExcerptSetByACF', 50); // Unhook this function so it doesn't loop infinitely
wp_update_post( $post_array );
add_action( 'save_post', 'customExcerptSetByACF', 50); // Re-hook this function
}
}
<?php //ignore this line - for formatting only
// Extends ACF default field value to Image field type
// Add default image setting to acf image field
add_action('acf/render_field_settings/type=image', 'add_default_value_to_image_field');
function add_default_value_to_image_field($field) {
acf_render_field_setting( $field, array(
'label' => 'Default Image',
'instructions' => 'Appears when creating a new post',
'type' => 'image',
'name' => 'default_value',
));
}
// Show the default image
add_filter('acf/load_value/type=image', 'reset_default_image', 10, 3);
function reset_default_image($value, $post_id, $field) {
if (!$value) {
$value = $field['default_value'];
}
return $value;
}
<?php // ignore - for formatting purposes
// ACF Google Map Field -> Address Shortcode
add_shortcode( 'acf_address' , function( $atts ) {
if (!function_exists('get_field') ) return '';
$atts = shortcode_atts( array( 'field' => false , 'sub' => 'address' ) , $atts, $shortcode = 'acf_address' );
if ($atts[ 'field' ] && $map = get_field( $atts[ 'field'] ) ) {
if ( isset( $map[ $atts['sub'] ] ) ) return $map[ $atts['sub'] ];
}
return '[ something went wrong ]';
} );
/*
[acf_address field="ACF_FIELD_NAME" sub="address"]
Fields you can pull:
address
lat
lng
zoom
place_id
street_number
street_name
street_name_short
city
state
state_short
post_code
country
country_short
*/
<?php //ignore this line - only for formatting
// Output all posts via the default main loop and show the title and address field in the marker and link that to the post
function acf_multiple_marker_main_query_map() {
ob_start();
echo "<div class='map-container'><div class='wrap'><div class='acf-map'>";
while ( have_posts() ) : the_post();
$location = get_field('property_address'); // Add your ACF address field here
$title = get_the_title();
if( !empty($location) ) {
?>
<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
<h4><a href="<?php the_permalink(); ?>" rel="bookmark"> <?php the_title(); ?></a></h4>
<p class="address"><?php echo $location['address']; ?></p>
</div>
<?php
}
endwhile;
echo '</div></div></div>';
return ob_get_clean();
}
add_shortcode( 'acf_multi_marker_main', 'acf_multiple_marker_main_query_map' ); // Create shortcode [acf_multi_marker_main]
<?php // ignore - for formatting purposes
add_shortcode( 'acf_multiple_marker', 'acf_multiple_marker' ); // Create shortcode [acf_multiple_marker]
// Output all posts via a custom loop of the CPT and show the title and address field in the marker and link that to the post
function acf_multiple_marker() {
ob_start();
$args = array(
'post_type' => 'property', // Add your CPT slug here
'posts_per_page' => -1,
);
$the_query = new WP_Query($args);
echo "<div class='map-container'><div class='wrap'><div class='acf-map'>";
while ( $the_query->have_posts() ) : $the_query->the_post();
$location = get_field('property_address'); // Add your ACF address field here
$title = get_the_title();
if( !empty($location) ) { // Edit the markup you want to output below
?>
<div class="marker" data-lat="<?php echo $location['lat']; ?>" data-lng="<?php echo $location['lng']; ?>">
<h4><a href="<?php the_permalink(); ?>" rel="bookmark"> <?php the_title(); ?></a></h4>
<p class="address"><?php echo $location['address']; ?></p>
</div>
<?php
}
endwhile;
echo '</div></div></div>';
wp_reset_postdata();
return ob_get_clean();
}
<?php // ignore - for formatting purposes
// Return ACF Number Fields Formatted with Commas on the Frontend
add_filter('acf/format_value/name=ACF_FIELD_NAME', 'acf_number_comma', 20, 3);
add_filter('acf/format_value/name=ANOTHER_ACF_FIELD_NAME', 'acf_number_comma_decimal', 20, 3);
//Use to convert all number fields instead of individual fields
add_filter('acf/format_value/type=number', 'acf_number_comma', 30, 3);
// Without Decimal
function acf_number_comma($value, $post_id, $field) {
$value = number_format(floatval($value));
return $value;
}
// With Decimal
function acf_number_comma_decimal($value, $post_id, $field) {
$value = number_format(floatval($value), 2);
return $value;
}
// Example uses Floor Plans for a home builder
jQuery(document).ready(($) => {
// give floor plans and modals matching IDs
const buttons = $(".item .modal-btn");
const modals = $(".item .modal");
buttons.attr('data-target', (index) => {
return '#fp' + index;
});
modals.attr('id', (index) => {
return 'fp' + index;
});
// make modal nav work
$(".modal-list>li").each((index, item) => {
const prevModal = $(this).find('.prev-modal');
const nextModal = $(this).find('.next-modal');
const currentModal = $(this).find('.modal');
const prevSiblingModal = $(this).prev().find('.modal');
const nextSiblingModal = $(this).next().find('.modal');
// previous service
if ($(this).prev().length) {
prevModal.attr('data-target', "#" + prevModal.attr('id'));
} else {
currentModal.addClass('first-item');
}
// next service
if ($(this).next().length) {
nextModal.attr('data-target', "#" + nextModal.attr('id'));
} else {
currentModal.addClass('last-item');
}
// arrow keys for modal nav
$('.modal').keydown((e) => {
switch (e.which) {
case 37: // left arrow key
$(".modal-nav-btn.prev-modal:visible").click();
break;
case 39: // right arrow key
$(".modal-nav-btn.next-modal:visible").click();
break;
}
});
});
});
// This is ACF repeater syntax for Beaver Builder/Themer
<h3>Floor Plan</h3>
<ul class="modal-list">
[wpbb-acf-repeater name='property_details_floor_plan']
<li class="item">
<button class="modal-btn" data-toggle="modal">[wpbb post:acf type='text' name='floor_plan_text']</button>
</li>
<div class="modal fade item-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-nav">
<button class="modal-nav-btn prev-modal" data-toggle="modal" data-target="#exampleModal" data-dismiss="modal">
<svg xmlns="http://www.w3.org/2000/svg" width="23.312" height="45.747" viewBox="0 0 23.312 45.747">
<path id="Path_144" data-name="Path 144" d="M1675.7,4981.259l-13.692,17.254,13.692,17.254" transform="translate(-1658.006 -4975.64)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"/>
</svg>
</button>
<button class="modal-nav-btn next-modal" data-toggle="modal" data-target="#exampleModal" data-dismiss="modal">
<svg xmlns="http://www.w3.org/2000/svg" width="23.312" height="45.747" viewBox="0 0 23.312 45.747">
<path id="Path_144" data-name="Path 144" d="M1662.006,4981.259l13.692,17.254-13.692,17.254" transform="translate(-1656.386 -4975.64)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="8"/>
</svg>
</button>
</div>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<img src="[wpbb post:acf type='image' name='floor_plan_img' image_size='large' display='url']">
</div>
</div>
</div>
</div>
[/wpbb-acf-repeater]
</ul>
// ACF Repeater + Hide/Show jQuery
jQuery(document).ready(function($) {
// Hide all expanded steps
$('.expandedstep').hide()
//Show expanded steps while in the builder
$('html.fl-builder-edit .expandedstep').show();
// When an expand step button is clicked
$('.expandstepbtn').on('click', function(e) {
e.preventDefault();
// Change Text for Expand Button
const stepbtntxtchange = $('.expandedstep').is(':visible') ? 'Expand' : 'Collapse';
$(this).text(stepbtntxtchange);
// Toggle the next adjacent sibling
$(this).next('.expandedstep').slideToggle(250);
});
});
/* This is ACF repeater syntax for Beaver Builder/Themer */
[wpbb-acf-repeater name='REPEATER_FIELD_NAME']
<div class="projectstep">
/* Always Displays */
[wpbb post:acf type='text' name='project_step']
/* Expands after button is clicked */
<button class="expandbtn">Expand</button>
<div class="expandedstep">
[wpbb post:acf type='text' name='expanded_project_step']
</div>
</div>
[/wpbb-acf-repeater]
<?php //ignore this line - only for formatting
// Register the truncated ACF shortcode
add_shortcode('truncated_acf_field', 'truncated_acf_field_shortcode');
function truncated_acf_field_shortcode($atts) {
if( function_exists('get_field') ) {
$atts = shortcode_atts( array(
'length' => 100, // Set the default to 100 characters if user doesn't define their own in the shortcode
'name' => '',
'ellipsis' => 'true' // Defaults to true if user leaves this out of the shortcode
), $atts );
// Check to make sure an ACF field name was added
if (empty($atts['name'])) {
return "Please add an ACF field name to the shortcode";
}
$field_value = get_field($atts['name']);
// Truncate the description to the defined number of characters and trim white space at the end
$truncated_field_value = mb_substr($field_value, 0, $atts['length']);
$truncated_field_value = rtrim($truncated_field_value);
// Add the ellipsis if the attribute is true and the original value is longer than the defined length
if ($atts['ellipsis'] === 'true' && mb_strlen($field_value) > $atts['length']) {
$truncated_field_value .= '...';
}
return $truncated_field_value;
} else {
return '<p>Please activate the Advanced Custom Fields plugin</p>';
}
}
// And your shortcode will look like [truncated_acf_field name="field_name" length="150"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment