Portfolio
Client builds and code samples. Filter by type, or open a project.
Past projects
-
X Games wordpress theme development front-end development -
Sparkling Ice wordpress theme development front-end development -
Quill & Quest Bookstore wordpress theme development front-end development -
AED Authority wordpress theme development new site build -
Smart Health Cards front-end development new site build -
Fathercraft wordpress theme development new site build
Code samples
Vue.js Employee Database
ACF Flexible Content Template
| <?php | |
| /** | |
| * Partial template for ACF flexible content | |
| * | |
| * @package Understrap | |
| */ | |
| // Exit if accessed directly. | |
| defined( 'ABSPATH' ) || exit; | |
| the_title( '<h1 class="entry-title d-none">', '</h1>' ); | |
| // check for ACF flexible content data | |
| if ( have_rows( 'modules' ) ) { | |
| // loop through the select ACF flexible content layouts | |
| while( have_rows( 'modules' ) ) { | |
| the_row(); | |
| // dispaly the matching flexible content partial | |
| get_template_part( 'modules/' . get_row_layout() ); | |
| // Just add your row templates into a directory named `modules` in the root of your theme | |
| // Each row template shoud have a filename matching the ACF slug | |
| // (ex: three-columns.php for a field with slug `three-columns`) | |
| } | |
| } |
| <?php | |
| /** | |
| * Template Name: Flexible Content | |
| * | |
| * Template for displaying ACF Flexible Content Modules | |
| * | |
| * @package Understrap | |
| */ | |
| // Exit if accessed directly. | |
| defined( 'ABSPATH' ) || exit; | |
| get_header(); | |
| ?> | |
| <div class="wrapper" id="page-wrapper"> | |
| <div class="container-fluid" id="content" tabindex="-1"> | |
| <div class="row"> | |
| <main class="site-main" id="main"> | |
| <?php | |
| while ( have_posts() ) { | |
| the_post(); | |
| // Get the template part for looping through our flexible content fields | |
| get_template_part( 'loop-templates/content', 'flexible' ); | |
| // If comments are open or we have at least one comment, load up the comment template. | |
| if ( comments_open() || get_comments_number() ) { | |
| comments_template(); | |
| } | |
| } | |
| ?> | |
| </main><!-- #main --> | |
| </div><!-- .row --> | |
| </div><!-- #content --> | |
| </div><!-- #page-wrapper --> | |
| <?php | |
| get_footer(); |
Portfolio Gallery CSS Grid
CSS Only Masonry Layout (No CSS Grid)
Scrolling Bootstrap Card Carousel
Scrolling Bootstrap Card Carousel - 4 Cards per Slide
Flickity WordPress Carousel
| <?php | |
| /** | |
| * Flickity-based carousel for returning posts from the loop. I find it far more versatile and simple than a Bootstrap | |
| * carousel. Get the required scripts and styles from here: https://flickity.metafizzy.co/ | |
| */ | |
| <div class="blog-carousel"> | |
| <?php | |
| if ( have_posts() ) : while ( have_posts() ) : the_post(); | |
| $thumbnail_id = get_post_thumbnail_id(); | |
| $thumbnail_url = wp_get_attachment_image_src( $thumbnail_id, 'large', true ); | |
| ?> | |
| <div class="carousel-cell"> | |
| <!-- I chose to display my posts in a custom card style. --> | |
| <article class="article-card"> | |
| <a href="<?php the_permalink(); ?>"><img src="<?php echo $thumbnail_url[0]; ?>" alt="<?php the_title(); ?>" class="card-img"></a> | |
| <div class="card-content"> | |
| <a href="<?php the_permalink(); ?>" class="article-title"><?php the_title( "<h4>", "</h4>" ) ?></a> | |
| </div> | |
| <footer class="card-footer"> | |
| <a href="<?php the_permalink(); ?>" class="button purple-outline" role="button">Learn More</a> | |
| </footer> | |
| </article> | |
| </div> | |
| <?php | |
| endwhile; | |
| endif; | |
| wp_reset_query(); | |
| ?> | |
| </div> | |
| ?> |
Material Design Bootstrap WordPress Carousel
| <?php | |
| // I'm using both Bootstrap 4.0 and MD Bootstrap, so you may want to tweak some of this yourself | |
| // Also remmeber to link up some styles, or the div with your background image won't display | |
| $args = array( | |
| 'post_type' => 'portfolio', // my own custom post type | |
| 'meta_query' => array( // pull in featured posts from metadata connected to a custom featured post plugin | |
| array( | |
| 'key' => 'featured-checkbox', | |
| 'value' => 'yes' | |
| ) | |
| ) | |
| ); | |
| $the_query = new WP_Query($args); | |
| ?> | |
| <!--Carousel Wrapper--> | |
| <div id="carousel-portfolio" class="carousel slide carousel-fade" data-ride="carousel" data-interval="false"> | |
| <!--Indicators--> | |
| <ol class="carousel-indicators"> | |
| <?php if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); ?> | |
| <li data-target="#carousel-portfolio" data-slide-to="<?php echo $the_query->current_post; ?>" class="<?php if ( $the_query->current_post == 0 ) : ?>active<?php endif; ?>"></li> | |
| <?php endwhile; endif; ?> | |
| </ol> | |
| <!--/Indicators--> | |
| <?php rewind_posts(); ?> | |
| <!--Slides--> | |
| <div class="carousel-inner" role="listbox"> | |
| <?php | |
| if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post(); | |
| $thumbnail_id = get_post_thumbnail_id(); | |
| $thumbnail_url = wp_get_attachment_image_src( $thumbnail_id, 'full-size', true ); | |
| $thumbnail_meta = get_post_meta( $thumbnail_id, '_wp_attatchment_image_alt', true ); | |
| ?> | |
| <!--Slide--> | |
| <!-- Set the featured image as the background image of the div --> | |
| <div class="carousel-item <?php if ( $the_query->current_post == 0 ) : ?>active<?php endif; ?> view hm-white-strong" style="background: url('<?php echo $thumbnail_url[0]; ?>') no-repeat center center; background-size: cover;"> | |
| <!-- Caption --> | |
| <div class="full-bg-img flex-center"> | |
| <ul class="animated fadeInUp col-md-12"> | |
| <li> | |
| <a href="<?php echo esc_url( home_url( '/' ) ); ?>"> | |
| <img src="<?php site_icon_url( 'thumbnail' ); ?>" class="img-fluid mx-auto" alt="<?php get_bloginfo( array('name', 'description') ); ?>"> | |
| </a> | |
| </li> | |
| <li style="color:black;"> | |
| <p class="flex-item lead"> | |
| <?php the_excerpt(); ?> | |
| </p> | |
| </li> | |
| <li> | |
| <!-- I have this pointing to a portfolio archive, but you can point it anywhere --> | |
| <a target="_blank" href="<?php echo esc_url( home_url( '/portfolio/' ) ); ?>" class="btn btn-primary btn-lg flex-item" rel="nofollow">See my work</a> | |
| </li> | |
| <li> | |
| <a target="_blank" href="mailto:<?php get_bloginfo('admin_email'); ?>" class="btn btn-default btn-lg flex-item" rel="nofollow">Hire Me</a> | |
| </li> | |
| <li> | |
| <a href="<?php the_permalink(); ?>" class="text-muted"> | |
| <!-- A caption showing which portoflio piece is in the background --> | |
| <p class="flex-item font-italic">Pictured: | |
| <?php the_title(); ?> | |
| </p> | |
| </a> | |
| </li> | |
| </ul> | |
| </div> | |
| <!-- /.Caption --> | |
| </div> | |
| <!--/.Slide--> | |
| <?php endwhile; endif; ?> | |
| </div> | |
| <!--/Slides--> | |
| <!--Controls--> | |
| <a class="carousel-control-prev" href="#carousel-portfolio" role="button" data-slide="prev"> | |
| <span class="carousel-control-prev-icon" aria-hidden="true"></span> | |
| <span class="sr-only">Previous</span> | |
| </a> | |
| <a class="carousel-control-next" href="#carousel-portfolio" role="button" data-slide="next"> | |
| <span class="carousel-control-next-icon" aria-hidden="true"></span> | |
| <span class="sr-only">Next</span> | |
| </a> | |
| <!--/.Controls--> | |
| </div> | |
| <!--/Carousel Wrapper--> | |
| <?php wp_reset_postdata(); ?> |
Production Image Redirector
WordPress plugin that points local and staging uploads image URLs at a production host: attachments, srcset, and images inside post content.
Full repository on GitHub · excerpt: includes/class-url-redirector.php
Bookshop Inventory — data provider
Custom WordPress plugin for bookstore inventory (Ingram Data Services). A provider contract and filter hook so you can swap the Ingram integration without rewriting the display layer.
AJAX archive filter
Filter a post archive without a full page reload: PHP handles the AJAX request and markup; JavaScript drives the UI and fetch calls.
Get in touch
Got a project or a role you think might be a good fit? I'd love to hear about it. Reach me at [email protected] or connect via the links below.
Open to remote contract and full-time roles.