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" >';
        }
    }
}

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.

Ajax Driven WordPress Website (Server Side)

I recently built a website for a designer where he requested the entire thing be Ajax driven and WordPress managed. I have built websites like this in the past using both Drupal and WordPress. In the past however I feel I have made the process overly complicated on the client side, often requiring huge amounts of Javascript to display pages. Using different code for different layouts etc. In hindsight this was a bad idea for several reasons. Firstly search engines might not see the same layout as you are showing the user. Same goes for people with Javascript turned off. Large quantities of additional and unnecessary Javascript need to be written. Finally it is a much longer development process from the method I chose this time.

Though this method was more difficult from the client side of scripting, it was much simpler from the server side perspective. I would create a page in WordPress called Ajax. Then write a custom template that would take a $_GET parameter of ‘URL’, get the post ID from the URL, get the post by that ID and simply pass the post object back as a JSON object. This is very simple (1-2 lines of code), except when you come to laying out your pages and need to specify where each individual div should go. To call it was simple, http://yoursite.com/ajax?URL=/about. To maintain it was a nightmare!

What I wanted this time was the ability to create the entire website just as I would without AJAX in mind. Style all the pages and create whatever templates I need using CSS and HTML. This saves a great deal of time when just doing little things. Believe me a refresh without AJAX is always much quicker than with, and if you think how many times you refresh when developing it makes a massive difference. Then I would in a similar way to my original method create a WordPress page called Ajax which I’d pass a $_GET parameter of URL to. However instead of grabbing the post as an object I would have the template grab the entire page content as a browser would receive it. This means any styles, template structure and custom fields will already have been applied and formatted. I’d simply need to fish out the divs I want and pass them back as a JSON object. Then simply replace the existing ones on the page. For me this meant just taking out the #main div and replacing the existing one. You also need to extract some other elements for styling reasons. I for example needed the classes listed in the body tag too.

You will require a really great PHP script to retrieve and extract the DOM elements in your AJAX called Simple HTML Dom. Below is my AJAX template class. There is almost zero error checking.

<?php
/*
Template Name: Ajax Post
*/

include("wp-content/themes/6cm/scripts/simple_html_dom.php");

// URL
if(isset($_GET['url'])) {
	$url = $_GET['url'];
	if($url != "") {
		// Get post
		$post = get_post(url_to_postid($url));
		// Add paragraphs
		$post->post_content = wpautop(do_shortcode($post->post_content));

		// Get entire page
		$html = file_get_html(get_bloginfo('url') . $url);
		// Extract just <div id="main">...</div>
		$ret = $html->find('div[id=main]', 0);
		// Extract <body> classes
		$body = $html->find('body', 0);
		$body_class = $body->class;
		// Get page scripts
		// $script = $html->find('head script', 1);

		// Create JSON Array
		$json_return = array();
		$json_return['html'] = $ret->innertext;
		$json_return['post_object'] = $post;
		$json_return['body_class'] = $body_class;
		// $json_return['script'] = $script;

		// Print JSON
		print json_encode($json_return);
	}
}
else {
	print 0;
}
?>

Next step is to implement a Javascript/jQuery deep linking script like Asual to write deep links. This allows users to easily make their way to specific pages and not experience the one page woes of Flash websites. You’ll also need to implement jQuery AJAX functions to call and replace content when links are change.

I’ll return shortly to write about my Client side scripting for this project. Hope this can be helpful for someone.