Work Samples

Select samples from recent years.

GA4 / WordPress Integration

I contracted with BiggerPockets (a content/media company in the real estate investment niche) for a couple years. During my time their I built some GA4 integrations in WordPress that pulled blog post page view data and matched it with the post's author.

We did a number of things with that data. One of the blocks I built with it displayed 'Trending Authors' based on a timeframe selected by the WP Admin.

Authors

MHB – Personal Brand

Matthew Howells-Barbey is a former HubSpot VP and co-founder of Traffic Think Tank (a $1M+ ARR Slack community).

Matthew asked me to help with building his personal brand website. Deisgn by Shane Austin and web development by me.

Matthew Howells-Barby

ACF Block CLI

Most modern web frameworks, like Laravel or React, have CLIs to help developers scaffold bits of their project's codebase. While it's not a framework, I was always bummed that Advanced Custom Fields didn't have one. So I built one myself – modernwpdev.co/acf-block-cli/

Below is an animation demonstrating the CLI. The animation is built with Tailwind and Alpine.js. It's an interesting example of my work in addition to the CLI itself.


<?php
/**
 * Block Name: Hero
 * Description: Displays a full width hero image with text overlay
 */

// $data is what we're going to expose to our render template
$data = array(
    'example_field' => get_field( 'example_field' ),
    'another_field' => get_field( 'another_field' )
);

// Dynamic block ID
$block_id = 'hero-' . $block['id'];

// Check if a custom ID is set in the block editor
if( !empty($block['anchor']) ) {
    $block_id = $block['anchor'];
}

// Block classes
$class_name = 'hero-block';
if( !empty($block['class_name']) ) {
    $class_name .= ' ' . $block['className'];
}

/** 
 * Pass the block data into the template part
 */ 
get_template_part(
    'theme/blocks/hero/render',
    null,
    array(
        'block'      => $block,
        'is_preview' => $is_preview,
        'post_id'    => $post_id,

        'data'       => $data,
        'class_name' => $class_name,
        'block_id'   => $block_id,
    )
);

{
    "name": "hero",
    "title": "Hero",
    "description": "Displays a full width hero image with text overlay",
    "category": "theme",
    "apiVersion": 2,
    "acf": {
        "mode": "preview",
        "renderTemplate": "theme/blocks/hero/block.php"
    },
    "supports": {
        "anchor": true,
        "jsx": true
    }
}

<?php
/**
 * Block Name: Hero
 * Description: Displays a full width hero image with text overlay
 */

// The block attributes
$block = $args['block'];

// The block data
$data = $args['data'];

// The block ID
$block_id = $args['block_id'];

// The block class names
$class_name = $args['class_name'];

$template = array(
    array('core/heading', array(
        'level' => 2,
        'content' => 'This is a default heading',
    )),
    array( 'core/paragraph', array(
        'content' => 'This is placeholder paragraph text.',
    ) )
);

$allowed_blocks = array( 'core/heading', 'core/paragraph', 'core/image' );
?>

<div id="<?php echo $block_id; ?>" class="<?php echo $className; ?>">
    <InnerBlocks 
        template="<?php echo esc_attr( wp_json_encode( $template ) ); ?>"
        allowedBlocks="<?php echo esc_attr( wp_json_encode( $allowed_blocks ) ); ?>"/>
</div>

<?php
function create_acf_block_cli_register_blocks() {
    // ACF Block Registration
    $blocks=array();
    foreach ($blocks as $block) {
        register_block_type( get_template_directory() . '/blocks/' . $block );
    }
}
add_action( 'init', 'create_acf_block_cli_register_blocks' );

Hire an expert web developer for less

The average salary for a junior dev in the US is $70,000. Hiring me costs about 25% less.

Piccolo

$4,500/mo

  • One concurrent request

  • Turnaround time in days, not weeks
  • Pause or cancel anytime
Get started

Grande

$7,500/mo

  • Two concurrent requests

  • Turnaround time in days, not weeks
  • Pause or cancel anytime
Get started

Want to talk with me first?

Learn more about how I work and discuss your project on a free call.

Schedule a call

Unsure? Let's make this really easy for you.

Within the first 3 weeks of your initial month, if you're not completely satisfied for any reason, just let me know, and I'll will refund your fee and cancel your subscription. That's something you wouldn't get from a full-time employee or some random freelancer.