Skip to content

Instantly share code, notes, and snippets.

@mwhiteley16
Created October 13, 2025 12:04
Show Gist options
  • Save mwhiteley16/229787c2469a537179be248cbfb8a2e1 to your computer and use it in GitHub Desktop.
Save mwhiteley16/229787c2469a537179be248cbfb8a2e1 to your computer and use it in GitHub Desktop.
ACF Block Registration Example
(function($){
// front end render on first instance of block only
$(document).ready(function(){
$('.block-faq').each(function(){
faqBlockInit();
return false;
});
});
// back end trigger
if( window.acf ) {
window.acf.addAction( 'render_block_preview/type=wd/acf-faq', acfFaqBlockInit );
}
// set inital block counter
let blockCountFaq = 0;
// back end render for first instance of block only
function acfFaqBlockInit(block) {
blockCountFaq++
if (blockCountFaq > 1) return;
faqBlockInit();
}
// the jQuery
function faqBlockInit() {
$('.block-faq__toggle-question').on( 'click', function() {
$(this).attr('aria-pressed', function (i, attr) {
return attr == 'true' ? 'false' : 'true'
});
$(this).siblings('.block-faq__toggle-answer').slideToggle().attr('aria-expanded', function (i, attr) {
return attr == 'true' ? 'false' : 'true'
});
});
}
})(jQuery);
{
"name": "wd/acf-faq",
"title": "FAQ Block",
"description": "A block to show FAQ items with an optional toggle.",
"category": "wd-blocks",
"icon": "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22.5 22.5'><defs><style>.a{fill:#222;}.b{fill:#1fa8af;}</style></defs><path class='a' d='M20.17,4a10.17,10.17,0,0,0-7-3.5L11.91.38h-.18a.64.64,0,0,0-.47.13A.68.68,0,0,0,11,.93L10.6,3.79a.48.48,0,0,0,.12.43.54.54,0,0,0,.44.18h.11l1.44.17c3.94.45,6.12,2.69,5.84,6a8.37,8.37,0,0,1-2.49,5.12A8.14,8.14,0,0,1,10,18.06l-.65,0H9.15a.8.8,0,0,0-.5.17.68.68,0,0,0-.25.44L8,21.5a.49.49,0,0,0,.12.42.57.57,0,0,0,.45.18h.17l1,0h.34a11.61,11.61,0,0,0,8.21-3.39,12.76,12.76,0,0,0,3.77-7.92A9.49,9.49,0,0,0,20.17,4Z'/><path class='b' d='M9.2,17h.15L10,17a7.61,7.61,0,0,0,3.64-.77L15,6.15a8.65,8.65,0,0,0-2.33-.57l-1-.12-1,7.35L9.23,7c-.11-.45-.33-.67-.65-.67H7.16c-.29,0-.5.22-.65.67L5.1,12.81,3.82,3a.55.55,0,0,0-.61-.55H.78a.36.36,0,0,0-.29.16A.6.6,0,0,0,.37,3a.5.5,0,0,0,0,.18L2.53,19.22a1.07,1.07,0,0,0,.23.6.64.64,0,0,0,.53.23H5.16c.37,0,.61-.21.73-.65l2-7.19Z'/></svg>",
"apiVersion": 3,
"keywords": [
],
"acf": {
"blockVersion": 3,
"renderTemplate": "render.php"
},
"supports": {
"align": [
"wide"
],
"alignContent": false,
"alignText": false,
"anchor": true,
"color": {
"background": false,
"gradients": false,
"link": false,
"text": false
},
"fullHeight": false
}
}
<?php
/**
* Blocks setup
*
* @package DuckbillGroup
* @author Whiteley Designs
* @since 1.0.0
* @license GPL-2.0+
* @link https://www.advancedcustomfields.com/resources/options-page/
*/
namespace WhiteleyDesigns\Blocks;
/**
* Load blocks.
*/
function load_blocks() {
$blocks = scandir( get_template_directory() . '/blocks/' );
$blocks = array_values( array_diff( $blocks, array( '_base', '.DS_Store' ) ) );
if ( ! empty( $blocks ) ) {
foreach ( $blocks as $block ) {
// Empty scripts array.
$scripts = [];
// Regsiter block scripts if they exist (must register script before block).
if ( file_exists( get_template_directory() . '/blocks/' . $block . '/block.js' ) ) {
// Set proper dependencies.
$deps = [
'acf',
'jquery',
];
// Additional dependencies per block.
if ( $block === 'slideshow' ) {
$deps[] = 'wd-flickity';
}
// Register script.
wp_register_script(
'block-' . $block . '-js',
get_stylesheet_directory_uri() . '/blocks/' . $block . '/block.js',
$deps,
WD_THEME_VERSION,
false
);
// Populate scripts array.
$scripts = [
'script' => 'block-' . $block . '-js',
];
}
// Register the block.
register_block_type(
get_template_directory() . '/blocks/' . $block,
$scripts
);
}
}
}
add_action( 'init', __NAMESPACE__ . '\load_blocks', 5 );
/**
* Add custom block category for ACF blocks.
*
* @param array $categories Array of available block categories.
* @param int $post Post object.
*
* @link https://developer.wordpress.org/block-editor/developers/filters/block-filters/#managing-block-categories
*/
function block_category( $categories, $post ) {
$categories = array_merge(
$categories,
[
[
'slug' => 'wd-blocks',
'title' => __( 'Whiteley Designs Blocks', 'dbg-2026' ),
],
]
);
return $categories;
}
add_filter( 'block_categories_all', __NAMESPACE__ . '\block_category', 10, 2 );
<?php
/**
* FAQ Block
*
* @package DuckbillGroup
* @author Matt Whiteley
* @since 1.0.0
* @license GPL-2.0+
*/
// ACF meta.
$wd_block_faq_enable_schema = get_field( 'wd_block_faq_enable_schema' );
// Block ID.
$block_id = str_replace( '_', '-', $block['id'] );
// Add anchor if present.
if ( ! empty( $block['anchor'] ) ) {
$block_id = $block['anchor'];
}
// Block Classes.
$block_classes = 'acf-block block-faq';
// Get align class if present.
if ( ! empty( $block['align'] ) ) {
$block_classes .= ' align' . $block['align'];
}
// Custom class name.
if ( ! empty( $block['className'] ) ) {
$block_classes .= ' ' . $block['className'];
}
?>
<div id="<?php echo esc_attr( $block_id ); ?>" class="<?php echo esc_attr( $block_classes ); ?>">
<?php if ( have_rows( 'wd_block_faq' ) ) : ?>
<?php $faq_count = 0; ?>
<?php while ( have_rows( 'wd_block_faq' ) ) : ?>
<?php the_row(); ?>
<?php
$faq_count++;
$wd_faq_question = get_sub_field( 'wd_faq_question' );
$wd_faq_answer = get_sub_field( 'wd_faq_answer' );
?>
<div class="block-faq__toggle" id="block-faq-question-<?php echo esc_attr( $block['id'] ); ?>-<?php echo esc_attr( $faq_count ); ?>">
<button class="block-faq__toggle-question" aria-label="Toggle FAQ Item" aria-pressed="false" aria-controls="aria-<?php echo esc_attr( $block_id ); ?>-<?php echo esc_attr( $faq_count ); ?>">
<span>
<?php echo esc_attr( $wd_faq_question ); ?>
</span>
<span class="block-faq__toggle-question-icon"></span>
</button>
<div id="aria-<?php echo esc_attr( $block_id ); ?>-<?php echo esc_attr( $faq_count ); ?>" class="block-faq__toggle-answer" aria-expanded="false">
<?php echo wp_kses_post( $wd_faq_answer ); ?>
</div>
</div>
<?php endwhile; ?>
<?php endif; ?>
</div>
<?php if ( true === $wd_block_faq_enable_schema ) : ?>
<?php
// Set up global to store FAQ scheme. There is a function in /inc/theme-functionality.php that outputs this schema in the footer.
global $wd_global_faq_schema;
// Initialize global schema array if not already set.
if ( ! isset( $wd_global_faq_schema ) || ! is_array( $wd_global_faq_schema ) ) {
$wd_global_faq_schema = array();
}
$faq_schema_items = array();
// Initialize schema count based on global array length.
$schema_count = count( $wd_global_faq_schema );
if ( have_rows( 'wd_block_faq' ) ) :
while ( have_rows( 'wd_block_faq' ) ) :
the_row();
$question = get_sub_field( 'wd_faq_question' );
$answer = get_sub_field( 'wd_faq_answer' );
if ( ! empty( $question ) && ! empty( $answer ) ) :
$schema_count++;
$faq_schema_items[] = array(
'@type' => 'Question',
'@id' => esc_url( get_permalink() ) . '#block-faq-question-' . esc_attr( $block['id'] ) . '-' . $schema_count,
'position' => $schema_count,
'url' => esc_url( get_permalink() ) . '#block-faq-question-' . esc_attr( $block['id'] ) . '-' . $schema_count,
'name' => wp_strip_all_tags( $question ),
'answerCount' => 1,
'acceptedAnswer' => array(
'@type' => 'Answer',
'text' => wp_strip_all_tags( $answer ),
'inLanguage' => 'en-US',
),
'inLanguage' => 'en-US',
);
endif;
endwhile;
endif;
if ( ! empty( $faq_schema_items ) ) {
$wd_global_faq_schema = array_merge( $wd_global_faq_schema, $faq_schema_items );
}
?>
<?php endif; ?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment