29 October 2020

Reminder List for Building WordPress Themes

List of helpers, things I tend to reference during the build process.

My theme set up often consists of using ACF, Bootstrap and SASS so this post is aimed at templates, functions and examples using these technologies. Most pieces of code will include the Bootstrap grid system and jquery.

Resources for the build

Insert image

<img src="<?php echo get_stylesheet_directory_uri(); ?>/images/picture.png" alt="Picture of something"/>

Use the WordPress custom logo link

<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
    <?php if ( has_custom_logo() ) : ?>
        <div class="site-logo"><?php the_custom_logo(); ?></div>
    <?php endif; ?>      
</a>

WordPress nav menu parameters

<?php if ( has_nav_menu( 'primary-menu' ) ) : ?>
    <div id="site-navigation" class="main-navigation" aria-label="<?php esc_attr_e( 'Top Menu', 'websitename' ); ?>">
        <?php
   			wp_nav_menu(
              array(
                  'menu'                 => '',
                  'container'            => 'div',
                  'container_class'      => '',
                  'container_id'         => '',
                  'container_aria_label' => '',
                  'menu_class'           => 'menu',
                  'menu_id'              => '',
                  'echo'                 => true,
                  'fallback_cb'          => 'wp_page_menu',
                  'before'               => '',
                  'after'                => '',
                  'link_before'          => '',
                  'link_after'           => '',
                  'items_wrap'           => '<ul id="%1$s" class="%2$s">%3$s</ul>',
                  'item_spacing'         => 'preserve',
                  'depth'                => 0,
                  'walker'               => '',
                  'theme_location' => 'primary-menu',
                  )
             );
        ?>
    </div>
<?php endif; ?>

Bootstrap Nav Examples https://getbootstrap.com/docs/4.5/examples/

Bootstrap Fixed Top

<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
  <a class="navbar-brand" href="#">Fixed navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarCollapse">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
      </li>
    </ul>
    <form class="form-inline mt-2 mt-md-0">
      <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

Remove the navbar toggler default outline styling

.navbar-toggler {
    border: none;
    outline: none;
    &:focus, &:hover, &:active {
        background-color: transparent;
        border: none;
        outline: none;
    }
}

WordPress hierarchy

Enqueue Scripts and styles

Wow Animations -> Raw wow.min.js | Raw animate.css

<?php
function website_scripts() {
	wp_enqueue_style( 'animate', get_template_directory_uri() . '/css/animate.css', array() );
	wp_enqueue_script( 'wow', get_theme_file_uri( '/js/wow.min.js' ), array( 'jquery' ), '2.1.2', true );
}
add_action( 'wp_enqueue_scripts', 'website_scripts' );
jQuery(function($) {
// addBox function helps push new element wow boxes array
    WOW.prototype.addBox = function(element){
        this.boxes.push(element);
    };

    var wow = new WOW(
      {
        boxClass:     'wow',      // animated element css class (default is wow)
        animateClass: 'animated', // animation css class (default is animated)
        offset:       0,          // distance to the element when triggering the animation (default is 0)
        mobile:       true,       // trigger animations on mobile devices (default is true)
        live:         true,       // act on asynchronously loaded content (default is true)
        // callback:     function(box) {
        //   // the callback is fired every time an animation is started
        //   // the argument that is passed in is the DOM node being animated
        // },
        scrollContainer: null,    // optional scroll container selector, otherwise use window,
        resetAnimation: true,     // reset animation on end (default is true)
      }
    );
    wow.init();
});

Ekko Lightbox -> Raw ekko-lightbox.min.js | Raw ekko-lightbox.css

<?php
function website_scripts() {
	wp_enqueue_style( 'animate', get_template_directory_uri() . '/css/ekko-lightbox.css', array() );
	wp_enqueue_script( 'bs-lightbox', get_theme_file_uri( '/js/ekko-lightbox.min.js' ), array('jquery'), '5.2', true );
}
add_action( 'wp_enqueue_scripts', 'website_scripts' );
jQuery(function($){ 
    $(document).on('click', '[data-toggle="lightbox"]', function(event) {
        event.preventDefault();
        $(this).ekkoLightbox({
            alwaysShowClose: true,
            wrapping: true,
            showArrows: true,
            maxWidth: 1200,
        });
    });
});

Isotope/Packery -> Download isotope.pkgd.min.js

<?php
function website_scripts() {
	wp_enqueue_script( 'isotope', get_theme_file_uri( '/core/js/isotope.pkgd.min.js' ), array('jquery'), '3.0.6', false );
}
add_action( 'wp_enqueue_scripts', 'website_scripts' );
jQuery(function($){
    var $grid = $('.grid-isotope').isotope({
        itemSelector: '.grid-item-isotope',
        layoutMode: 'fitRows',
        resizeContainer: true
    });
    // filter items on button click
    $(document).on( 'click', '.filter-button', function() {
        var filterTitle = $(this).text();
        $('.filter-button').removeClass('active');
        $(this).addClass('active');

        $('#currently-showing').text(filterTitle);
        
        if ($(this).attr('data-filter-by')) {
            var filterValue = $(this).attr('data-filter-by');
            $grid.isotope({ filter: filterValue });
        };
    });
});

jQuery check width function and add class to nav elements on scroll

Add to theme.js. This function runs if the screen width is uner 768px and adds the ‘scrolled’ class to the relevant html elements so they can be animated on load, ready, resize and scroll.

