Skip to content

Instantly share code, notes, and snippets.

@kingkool68
Created April 22, 2022 15:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kingkool68/e45491dbbfd6075ffc16ecdee07a1b58 to your computer and use it in GitHub Desktop.
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
<?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