The Wordpress Gutenberg editor makes it much easier now to allow flexible layout editing. It also allows us to generate custom blocks with stylised content that can be re-used as often as required. The following details instructions to create a jquery accordion block that can be dropped ito place on any page, as many times as you like.
Just a few requirements before we dive in. This project requires a fairly good understanding of editing Wordpress templates. You will also need to have a copy of the Advanced Custom Fields (ACF) plugin installed. I've also have a licence to use the Pro version of Font Awesome Pro, but this is not 100% necessary.
First we need to make sure that the jQuery UI library is included in the template. Add the following to your template (or child theme):
//Add jquery UI to theme functions.php file
function load_my_scripts() {
if (!is_admin()) {
wp_register_script('jqueryui', '//code.jquery.com/ui/1.12.1/jquery-ui.js', array('jquery'), '1.12.1', true);
wp_enqueue_script('jqueryui');
}
}
add_action('init', 'load_my_scripts');
Add a folder called 'blocks' in your theme directory, and create a new file called content-accordion.php. In this file add the following. Note that there are various lines in this file that refer to custom fields that we'll generate in the Advanced Custom Fields plugin.
<?php
/**
* Accordion Block Template.
*
* @param array $block The block settings and attributes.
* @param string $content The block inner HTML (empty).
* @param bool $is_preview True during AJAX preview.
* @param (int|string) $post_id The post ID this block is saved to.
*/
// create id attribute for specific styling
$id = 'accordion-' . $block['id'];
if( !empty($block['anchor']) ) {
$id = $block['anchor'];
}
// Create class attribute allowing for custom "className" and "align" values.
$className = 'accordion';
if( !empty($block['className']) ) {
$className .= ' ' . $block['className'];
}
if( !empty($block['align']) ) {
$className .= ' align' . $block['align'];
}
//get repeater field name
if( have_rows('accordion') ): ?>
<div class="<?php echo esc_attr($className); ?> <?php echo $align_class; ?>" id="<?php echo $id; ?>">
<?php
//whilst we have repeating fields
while ( have_rows('accordion') ) : the_row();
//vars
$acc_title = get_sub_field('accordion_title');
$acc_content = get_sub_field('accordion_content');
?>
<h3 class="acc_title">
<?php echo $acc_title; ?>
</h3>
<div class="panel" style="display: none;">
<?php echo $acc_content; ?>
</div>
<?php endwhile; ?>
</div>
<?php endif; // end accordion ?>
Next, add a function in the theme functions.php file as below. This registers a new block type, and links to our content-accordion.php file. You can actually register multiple blocks if you wish to.
////////////////////////////////////////////////////////////////////
// ACF Gutenberg blocks
// https://www.advancedcustomfields.com/resources/blocks/
// icons: https://developer.wordpress.org/resource/dashicons/#editor-alignleft
////////////////////////////////////////////////////////////////////
function register_acf_block_types() {
// register a testimonial block
acf_register_block(array(
'name' => 'tms-accordion',
'title' => __('Accordion'),
'description' => __('A custom accordion block.'),
'category' => 'formatting',
'icon' => 'arrow-down-alt2',
'keywords' => array( 'accordion', 'read more' ),
'render_template' => '/blocks/content-accordion.php',
// if using in a plugin ues this line instead
//'render_template' => plugin_dir_path( __FILE__ ) . 'blocks/content-accordion.php',
));
}
// Check if function exists and hook into setup.
if( function_exists('acf_register_block_type') ) {
add_action('acf/init', 'register_acf_block_types');
}
Once the above files are in place, it should be possible to add some custom fields in ACF. You will need to generate a new Field Group, with the following fields:
In the Location panel (a bit lower down the page), set the 'Show this field group if' field to 'Block' > 'is equal to' > Accordion (If Accordion appears in the third drop-down, then youve done the first two bits correctly!).
Alternatively, copy the text below into a new file, saved with a .json siffix, and imprt it into ACF.
[
{
"key": "group_5ce8018486f73",
"title": "Accordion Block",
"fields": [
{
"key": "field_5ce801946ee6c",
"label": "Accordion",
"name": "accordion",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"collapsed": "field_5ce801c96ee6d",
"min": 0,
"max": 0,
"layout": "block",
"button_label": "",
"sub_fields": [
{
"key": "field_5ce801c96ee6d",
"label": "Accordion Title",
"name": "accordion_title",
"type": "text",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": ""
},
{
"key": "field_5ce801ed6ee6e",
"label": "Accordion Content",
"name": "accordion_content",
"type": "wysiwyg",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"tabs": "all",
"toolbar": "very_simple",
"media_upload": 1,
"delay": 0
}
]
}
],
"location": [
[
{
"param": "block",
"operator": "==",
"value": "acf\/tms-accordion"
}
]
],
"menu_order": 0,
"position": "normal",
"style": "default",
"label_placement": "top",
"instruction_placement": "label",
"hide_on_screen": "",
"active": true,
"description": ""
}
]
Publish the ACF fields. You will now find that there is a new Accordion Block available in the Gutenberg editor.
We'll need a bit of jquery to make the accordion work. Add this as a script in your theme. This also includes a function to scroll the title of the accordion to the top of the browser window - you can adjust the top offset to make sure that the accordion doesn't become hidden behind the masthead (if you have a fixed header).
// jQuery accordion
;(function($){
$( ".accordion" ).accordion({
collapsible: true,
active : 'none',
header: ".acc_title",
heightStyle: "content",
activate: function( event, ui ) {
if(!$.isEmptyObject(ui.newHeader.offset())) {
if ($(window).width() > 767) {
$('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top -180 }, 'slow');
}
else {
$('html:not(:animated), body:not(:animated)').animate({ scrollTop: ui.newHeader.offset().top -50 }, 'slow');
}
}
}
});
})(jQuery);
To make this all look pretty on the front of the site, we also need some CSS. Add the following to your theme CSS file.
/***********************************************
ACF FAQ Accordion
***********************************************/
.accordion {
display: block;
width: 100%;
clear:both;
}
.accordion .acc_title {
border: 1px solid #E6E7E8;
padding: 20px 50px 20px 20px;
cursor: pointer;
margin-bottom: 0;
margin-top: 3px;
position: relative;
font-size: 20px;
display: block;
width: 100%;
margin-bottom: 0px !important;
}
.accordion .acc_title:before {
content:'\f078';
font-family: 'Font Awesome 5 Pro';
position: absolute;
right: 20px;
top: 19px;
}
.accordion .acc_title.ui-state-active {
border-bottom: 0;
//color: $blue;
}
.accordion .acc_title.ui-state-active:before {
content:'\f077';
font-family: 'Font Awesome 5 Pro';
position: absolute;
right: 20px;
top: 19px;
}
.accordion .acc_title:focus {outline:none;}
.accordion .ui-accordion-content {
border-left: 1px solid #E6E7E8;
border-right: 1px solid #E6E7E8;
border-bottom: 1px solid #E6E7E8;
padding: 1px 20px 20px 20px;
margin-top: 0;
width: 100%;
}
Specialising in responsive Wordpress website design, development, hosting, site optimisation, digital marketing, as well as graphic design for print.