jQuery(function($) {
  var checkWidth = function(){

    if ($(window).width() < 768) {
      $('#page').addClass('scrolled');
      $('.navbar').addClass('scrolled');
      $('.custom-logo').addClass('scrolled');
      $('.primary-menu').addClass('scrolled');
    } else {
      $('#page').removeClass('scrolled');
      $('.navbar').removeClass('scrolled');
      $('.custom-logo').removeClass('scrolled');
      $('.primary-menu').removeClass('scrolled');
    }
  }

  $(window).on('load ready resize scroll', checkWidth);
});

Add the class to make the animation happen in style.css

/* Add class on scroll down to shrink nav*/
.scrolled {
    transition: all 0.3s ease-in-out;
}
#page.scrolled {
    margin-top: 60px;
}

ACF file download

Nice little number to grab the required data for the file and display it on the frontend using the ACF file attribute set to ID.

<?php
  $attachment_id = get_field('pdf_download');
  $url = wp_get_attachment_url( $attachment_id );
  $title = get_the_title( $attachment_id );
  $filesize = filesize( get_attached_file( $attachment_id ) );
  $filesize = size_format($filesize, 2);  
  $path_info = pathinfo( get_attached_file( $attachment_id ) );
 ?>

    <section class="theme-button">
        <div class="container">
            <div class="row">
                <div class="col text-center">
                    <a target="_blank" rel="noopener" type="<?php echo $path_info['extension']; ?>" data-size="<?php echo $filesize; ?>" href="<?php echo $url; ?>">DOWNLOAD PDF</a>
                </div>
            </div>
        </div>
    </section>

Classic WordPress post query

This one using the taxonomy category of ‘member-type’ with the term ‘team’ of a custom post type called ‘members’. Remove the ‘tax_query for a simple loop of posts.

<?php
    if ( have_posts() ) :
        // Start the Loop.
        while ( have_posts() ) : the_post();

        $args = array(
            'posts_per_page'   => -1,
            'order'            => 'menu_order',
            'post_type'        => 'members',
            'tax_query'        => array(
                                        array(
                                            'taxonomy' => 'member-type',
                                            'terms' => 'team',
                                            'field' => 'slug',
                                            'include_children' => true,
                                            'operator' => 'IN'
                    ),
                ),
            'post_status'      => 'publish'
        ); ?>

        <?php $posts = get_posts( $args ); ?>
        <?php foreach ( $posts as $post ) : setup_postdata( $post ); 

            $role = get_field('role');
            $profile = get_field('profile');
            $image = get_field('image');

        ?>   
            <article class="content-with-sidebar" id="<?php echo $post->post_name; ?>">
                <div class="row mb-3">
                    <div class="col-12">
                        <h1><?php the_title();?>&nbsp;&nbsp;<span><?php echo $role; ?></span></h1>
                    </div>
                </div>
                <div class="row pb-5">
                    <div class="col-12 col-lg-6">
                        <?php echo $profile; ?>
                    </div>
                    <div class="col-12 col-lg-5 offset-lg-1">
                        <?php if (get_field('image')): ?>
                            <div class="profile-image aspect ratio1-1" style="background-image: url(<?php echo $image; ?>);">
                            </div>
                        <?php endif; ?>
                    </div>
                </div>
            </article>
        <?php endforeach; ?>
    <?php endwhile; ?>
<?php endif; ?>

Aspect ratio styles

/* Apect ratio ===============================================*/
.aspect {
    background-position: center center;
    background-repeat: no-repeat;
    background-size: cover;
    width: 100%;
    position: relative;
    margin: 0;
    display: inline-block;
    vertical-align: top;
}
.aspect:before {
    content: '';
    display: block;
}
.ratio1-1:before {
    padding-top: 100%;
}
.ratio2-1:before {
    padding-top: 50%;
}
.ratio1-2:before {
    padding-top: 200%;
}
.ratio4-3:before {
    padding-top: 75%
}
.ratio16-9:before {
    padding-top: 56.25%;
}
.ratioThinBanner:before {
    padding-top: 5.5%;
}
.aspect-content {    
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
}

Use aspect ratio to insert a simple banner

<section id="banner" class="aspect ratioThinBanner" style="background-image: url(<?php the_field('banner'); ?>);"></section>

Simple banner with nice detect page id

<?php
    $pageId = get_the_ID();
    $banner = get_field('banner', $pageId);
    $posts_page = get_page( $pageId);
    $blogTitle = $posts_page->post_title;
?>

<section id="banner" class="aspect ratioThinBanner" style="background-image: url(<?php echo $banner; ?>);">
    <h1 class="text-center"><?php echo $blogTitle; ?></h1>
</section>

Simple banner styles.css

#banner {
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
    min-height: 200px;
    h1 {
        color: #ffffff;
        font-weight: 400;
        text-shadow: rgba(0, 0, 0, 0.8) 2px 0 13px;
    }
}

Basic footer elements

<footer class="site-footer">
    <div class="container-fluid">
        <div class="row align-items-center">
            <div class="col-12 col-md-6 text-left">
                <p>&copy;<?php echo date('Y'); ?> <a href="https://example.com/" target="_blank"> Wesitename</a> All rights reserved.</p>
            </div>
            <div class="col-12 col-md-6">
                <div class="site-logo-footer ml-auto"><a href="<?php echo home_url(); ?>"><img alt="logo" class="img-fluid" src="<?php echo get_template_directory_uri(); ?>/images/logo.png"/></a>
                </div>
            </div>
        </div>
    </div>
</footer>

Simple FOUC (Flash of unstyled content) fix

body {
	animation-name: fadeInOpacity;
    animation-iteration-count: 1;
    animation-timing-function: ease-in;
    animation-duration: 2s;
}
@keyframes fadeInOpacity {
     0% {
         opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

utopianfool

Creative Web Developer

View all posts by utopianfool →