Created
April 22, 2022 15:31
-
-
Save kingkool68/e45491dbbfd6075ffc16ecdee07a1b58 to your computer and use it in GitHub Desktop.
How I use Advanced Custom Fields' Blocks to make custom components for WordPress sites. Logic is all in PHP, HTML templating is done in Twig via https://github.com/kingkool68/sprig
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* A block with an image and text on the side | |
*/ | |
class CoderPad_Text_Image_Block { | |
/** | |
* Get an instance of this class | |
*/ | |
public static function get_instance() { | |
static $instance = null; | |
if ( null === $instance ) { | |
$instance = new static(); | |
$instance->setup_actions(); | |
} | |
return $instance; | |
} | |
/** | |
* Hook into WordPress via actions | |
*/ | |
public function setup_actions() { | |
add_action( 'acf/init', array( $this, 'action_acf_init' ) ); | |
} | |
/** | |
* Register Advanced Custom Fields | |
*/ | |
public function action_acf_init() { | |
// Custom fields for the block | |
$args = array( | |
'name' => 'coderpad-text-image', | |
'title' => 'CoderPad Text/Image', | |
'description' => 'A custom Text/Image block.', | |
'render_callback' => array( $this, 'render_from_block' ), | |
'category' => 'coderpad', | |
'icon' => 'align-left', | |
'keywords' => array( 'text/image', 'text image' ), | |
); | |
acf_register_block_type( $args ); | |
$args = array( | |
'key' => 'text_image_block_fields', | |
'title' => 'Call to Action Block Fields', | |
'fields' => array( | |
array( | |
'key' => 'field_text_image_block_image_id', | |
'name' => 'text_image_block_image_id', | |
'label' => 'Image', | |
'type' => 'image', | |
'return_format' => 'id', | |
), | |
array( | |
'key' => 'field_text_image_block_image_size', | |
'name' => 'text_image_block_image_size', | |
'label' => 'Image Size', | |
'type' => 'select', | |
'choices' => CoderPad_Media::get_image_size_names(), | |
'allow_null' => true, | |
), | |
array( | |
'key' => 'field_text_image_block_image_alignment', | |
'name' => 'text_image_block_image_alignment', | |
'label' => 'Image Alignment', | |
'type' => 'select', | |
'choices' => array( | |
'left' => 'Left', | |
'right' => 'Right', | |
), | |
), | |
array( | |
'key' => 'field_text_image_block_image_proportion', | |
'name' => 'text_image_block_image_proportion', | |
'label' => 'Image Proportion', | |
'type' => 'select', | |
'choices' => array( | |
'one-third' => '1/3', | |
'half' => '1/2', | |
'two-thirds' => '2/3', | |
), | |
'allow_null' => true, | |
), | |
array( | |
'key' => 'field_text_image_block_headline', | |
'name' => 'text_image_block_headline', | |
'label' => 'Headline', | |
'type' => 'text', | |
), | |
array( | |
'key' => 'field_text_image_block_headline_url', | |
'name' => 'text_image_block_headline_url', | |
'label' => 'Headline URL', | |
'instructions' => 'Link the headline and image to a URL', | |
'type' => 'text', | |
), | |
array( | |
'key' => 'field_text_image_block_description', | |
'name' => 'text_image_block_description', | |
'label' => 'Description', | |
'type' => 'wysiwyg', | |
'toolbar' => 'basic', | |
'media_upload' => false, | |
), | |
array( | |
'key' => 'field_text_image_block_cta_label', | |
'name' => 'text_image_block_cta_label', | |
'label' => 'Call to Action Label', | |
'type' => 'text', | |
), | |
array( | |
'key' => 'field_text_image_block_cta_url', | |
'name' => 'text_image_block_cta_url', | |
'label' => 'Call to Action URL', | |
'type' => 'url', | |
), | |
array( | |
'key' => 'field_text_image_block_cta_style', | |
'name' => 'text_image_block_cta_style', | |
'label' => 'Call to Action Style', | |
'type' => 'select', | |
'choices' => array( | |
'primary' => 'Primary', | |
'outline' => 'Outline', | |
), | |
), | |
), | |
'location' => array( | |
array( | |
array( | |
'param' => 'block', | |
'operator' => '==', | |
'value' => 'acf/coderpad-text-image', | |
), | |
), | |
), | |
'description' => 'Text/Image fields', | |
); | |
acf_add_local_field_group( $args ); | |
} | |
/** | |
* Render a Text Image component | |
* | |
* @param array $args Arguments to modify what is rendered | |
*/ | |
public static function render( $args = array() ) { | |
$defaults = array( | |
'image' => '', | |
'image_alignment' => 'left', | |
'image_proportion' => '', | |
'headline' => '', | |
'headline_url' => '', | |
'cta_label' => '', | |
'cta_url' => '', | |
'cta_style' => 'primary', | |
); | |
$context = wp_parse_args( $args, $defaults ); | |
if ( $context['image_alignment'] !== 'right' ) { | |
$context['image_alignment'] = $defaults['image_alignment']; | |
} | |
if ( ! empty( $context['headline'] ) ) { | |
$context['headline'] = apply_filters( 'the_title', $context['headline'] ); | |
} | |
if ( ! empty( $context['description'] ) ) { | |
$context['description'] = apply_filters( 'the_content', $context['description'] ); | |
} | |
return Sprig::render( 'text-image-block.twig', $context ); | |
} | |
/** | |
* Call to Action block callback function | |
* | |
* @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. | |
*/ | |
public function render_from_block( $block = array(), $content = '', $is_preview = false, $post_id = 0 ) { | |
$image_id = get_field( 'text_image_block_image_id' ); | |
$image_args = array(); | |
$image_size = get_field( 'text_image_block_image_size' ); | |
if ( ! empty( $image_size ) ) { | |
$image_args['size'] = $image_size; | |
} | |
$headline_url = get_field( 'text_image_block_headline_url' ); | |
if ( $is_preview ) { | |
$headline_url = ''; | |
} | |
if ( ! empty( $headline_url ) ) { | |
$image_args['link_url'] = $headline_url; | |
} | |
$args = array( | |
'image' => CoderPad_Media::render_image_from_post( $image_id, $image_args ), | |
'image_alignment' => get_field( 'text_image_block_image_alignment' ), | |
'image_proportion' => get_field( 'text_image_block_image_proportion' ), | |
'image_size' => get_field( 'text_image_block_image_size' ), | |
'headline' => get_field( 'text_image_block_headline' ), | |
'headline_url' => $headline_url, | |
'description' => get_field( 'text_image_block_description' ), | |
'cta_label' => get_field( 'text_image_block_cta_label' ), | |
'cta_url' => get_field( 'text_image_block_cta_url' ), | |
'cta_style' => get_field( 'text_image_block_cta_style' ), | |
); | |
if ( empty( $args['headline'] ) && $is_preview ) { | |
echo '(Fill in Text/Image Block Details)'; | |
return; | |
} | |
echo static::render( $args ); | |
} | |
} | |
CoderPad_Text_Image_Block::get_instance(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment