Why Flexsider’s Carousel Demo with Dynamic Sizing Doesn’t Work

I’ve scratched my head a few too many times to not post this (if only for my own reference). The ever amazing and rarely updated Flexslider from the folks at Woocommerce has a bug in one of the demos that doesn’t make it operate as intended. It’s the carousel with a dynamic number of elements that changes with the width of the site. You can find it here.

There are two problems with their source code.

Firstly despite declaring a ‘flexslider’ variable at the top of the page they don’t initialize the slider into this. You need to do this to update the sliders min and max values.

Secondly it seems they’re incorrectly updating the min and max sizes on the event of the window resizing. They’re using the property below which doesn’t  work (especially because they’ve not associated their ‘flexslider’ variable with the slider itself).

flexslider.vars.minItems = gridSize;
flexslider.vars.maxItems = gridSize;

However to correctly update this value in Flexslider you need to do the folllowing. Please note the different with $flexslider and flexslider is just my naming convention.

$flexslider.data('flexslider').vars.minItems = gridSize;
$flexslider.data('flexslider').vars.maxItems = gridSize;

Heres the fully working code.

var $window = $(window),
    $flexslider;
 
// tiny helper function to add breakpoints
function getGridSize() {
  return (window.innerWidth < 768) ? 1 : 3;
}
 
$window.load(function() {
  // Carousel Homepage
  $flexslider = $('.flexslider').flexslider({
    animation: "slide",
    itemWidth: 360,
    itemMargin: 25,
    minItems: getGridSize(),
    maxItems: getGridSize(),
    slideshow: false,
    prevText: "Prev"
  });  
});
 
if(!!$('.flexslider').length) {
  // check grid size on resize event
  $window.resize(function() {
    var gridSize = getGridSize();
    $flexslider.data('flexslider').vars.minItems = gridSize;
    $flexslider.data('flexslider').vars.maxItems = gridSize;
  });
}

Should you need to add additional break points or different breakpoints just update the getGridSize function.

Quickly replace WP Contact Form 7 Loading Gif (Updated)

WPCF7 is an amazing contact form plugin. Its simplicity makes it great if you prefer to control all the elements of a sites design yourself. One annoying thing about it is that the loading gif is extremely old and only plays well on white backgrounds. Here’s a single line of CSS to replace its outdated AJAX spinner with an SVG inline one.

.wpcf7 form .ajax-loader {
  background: url('data:image/svg+xml;utf8,<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0" width="16px" height="16px" viewBox="0 0 128 128" xml:space="preserve"><rect x="0" y="0" width="100%" height="100%" fill="%23FFFFFF" fill-opacity="0" /><g><circle cx="16" cy="64" r="16" fill="%23EBEBEB" fill-opacity="1"/><circle cx="16" cy="64" r="16" fill="%23DDDDDD" fill-opacity="0.67" transform="rotate(45,64,64)"/><circle cx="16" cy="64" r="16" fill="%23999999" fill-opacity="0.42" transform="rotate(90,64,64)"/><circle cx="16" cy="64" r="16" fill="%23cccccc" fill-opacity="0.2" transform="rotate(135,64,64)"/><circle cx="16" cy="64" r="16" fill="%23e1e1e1" fill-opacity="0.12" transform="rotate(180,64,64)"/><circle cx="16" cy="64" r="16" fill="%23e1e1e1" fill-opacity="0.12" transform="rotate(225,64,64)"/><circle cx="16" cy="64" r="16" fill="%23e1e1e1" fill-opacity="0.12" transform="rotate(270,64,64)"/><circle cx="16" cy="64" r="16" fill="%23e1e1e1" fill-opacity="0.12" transform="rotate(315,64,64)"/><animateTransform attributeName="transform" type="rotate" values="0 64 64;315 64 64;270 64 64;225 64 64;180 64 64;135 64 64;90 64 64;45 64 64" calcMode="discrete" dur="720ms" repeatCount="indefinite"></animateTransform></g></svg>');
}

With the release of Chome 72 it became apparent that the use of the ‘#’ in the colour values was invalid. I’ve replaced these with %23 to ensure they’re still rendered.

Force Updates in WordPress

If you manage many WordPress websites you’ll know the pains of keeping them up to date. Here are a few items you can add to your themes functions.php to force this process along. Obviously use this with caution and I’d strongly recommend NOT doing this on any site with e-commerce.

/* Updates */
add_filter( 'allow_minor_auto_core_updates', '__return_true' );
add_filter( 'allow_major_auto_core_updates', '__return_true' );
add_filter( 'auto_update_plugin', '__return_true' );
add_filter( 'auto_update_theme', '__return_true' );

Quick WordPress install with WP-Cli & Shell Script

I’ve recently been trying to automate more of development process. As a developer you know that you have these powerful skills and you should use them to a greater level to make your life easier. The problem is that it’s often hard to justify taking the time to do this if you’re already on a tight timeline. Needless to say I’ve finally created something that is helping remove 20-30 minutes from my developments.

I’ve been using the Vagrant repository Scotch Box for a while now. It is amazing! It’s a full LAMP stack with heaps of necessary included software. This includes Grunt, Gulp, Bower, Mailcatcher and WP-Cli (plus heaps more without being bloated). WP-Cli a great tool that allows you to run command line queries at your WP installs. I’d began using this plus a good old fashion text file of frequent install commands to speed up my process. It was finally this week that I put it into a script that I could easily run and have an install up in under 1 minute (it could be less if you have better download speeds).

 

#!/usr/bin/env bash

clear
#  Take User Inputs
read -p "Database name: " db
read -p "Site URL: " url
read -p "Site title: " title
pass=$(date +%s | sha256sum | base64 | head -c 32 ; echo)

# Start Install
mkdir /var/www/public/$url
cd /var/www/public/$url

# Download WP and Config
wp core download
wp core config --dbname=$db --dbuser=root --dbpass=root
wp db create
# Run WP Install
wp core install --url=$url --title="$title" --admin_user=my_admin_user --admin_password="$pass" --admin_email="morganl@6cm.com.au"

# Add and Remove Base Plugins
wp plugin install admin-menu-tree-page-view contact-form-7 akismet advanced-custom-fields
wp plugin delete hello

# Delete installed posts and create homepage
wp post delete $(wp post list --post_type='page' --format=ids) --force
wp post delete $(wp post list --post_type='post' --format=ids) --force
wp post create --post_type='page' --post_title="Home" --post_status="publish" 
wp option update page_on_front 3
wp option update show_on_front page

# Replace Uncategorized with a new Category as default
wp term create category News
wp option update default_category 2
wp term delete category 1

# Set Your Timezone - Most of you will want to change this
wp option update timezone_string Australia/Perth
wp option update blogdescription ""

# Options checkboxes the way I like them
wp option update default_pingback_flag 0
wp option update default_ping_status 0
wp option update default_comment_status 0
wp option update comment_registration 1

# Update rewrite (You'll still need to resave the Settings > Permalinks Page)
wp rewrite structure '/%year%/%monthnum%/%postname%'

# Copy base theme to site
cd wp-content/themes/
git clone https://github.com/morganleek/scm-wp-base.git
mv scm-wp-base 6cm
wp theme activate 6cm

# Create necessary Apache configs
cd /etc/apache2/sites-available/
sudo cp default.conf $url.conf
sudo sed -i "s/localpress/$url/g" $url.conf 
cd ../sites-enabled/
sudo ln -s ../sites-available/$url.conf $url.conf
sudo service apache2 restart

# Update /etc/hosts - You'll need to do this manually for your own machine
sudo sed -i "s/#addmore/$url #addmore/g" /etc/hosts

# Spit out username and password details
echo ""
echo ""
echo "CMS"
echo "---"
echo "User: my_admin_user"
echo "Pass: $pass"
echo ""

In addition you’ll also need to update your /etc/hosts file once to allow the script to add the new domain to your list of local sites. This usually just means adding #addmore to the end of your localhost domains list.

127.0.0.1 localhost mysite anothersite #addmore

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
127.0.1.1 scotchbox scotchbox

Remove WordPress Theme Update Notifications

I’ve built and maintain many WordPress websites. I really love WordPress’ ease of update, however having to maintain these sites I greatly dislike the constant theme updates. I understand the need to update themes you use, but why do I need to download a new Twenty-x theme every 12 months when I’m using a custom theme that’s not dependant on any of them?

In an effort to lighten my work load I went in search for a quick fix but came up empty handed. A quick poke through the WP core showed a handy filter I could change to quickly get my desired result.

Unfortunately because this is admin core functionality it needed to be in a plugin. If you have a base theme plugin add this to that, otherwise use as is.

<?php
/**
 * @package Remove_Theme_Updates
 * @version 1.0
 */
/*
Plugin Name: Remove Theme Updates
Plugin URI: https://morganleek.me/
Description: Remove annoying theme updates from WordPress. Don't use if you need your themes automatically updated.
Author: Morgan Leek
Version: 1.0
Author URI: https://morganleek.me/
*/

add_filter('site_transient_update_themes', 'remove_update_themes', 100, 1);

function remove_update_themes($value) {
    return null;
}

?>

Advanced Custom Fields and Woocommerce Location Rules

Just a short post about a Git I’ve started up. I recently needed to specify a couple of ACF fields to only appear on a ‘Simple Product’ type in ever popular Woocommerce. To my surprise there wasn’t an existing plugin that extended ACF location rules to integrate with Woo attributes. So I went about writing my very own. Recently deciding I wanted to give more back to the community that gives so much to me I stuck it up of Github.

I will continue to add attributes over the next few weeks. At the time of writing this post I currently have support for the following attributes.

  • Product Types (Simple, Grouped, External, Variable)
  • Product Variations (Downloadable, Virtual, Sold Individually)
  • Product Taxation (Product Taxable, Shipping Taxable)

Please download and comment on the Git should you find any issues. Also please make suggestions for additional features in the issues area.

Screen-Shot-2015-06-07-at-3.21.18-pm

Shopp Plugin Pinterest Rich Pins

Pinterest’s Rich Pins are a great way for clients to link their shopping cart products more deeply with Pinterest. It allows additional information like price, availability and location to be attached to the pin. I recently had a request to integrate the rich pins into a website and discovered no quick cut and paste solution for my clients (less popular) e-commerce WordPress plugin Shopp. Rich Pins essentially use Facebook’s Open Graph standard to implement the pins, so it didn’t seem like it was going to be a huge process. All the same I thought I’d share it here in hope of saving someone else a few minutes in the future.

Just to note unlike Facebook or Twitter this data will only be referenced once you clear your Rich Pin setup with Pinterest. A member of their team will visit your site and ensure they are set correctly. For more information about this and validating your Rich Pin pages see the Pinterest Rich Pin overview.

You’ll also need to manually set the currency, using the three letter codes available on XE. In my example the currency is set to AUD for Australian Dollars.

// Pinterest OG Tags            
if(function_exists('shopp')) {
    add_action('wp_head', 'shopp_rich_pins_head', 10);

    function shopp_rich_pins_head() {
        // Only run on product pages
        if(shopp('product.found')) {
            print '<meta property="og:type" content="product" />';
            print '<meta property="og:url" content="' . shopp('product.url', 'return=true') . '" />';
            if(shopp('product.has-images')) {
                print '<meta property="og:image" content="' . shopp('product.get-cover-image', 'property=url') . '" />';
            }
            print '<meta property="og:title" content="' . shopp( 'product.name', 'return=true' ) . '" />';
            // Check if price is on sale
            if(shopp('product','onsale')) {
            	// Pinterest treats the 'ammount' as the regular price 
	            // or the sale price if the item is on sale.
            	print '<meta property="og:price:amount" content="' . shopp('product.saleprice', 'number=true&return=true') . '" />';
            	print '<meta property="og:price:standard_amount" content="' . shopp('product.price', 'number=true&return=true') . '" />';
		    }
		    else {
		    	print '<meta property="og:price:amount" content="' . shopp('product.price', 'number=true&return=true') . '" />';
		    }

            print '<meta property="og:price:currency" content="AUD" />';
            print '<meta property="og:site_name" content="' . get_bloginfo('name') . '" />';
            print '<meta property="og:availability" content="instock" />';
            print '<meta property="product:gender" content="unisex" >';
        }
    }
}

Australia States & Territories Select Drop Down List

This is a quick one, possibly for my benefit more than anyone. Pretty tired of recreating select lists of the Australian states and territories when building forms. Also thought I’d include a couple of variations as we’ve really got a heap of territories you’re not always going to want.

<!-- States & Territories by Size -->

<select name="state">
	<option name="nsw">New South Wales</option>
	<option name="vic">Victoria</option>
	<option name="qld">Queensland</option>
	<option name="wa">Western Australia</option>
	<option name="sa">South Australia</option>
	<option name="tas">Tasmania</option>
	<option name="act">Australian Capital Territory</option>
	<option name="nt">Northern Territory</option>
</select>

<!-- States & Territories Alphabetical -->

<select name="state">
	<option name="act">Australian Capital Territory</option>
	<option name="nsw">New South Wales</option>
	<option name="nt">Northern Territory</option>
	<option name="qld">Queensland</option>
	<option name="sa">South Australia</option>
	<option name="tas">Tasmania</option>
	<option name="vic">Victoria</option>
	<option name="wa">Western Australia</option>
</select>

<!-- Complete List of States & Territories Alphabetical -->

<select name="state">
	<option name="aci">Ashmore and Cartier Islands</option>
	<option name="aat">Australian Antarctic Territory</option>
	<option name="act">Australian Capital Territory</option>
	<option name="ci">Christmas Island</option>
	<option name="ki">Cocos (Keeling) Islands</option>
	<option name="csi">Coral Sea Islands</option>
	<option name="himi">Heard Island and McDonald Islands</option>
	<option name="jb">Jervis Bay Territory</option>
	<option name="nsw">New South Wales</option>
	<option name="ni">Norfolk Island</option>
	<option name="nt">Northern Territory</option>
	<option name="qld">Queensland</option>
	<option name="sa">South Australia</option>
	<option name="tas">Tasmania</option>
	<option name="vic">Victoria</option>
	<option name="wa">Western Australia</option>
</select>

WordPress Metadata Media Naming

A client of mine recently ran into a problem. He had a large number of professionally shot photography for his business. Over the years he had gotten into the good habit of renaming his photos so they were easy to manage. The problem was that WordPress’ media manager was naming the photos using metadata that had been attached to the images by the DSLR that shot them. In his case all images where being called ‘SONY DCR’. I essentially needed to remove the metadata title when the image was uploaded so WP wouldn’t use it as the title. After some searching I found exactly what I needed in wp_read_image_metadata.

add_filter( 'wp_read_image_metadata', 'custom_upload_name' );  

function custom_upload_name( $file )
{
    $file['title'] = "";

    return $file;
}

Pretty simple solution, but it works nicely. Just add this to your functions.php file.