Categories
Events Tutorials

WPCampus 2016: WordPress Masterclass Workshop

Getting ready

So you’ve decided to take part in Morten Rand-Hendriksen’s WordPress Masterclass at WPCampus? Great! If you want to get the full experience and play along as Morten messes up the code of a WordPress site to make it work the way he wants it to, here are the preparatory steps you need to take:

  1. Set up a local version of WordPress on your laptop. You can use your own preferred development environment or a custom install. If you’re on Windows, simple options include WAMPServer or DesktopServer. If you’re on Mac, use MAMP or DesktopServer.
  2. Make sure the Twenty Sixteen theme is installed and activated (if you are setting up a new WordPress install, this is the default).
  3. Download and install the custom demo content prepared for the workshop (right-click + Save Link As). To install the demo content, go to the WordPress admin panel, select Tools -> Install, select WordPress, install the WordPress Importer, and follow the instructions. Make sure to check the Download and import file attachments box.
  4. Make sure you have a working code editor on your computer. Morten will be using the free, open source Atom code editor. You can use any code editor you prefer.

During the actual workshop, you’ll be provided with code examples and instructions on how to build a custom child theme and how to extend that child theme with custom post types, taxonomies, and even custom fields.

Part 1: Build a Twenty Sixteen Child Theme

In the first hour of the workshop, we’ll build a child theme with Twenty Sixteen as the parent. The purpose of building this child theme is to gain full control of the appearance and functionality of the theme without having to a) build it from the ground up, and b) modify the original code.

To make it easier for you to follow along, I have created a series of Gists – code snippets shared on Github’s servers – that provide the individual components I’ll be building in the workshop. As we move through the different code snippets, I’ll explain where to put them, how they work, and how you can modify them to make your child themes work the way you want.

I’ve broken down each of the workshops into individual sections that follow a logical chain of events so to speak, but for the most part you can apply these code snippets in any order you want, or individually. I’ve also provided links to the relevant Codex and Handbook documentation for specific functions and they are introduced.

That’s enough talk. Let’s get crackin’!

Categories
Tutorials

Using Media Queries in JavaScript with enquire.js for Responsive Masonry and More

Ever wanted to toggle JavaScript on and off with media queries only to discover you cant? Instead you have to write a huge pile of JavaScript to monitor the initial and changing document width and toggle the script on and off manually. This is cumbersome and requires an unreasonable amount of code to do something that should be simple.

Enter enquire.js by Nick Williams: A tiny JavaScript file that allows you to use media queries to toggle JavaScript on and off the same way we use them to toggle CSS on and off. This is such a simple and ingenious solution I had to write a tutorial about it. Bear in mind what I’m showing you here is an extremely simple example. Enquire.js has huge potential that goes far beyond my example. Nevertheless this example should get you up and on your way and will show you how to solve a common and frustrating problem along the way!

Responsive Masonry and other Castles in the Sky

This is the preamble. If you’re just looking for the actual example you can skip this part.

If you scroll to the bottom of my site right now and resize the width of your browser window you’ll see that  the widgets in the footer are tiling and reorganizing in a clean and structured way thanks to Masonry.

Masonry and more evolved varieties like Isotope have changed the way we organize, display, and consume content on the web thanks to their relative responsiveness and ability to take advantage of various changing screen sizes.

The problem with these JavaScript solutions that change the behaviour of your content (Superfish for drop-down menus comes to mind) is that when you display the content on smaller screens you often want these scripts to shut down. In the case of Masonry on this site, when you get to a screen width below 880px wide I no longer want Masonry to be involved. Instead I want the widgets to stack vertically and be full width.

To do this I can write a huge stack of JavaScript as I outlined earlier or I can use the fairly wonky CSS approach recommended by Masonry, but none of this is ideal:

If we approach the problem from a mobile-first perspective we really shouldn’t load Masonry or a script to test whether Masonry should run on smaller devices. It’s a waste of resources and the script just sits there bugging the browser when it shouldn’t be there at all. A better solution would be to only load the script when the screen is or gets wide enough. And that’s exactly what enquire.js lets us do!

Toggling Masonry On and Off with enquire.js

I’m using Masonry as the example here but this same approach can be used for any JavaScript that should change based on media query type events like document width.

Say we have a WordPress site in which we want to control our footer widgets with Masonry. And let’s assume we already have a footer with a widgetized area with the ID #footer-widgets and that each of the widgets has the class .widget. A standard setup in other words.

In this scenario we can deploy Masonry by writing a small script file and pulling the library it right from WordPress core.

The script file, saved in the theme under the /js/ folder with the name masonry-settings.js looks like this:


// Masonry settings to organize footer widgets
jQuery(document).ready(function($){
  var $container = $('#footer-widgets');
  $container.masonry({
    columnWidth: 400,
    itemSelector: '.widget',
    isFitWidth: true,
    isAnimated: true
  });
});

Now we have to enqueue the script and add Masonry as a dependency. This is done in functions.php:


wp_enqueue_script( 'my-masonry', get_template_directory_uri() . '/js/masonry-settings.js', array('masonry'), '20140429', true );

This will make Masonry kick in and set the column width at 400px in the footer which is fine for larger screens. However if you start narrowing the width of  your screen you’ll see this doesn’t work very well.

What we want to do now is toggle Masonry on and off at a certain width breakpoint, in our case 880px: Narrower than 880px and Masonry is not loaded, wider than 880px and Masonry does its thing.

For this we’ll use enquire.js. First get the single enquire.js.min file from the site and dump it in your theme /js/ folder. Next we need to enqueue the file the same way we enqueued our Masonry settings. Enquire has no dependencies so we’ll set the dependency attribute to false:


wp_enqueue_script( 'my-enquire', get_template_directory_uri() . '/js/enquire.min.js', false, '20140429', true );

Now enquire.js is loaded but we need to tell it what to do. Here we’re going to make some modifications to our original masonry-settings.js file to add some media query magic:


// Masonry settings to organize footer widgets
jQuery(document).ready(function($){
  var $container = $('#footer-widgets');
  enquire.register("screen and (min-width:880px)", {

    // Triggered when a media query matches.
    match : function() {
      $container.masonry({
        columnWidth: 400,
        itemSelector: '.widget',
        isFitWidth: true,
        isAnimated: true
      });
    },

    // Triggered when the media query transitions
    // from a matched state to an unmatched state.
    unmatch : function() {
      $container.masonry('destroy');
    }

  });
});

Let’s break it down:

First we register enquire.js and give it a media query:


enquire.register("screen and (min-width:880px)", {}

Then we supply enquire.register with the match and unmatch objects that as their names suggest trigger when the media query either matches (true) or unmatches (false):


enquire.register("screen and (min-width:880px)", {
  // Triggered when a media query matches.
  match : function() {
    // Turn Masonry on
  }

  // Triggered when the media query transitions
  // from a matched state to an unmatched state.
  unmatch : function() {
    // Turn Masonry off using destroy
  }

}

Now all that’s left is slotting in our original Masonry code within Match and call masonry(“destroy”) on unmatch and we’re done!

Other uses (*cough* Superfish *cough*)

Now that you see how easy it is to use enquire.js and how you can mix it in with your JavaScript here is another example of how the script is being used in the current theme you are looking at:

The main menu in this theme is keyboard accessible through its drop-down items (none are present so you just have to trust me on this one). This is achieved using the Superfish jQuery plugin. The problem is on smaller screens the mobile menu kicks in and Superfish goes from being a big help to being a royal pain in the ass. To solve this we need to turn it off when the mobile menu is displayed.

Since we’ve already enqueued enquire.js all we have to do is make some small changes to the /js/superfish-settings.js file:


/* Custom Superfish settings */
jQuery(document).ready(function($){
  var sf= $('ul.nav-menu');
  enquire.register("screen and (min-width:600px)", {

    // Triggered when a media query matches.
    match : function() {
      sf.superfish({
        delay: 200,
        speed: 'fast'
      });
    },

    // Triggered when the media query transitions
    // from a matched state to an unmatched state.
    unmatch : function() {
      sf.superfish('destroy');
    }

  }); 
});

Looks awfully familiar, doesn’t it? That’s because it’s exactly the same thing. So easy and it just works.

Enquire for yourself

Now that you know enquire.js exists and you’ve seen how easy it is to use you need to go out and try it for yourself. Once you’ve done so, report back and let me know how you fared. I’m curious to see what others end up doing with it. I have barely scratched the surface of what’s possible here so there is a world of possibilities waiting to be explored!

Categories
Tutorials WordPress

Adding Borders to WordPress Images the Right Way – a.k.a. Why Inline Styles Have No Place In Your Posts

As with most updates to popular software the 3.9 release of WordPress has brought with it some controversy. In this case the point of contention is the removal of a little known feature that allowed the user to add borders and margins (vertical and horizontal “space”) to individual images right from within the image editor. The feature was removed and not surprisingly those that used and depended on it are enraged. WP Tavern has a great rundown of the story complete with links to forum posts so I’m not going to rehash it here. Instead I’ll show you how to add borders to images the right way, explain why inline styles are to be avoided whenever possible, and finally provide a suggestion on how theme developers can prevent this type of issue from happening again.

How to Add Borders to Individual Images the Right Way in WordPress

So, when you have an image, you want that image to have a border, and your theme doesn’t apply a border automatically, what do you do? You add some CSS. And that CSS needs to be added separately from the content. In other words no inline styles.

Depending on your level of skill this may or may not seem like a big deal. I’m here to tell you it’s actually super easy. Let’s say you know nothing about HTML or CSS or anything else. Here’s all you have to do:

  1. Install and activate Jetpack (the plugin)
  2. Go to Jetpack, find Custom CSS, and click the Customize button
  3. Create some new style rules

Customize CSS with Jetpack
Let’s say you want to add a black border. Here is the code required:


.border-black {
    border: #000 solid 1px;
}

Want a gray border instead? Here’s the code for that as well:


.border-gray {
    border: #b9b9b9 solid 1px;
}

With your new CSS rules in place you are ready to apply them to your image. To do so go to your post, find your image, click the edit button by hovering over that image, and in the edit window click the Advanced Options tab to open the Advanced Options.

Adding new CSS classes to images using the Advanced Image Option

From here all you have to do is enter the class name for your CSS rule (“border-black” for black, “border-gray” for gray) in the Image CSS Class field and save your image.

If you want to add multiple classes you can. Just separate them with a space. Also, remember to not put the dot (punctuation mark) in front of the class names. This is not necessary.

If you look at the image above you’ll see it has a black border. This border was added using the exact method described in this tutorial.

Edit: In the comments Caspar Hübinger points out you can also use the Simple Custom CSS plugin to add CSS to your site without adding all the bulk of Jetpack.

Explanation

So what have we done here? First we created two new CSS rules that define a 1px border around any element that is either black or gray. Then we use the WordPress editor to apply those styles to our image through a class. And voila! The image has a border.

The key difference between this approach and that of adding the border with an inline style is that we can now quickly change the border on all images at once by editing the custom CSS. And since we used the Custom CSS function in Jetpack the border will persist even if we switch to a different theme.

Jetpack? You must be off your rocker Morten

At this point if you’re a seasoned WordPress pro you’re probably blowing a gasket over my recommendation of Jetpack. “Jetpack is huge and cumbersome and slows the site down and there are a million other better more awesome solutions etc etc etc.” And this is true. I am no fan of Jetpack. However we have to consider the end-user here: If  you are using the add image border function you probably do so because you don’t want to tamper with your theme or child theme. If that’s the case, Jetpack provides an easy way around the problem. Of course if you have the skills and the time you can add the exact same code to your child theme or custom theme you built from scratch, but this is not a workable solution for the majority of WordPress users. Jetpack is.

Inline Styles are Bad, Mmmmmkay?

Some will interject here and say that you can achieve the same thing by using inline styles. After all that’s what the old solution did and what the new Advanced Image Styles plugin does. Here’s some sobering web standards news: Inline styles is a non-starter. To understand why you need to understand how HTML and CSS interact and why inline styles have no place in WordPress content.

There are two main types of code that go together to create a website:

  • HTML
  • CSS

The HTML marks up the content and tells the browser or other reader how different parts of the content relate to each other. The CSS adds a presentational layer to that markup telling the browser or other reader how to display that content. This provides a clear separation between style and content and it works exceptionally well, especially in applications like WordPress where we can switch themes (and with them the CSS) of the content and see a global change in the appearance of the content without having to change the content itself.

Inline styles are an old leftover from the time when CSS was just being introduced and they work counter to the separation I explained earlier. An inline style allows you to place CSS code inside the tag of any element meaning that style only applies to this singular element. That’s what a function like add borders and space does: It puts presentational code inside the markup.

Why is this bad? There are many reasons:

  • The inline style will apply everywhere regardless of where you display the content.
  • The inline style overrides any CSS supplied by a stylesheet and interferes with media queries and other responsive approaches.
  • The inline style applies to one element only and cannot be easily repeated (ie it has to be applied to every single element).
  • The inline style does not allow us to make a global change to the style that applies to all elements at once.
  • The inline style is presentational code placed in the markup. This goes against current web standards and should be avoided.

There are very few cases where inline styles are appropriate. The only one I can think of is where you use PHP to inject a conditional background image into a specific element, but even there we have better ways of approaching the problem. Needless to say inline styles have no place in WordPress, and especially not in adding borders or margins to images.

But what about margins?

I’m sure you’re itching to point out that my proposed solution only addresses borders, not “space” or margins. And you’d be right. Of course you can use the same approach as before to add margins as well but I have serious reservations about this which I’ll explain in a few paragraphs. However, if you must tamper with the margins I’d make sure to add them as separate CSS rules. I’m willing to bet that if you are adding custom margins it is because the positioning of your images out of the box is not ideal. So essentially you are fixing a layout problem in the theme. Chances are you also add different margins depending on the image, but you tend to add the same set of margins over and over. In that case you create a new CSS rule for each of your margin scenarios and apply them as necessary the same way we applied the border.

As an example you could have this margin rule:


.margin-medium {
    margin: 0 1em 2em;
}

which adds a margin of 0px on top, 1em on left and right, and 2em on the bottom. Then to apply both the black border and the margin you simply enter “border-black margin-medium” in the Image CSS Class section for the image.

Now that you know how to do it I’m going to strongly recommend you don’t mess with the margins. This requires a bit more of an explanation:

The Problem

The problem at hand is not one of deprecated WordPress features nor of bad user behaviour. The cause of the outrage and frustration is that theme developers are not accounting for the user scenario where the user wants to add a border. When there is no option the user will find a new way of doing it outside of the theme and this is not ideal for anyone.

There are many reasons why you’d want to add a border. The most obvious one is if your image background color matches the color of your theme so there is no clear separation between the image and the main background. I’ve encountered this many times and this is why my themes ship with custom CSS to address this particular issue. More on that in a bit. Let’s first take a look at what happens when you add images to a post or page in WordPress:

When you add an image to a post or page in WordPress you also add some CSS classes to that image. The classes vary depending on the image size and alignment and other factors. A good theme has CSS rules that apply  to these classes and provide proper margin and padding for all images. And this is why messing with the margins is a bad idea:

In a good theme the designer and developer has made decisions about how an image is to be presented in relation to other content based on its size and alignment. That means margin has been added where required and removed where it shouldn’t be. If you go in and start adding or subtracting margins you are interfering with what the theme does out of the box and this can lead to crazy behaviour, especially when you switch to a new theme.

Here’s the thing: If your images jam up against text or other elements in your theme it is either the explicit decision of the theme developer that they do so or more likely the theme is not all it’s cracked up to be. Yep, I said it: If your images look wrong in context, your theme is likely not worth its salt and you should look for another one.

The Solution: A Unified Border Class Name Standard

There is an obvious solution to this issue that will allow users to do what they want (add borders to images) while ensuring cross-theme compatibility while avoiding the addition of plugin functionality like Jetpack Custom CSS or plugins that add inline styles: Create a unified border class name standard.

All theme developers should add a set of CSS rules targeting a pre-defined list of border classes the user can call when required. The list could look something like this:


.border-thin-black {
    border: #000 1px solid;
}

.border-medium-black {
    border: #000 3px solid;
}

.border-thick-black {
    border: #000 5px solid;
}

.border-thin-gray {
    border: #b9b9b9 1px solid;
}

.border-medium-gray {
    border: #b9b9b9 3px solid;
}

.border-thick-gray {
    border: #b9b9b9 5px solid;
}

In addition theme developers could make rules whose colors are set through the customizer with class names like .border-thin-custom. That way custom colors can be introduced as the user switches themes while the predefined colors stay intact.

Let your voice be heard

I know you have opinions on this. Don’t internalize your strife. Voice your thoughts, concerns, and opinions in the comments below and start a conversation.

Categories
Tutorials WordPress Tips

How to add proper pagination as default in WordPress themes

When you scroll to the bottom of an index page on a WordPress site, what do you see? Chances are it’s two links, one saying “Older Posts” and one saying “Newer Posts”. Scarcely has any default setting been more engagingly uninformative, and unnecessarily so. This “let’s not tell the visitor where she is on the site nor how much other content is available” approach to navigation is the epitome of User Experience archaism and should be but a footnote in the annals of WordPress history. Instead it is a cornerstone of the free WordPress theme experience and the default setting for all baseline WordPress themes (_s included) with one groundbreaking exception: Twenty Fourteen.

It is time we the people who build WordPress themes cast aside the rotting corpse of Older and Newer posts and replace it with proper pagination. After all the function is already built into WordPress – in fact it has been for a very, very long time. So, without further ado let me provide you with the code you need to get started and a few tweaks to move your WordPress pagination into the 21st century.

paginate_links() – the old friend you never knew you had

You don’t need fancy plugins or custom code to get proper pagination in your index pages. The paginate_links() function will do that for you in a snap. Here it is in its most basic form, straight from the Codex:


<?php
global $wp_query;

$big = 999999999; // need an unlikely integer

echo paginate_links( array(
	'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
	'format' => '?paged=%#%',
	'current' => max( 1, get_query_var('paged') ),
	'total' => $wp_query->max_num_pages
) );
?>

(If you’re wondering what the $big variable is for it helps output a clean URL when the page is loaded. Pay no mind.)

Slot this code into your template file where you want the pagination to appear (i.e. replace the current Older Posts and Newer Posts code with this one) and you’re good to go. If you want the basic solution that is. Which probably isn’t what you want.

Options Aplenty

Luckily for us we don’t have to be content with the default example above. paginate_links() has plenty of parameters we can use to change its output. The parameters you should care about from a design perspective are:

  • end_size: Decides how many numbers to display at the start and end of the list. Defaults to 1 meaning you’ll get output like this: 2 … 5 6 7 … 10. If you change the number to 2 you’ll get 2 3 … 5 6 7 … 9 10. You get the idea. Visually 1 looks best but in some cases you may want to change this value.
  • mid_size: Decides how many numbers to display on the left and right side of the current page (not including the current page). Defaults to 1. So if you set mid_size to 2 and are on page 6 you’d get 2 … 4 5 6 7 8 … 10.
  • prev_next: True or false decides whether a Previous and Next link should appear in the list or not. The actual wording is controlled separately (see below).
  • prev_text and next_text: The actual text output displayed if prev_next is set to true. Default output is « Previous and Next » and the strings are wrapped and prepared for translation.
  • type: Decides what the function outputs. The default plain outputs a list of anchor tags (links) which imo makes no sense. This can be switched to either array (great if you want complete control and know how to handle arrays in PHP) or list which outputs an unordered list and should be the default setting. I strongly recommend  setting type to list so you can work with the output in a reasonable way.

There are other variables but they are technical and control the functionality which I’ll address at the end of this article.

Upcycling existing code

Proper WordPress Pagination
So, let’s say you want to add pagination to your site (not unlike what you see directly above here) and you want to do it in a clean way. In that case it behooves you to create a function, stash it in functions.php or template-tags.php in your theme or child theme, and call it in when necessary. The easiest way to get this working, and working properly, is to upcycle the function provided in Twenty Fourteen and make some subtle changes to its output:


<?php

if ( ! function_exists( 'yourtheme_paging_nav' ) ) :
/**
 * Display navigation to next/previous set of posts when applicable.
 * Based on paging nav function from Twenty Fourteen
 */

function yourtheme_paging_nav() {
	// Don't print empty markup if there's only one page.
	if ( $GLOBALS['wp_query']->max_num_pages < 2 ) {
		return;
	}

	$paged        = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
	$pagenum_link = html_entity_decode( get_pagenum_link() );
	$query_args   = array();
	$url_parts    = explode( '?', $pagenum_link );

	if ( isset( $url_parts[1] ) ) {
		wp_parse_str( $url_parts[1], $query_args );
	}

	$pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
	$pagenum_link = trailingslashit( $pagenum_link ) . '%_%';

	$format  = $GLOBALS['wp_rewrite']->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
	$format .= $GLOBALS['wp_rewrite']->using_permalinks() ? user_trailingslashit( 'page/%#%', 'paged' ) : '?paged=%#%';

	// Set up paginated links.
	$links = paginate_links( array(
		'base'     => $pagenum_link,
		'format'   => $format,
		'total'    => $GLOBALS['wp_query']->max_num_pages,
		'current'  => $paged,
		'mid_size' => 3,
		'add_args' => array_map( 'urlencode', $query_args ),
		'prev_text' => __( '&larr; Previous', 'yourtheme' ),
		'next_text' => __( 'Next &rarr;', 'yourtheme' ),
		'type'      => 'list',
	) );

	if ( $links ) :

	?>
	<nav class="navigation paging-navigation" role="navigation">
		<h1 class="screen-reader-text"><?php _e( 'Posts navigation', 'yourtheme' ); ?></h1>
			<?php echo $links; ?>
	</nav><!-- .navigation -->
	<?php
	endif;
}
endif;

?>

To make this work in a template simply call the function like this:


<?php yourtheme_paging_nav(); ?>

The function will output clean HTML markup with the pagination links wrapped in list items within an unordered list like this:


<nav class="navigation paging-navigation" role="navigation">
	<h1 class="screen-reader-text">Posts navigation</h1>
	<ul class='page-numbers'>
		<li><a class="prev page-numbers" href="http://localhost/page/7/">&larr; Previous</a></li>
		<li><a class='page-numbers' href='http://localhost/'>1</a></li>
		<li><span class="page-numbers dots">&hellip;</span></li>
		<li><a class='page-numbers' href='http://localhost/page/5/'>5</a></li>
		<li><a class='page-numbers' href='http://localhost/page/6/'>6</a></li>
		<li><a class='page-numbers' href='http://localhost/page/7/'>7</a></li>
		<li><span class='page-numbers current'>8</span></li>
		<li><a class='page-numbers' href='http://localhost/page/9/'>9</a></li>
		<li><a class='page-numbers' href='http://localhost/page/10/'>10</a></li>
		<li><a class='page-numbers' href='http://localhost/page/11/'>11</a></li>
		<li><span class="page-numbers dots">&hellip;</span></li>
		<li><a class='page-numbers' href='http://localhost/page/14/'>14</a></li>
		<li><a class="next page-numbers" href="http://localhost/page/9/">Next &rarr;</a></li>
	</ul>
</nav><!-- .navigation -->

Now all you need is some basic CSS to make it all look good:


/* =Index pagination
----------------------------------------------- */

/* The containing box with a nice white background */
.paging-navigation {
	font-family: sans-serif;
	padding: 1em;
	background: #fff;
	background: hsl(0, 0%, 100%);
}

/* Remove bullets and list indentation */
.paging-navigation ul {
	list-style-type: none;
	margin: 0;
	padding: 0;
}

/* Make the list items appear horizontally */
.paging-navigation li {
	display: inline;
}

/* Give each link and the current item some padding to make them easy to click */
a.page-numbers,
span.page-numbers {
	padding: .3em .7em;
	color: #333;
	color: hsl(0, 0%, 20%);
}

/* Link hover state */
a:hover.page-numbers {
	color: #000;
	color: hsl(0, 0%, 0%);
}

/* Current page bold and dark */
.paging-navigation .current {
	font-weight: bold;
	color: #000;
	color: hsl(0, 0%, 0%);
}

Of course you can elaborate on this to your heart’s content, but this is the gist of it.

Go Forth and Paginate

Now that you see how easy it is to add proper pagination to your WordPress index pages I think you will agree with me there is no good reason to keep the old Older and Newer posts links in place. If you don’t agree with me, by all means leave your disagreements in the comments below and let’s have a discussion. Otherwise, familiarize yourself with paginate_links(); and give your visitors a better user experience.

Categories
Lynda.com Tutorials

A bugfix for WordPress 3: Building Child Themes on lynda.com

With the update of WordPress to version 3.4 came some important feature improvements that changed the way certain key components work. This includes how the header image and background functionality is implemented. This in turn means the old methods of making changes to these elements suddenly don’t work any more.

The Issue

This change has made a previously well functioning component in my WordPress 3: Building Child Themes course on lynda.com non-functional.

In movie 2.3 I instruct the viewer to redefine the height and width of the header image using the following code in a child theme functions.php file:


<?php
define( 'HEADER_IMAGE_WIDTH', apply_filters( 'twentyten_header_image_width', 980 ) );
define( 'HEADER_IMAGE_HEIGHT', apply_filters( 'twentyten_header_image_height', 224 ) );
?>

Unfortunately with the new implementation of the header image function, this no longer works. A new filter function is needed.

The Fix

To get the result you want without messing things up in the process, a modified version of the code above is necessary. So, to resize the header image in a child theme of Twenty Ten you use the following code:


<?php
function tnc_header_width($width) {
	$width = 980;
	return $width;
}

function tnc_header_height($height) {
	$height = 224;
	return $height;
}

add_filter( 'twentyten_header_image_width', 'tnc_header_width' );
add_filter( 'twentyten_header_image_height', 'tnc_header_height' );

?>

An Update is Imminent

We are hard at work rolling out an update to the course to bring it in line with the new version of Twenty Ten. Until then, just use the code above and everything will work fine.

Categories
Responsive Design Tutorials WordPress

Automatic responsive videos in WordPress with oEmbed, FitVids and a little PHP magic

Automaitc responsive videos in WordPress with oEmbed, FitVids and PHP
UPDATE: I’ve added a 4th step to the list to remove automatic inline styles from being inserted when embedding videos.

If you’re using a responsive theme on your WordPress site (or you’ve built a responsive theme) and you’ve added YouTube, Vimeo or other videos using oEmbed you will undoubtedly have noticed those videos do not resize with the rest of the frame. And that’s a royal pain. Fortunately there are solutions out there that can fix this, but they are a little tricky to implement. In this tutorial I’ll share with you a method for making the process automatic so you don’t have to worry about it.

The Problem

Responsive themes use percentage values, media queries and other coding magic to make the content resize to fit the size of the window. But when you embed videos from YouTube etc using the built in oEmbed function in WordPress (i.e. just paste in the URL to the video and it appears automatically) that video is inserted with a fixed width and height. As a result when the rest of the page resizes to fit the window, the video stays the same size causing all sorts of problems. This is sub optimal.

FitVids to the rescue… almost

Realizing this is a frustrating problem Chris Coyier and Paravel created a clever little jQuery plugin called FitVids that when installed automatically resizes videos along with the rest of the content. FitVids attaches to specified containers and forces the video iframes within these containers to resize along with it. Very clever and it works exactly as expected. However, to make this work you have to wrap the video in a container with a specified class. So if you want to use the oEmbed method you have to go to HTML view, create a div with a class and then put the URL inside it. Which kind of takes away the whole point of using oEmbed which is simplicity.

The Solution

What is needed is a function that automatically wraps all oEmbed videos in a div with the correct class that applies FitVids so all the user has to do is paste in the link to the video and then WordPress does the rest. And that’s just what we’re going to do:

Step 1: Enqueue FitVids

Go download FitVids.js from GitHub and add the jquery.fitvids.js file to your theme. I place all my JavaScript files in a sub-folder called ‘js’ for simplicity. Then we need to enqueue the script and associate it with jQuery. This is done in functions.php:


<?php 
// Add FitVids to allow for responsive sizing of videos
function your_theme_fitvids() {
	if (!is_admin()) {

		wp_register_script( 'fitvids', get_template_directory_uri() . '/js/jquery.fitvids.js', array('jquery'), '1.0', true);    	
		wp_enqueue_script( 'fitvids');
	}
}

add_action('init', 'your_theme_fitvids');
?>

This function loads the jquery.fitvids.js file along with the packaged version of jQuery that comes with WordPress whenever a page is loaded.

Step 2: Create a function to target the videos

To make FitVids work you need to add a JavaScript function targeting a specific class. The function looks like this:


<?php
add_action('wp_footer', 'add_fitthem');
    	
function add_fitthem() { 
	    	jQuery(document).ready(function() {
    			jQuery('.video').fitVids();
    		});
}

All that happens here is the action is loaded in the footer (so it doesn’t slow down the population of the page itself and allows the videos in the iframes to load properly). It then appends the function to the .video class so that any video inside a div with the class video will be scaled to size.

This function is combined with the previous function so they get called at the same time. The resulting function looks like this:


<?php
// Add FitVids to allow for responsive sizing of videos
function your_theme_fitvids() {
	if (!is_admin()) {

		wp_register_script( 'fitvids', get_template_directory_uri() . '/js/jquery.fitvids.js', array('jquery'), '1.0', true);    	
    	wp_enqueue_script( 'fitvids');
    	add_action('wp_footer', 'add_fitthem');
    	
    	function add_fitthem() { 
		    	jQuery(document).ready(function() {
	    			jQuery('.video').fitVids();
	    		});

	    }
	}
}

add_action('init', 'your_theme_fitvids');

Step 3: Automatically wrap oEmbed videos in a div with a class

The last step is to change the oEmbed output so that it automatically wraps the video iframe in a div with the class .video. This is done using a filter:


<?php
// Automatically add FitVids to oembed YouTube videos
function your_theme_embed_filter( $output, $data, $url ) {

	$return = '<div class="video">'.$output.'</div>;
	return $return;

}
add_filter('oembed_dataparse', 'your_theme_embed_filter', 90, 3 );
?>

This function grabs the output of the oembed_dataparse function (the one that creates the final code when you paste in a video URL) and wraps it in the correct div.

Step 4: Set Maximum Embed Size to 0

To get everything to work properly you have to go to Settings -> Media and set both width and height under Maximum Embed Size to 0. If you have a value in either of these fields, WordPress will include inline style code to constrain the size of the video and as a result the automatic resizing will not work.

That is all! When you add new videos to posts and pages using the oEmbed function, they are not automatically wrapped in the correct div and class and FitVids is applied. And voila: Your videos are responsive.

Caveat: These functions are not recursive!

The only catch with this process is that it is not recursive. By that I mean it doesn’t automatically work on videos that have already been embedded on your site. That is because the oembed_dataparse() function is called the when the post is published or updated. As a result, the function has already been run on old content and to apply the new div and class you have to re-run it. Fortunately that just means going in and clicking the Update button for each of the posts that have oEmbed videos in them, but if you have hundreds of videos you may want to consider doing some sort of database search/replace action.

To avoid the recursive problem I suggest you add this function to your theme at the very beginning and be done with it. That way as you populate your site the all your videos will be responsive.

Comments? Questions? Problems?

Got something to say? Leave a comment below.

Categories
Tutorials WordPress

Simple video embedding with custom fields in WordPress – YouTube

Creating a custom video field in WordPressOne of my primary goals when building WordPress themes for my clients is to make it as easy as possible for them to post and manage content. And though video embedding has become much simpler over the years, controlling the video content can still be a bit of a pain, especially if you can’t remember the width of your content or if you have an index page where you want to showcase video thumbnails rather than the actual video.

To simplify the process I usually resort to a custom meta box but the technique works just as well with custom fields.

This is the first of two tutorials on this topic and here I’ll be focusing on YouTube videos and oEmbed. The next tutorial will be on self-hosted videos and VideoJS.

Auto-Embedding YouTube videos with a custom field

Consider the following scenario: You have a design that calls for videos to be embedded outside of the main content, for example by placing it above the headline. This is becoming more and more common, and provides both a better user experience and easier access to the important content in the post. The problem of course is that regular video embedding puts the video in the post body, and that’s not what we want. Enter the custom field option.

First thing first: In the post you want to present the video, create a new custom field with the name video_url and the value set to a normal YouTube video ID (the illegible part at the end of the video URL).

Now you have a custom field carrying the YouTube video value. The next step is to dump it into your theme so WordPress can display it. For this we’re going to use the built in oEmbed functionality in WordPress which when used normally lets you dump in a YouTube URL and then automagically inserts the embed code. But in our case we’re adding the URL dynamically in the theme so we are going to use the wp_oembed_get() function a function. The end result is the code you see below:


<?php
// Get the video URL and put it in the $video variable
$videoID = get_post_meta($post->ID, 'video_url', true);
// Echo the embed code via oEmbed
echo wp_oembed_get( 'http://www.youtube.com/watch?v=' . $videoID ); 
?>

The code above places the embed code dynamically generated from the YouTube URL wherever the code is placed in your theme (this of course has to go inside the loop).

Making it conditional

Normally I wrap the code above in divs to control the behavior and place the video where I want it. Because I’m neurotic about clean code I insist on always using conditionals in cases like this to avoid leaving empty divs lying around when no video was added through the custom field. With the conditional added the code gets a bit expanded, but works the same way:


<?php
// Get the video URL and put it in the $video variable
$videoID = get_post_meta($post->ID, 'video_url', true);
// Check if there is in fact a video URL
if ($videoID) {
	echo '<div class="videoContainer">';
	// Echo the embed code via oEmbed
	echo wp_oembed_get( 'http://www.youtube.com/watch?v=' . $videoID ); 
	echo '</div>';
}
?>

Now the video will display wherever you place the code on the provision a video URL was actually added with a custom field.

Getting a video thumbnail from YouTube

So far we’ve just made a fancy way of embedding videos, and it might seem a bit superfluous to do so seeing as you can just add the video right in the post body. But there’s a reason you may want to do it this way: What if you want to make an index page of all your video posts but you want to show the video thumbnail directly from YouTube instead of the video itself? To do this you need the video ID and you also need a bit of PHP magic.

The code below goes inside the loop on an index page and produces the video thumbnail wrapped in a link to the post:


<?php 
// Calls up the YouTube video thumbnail or, if no URL is provided, the featured image from WordPress

// Add a container and a link around the video
echo '<div class="tinyVideoThumb">';
echo '<a href="' . get_permalink() . '" title="Go to ' . the_title() . '" rel="bookmark">';

if ( $video_url ) { // if there is a video URL
	
	// Get the video URL from custom field
	$videoID = get_post_meta($post->ID, 'video_url', true); 
	// Query YouTube for video meta data
	$thumb_query_url = 'http://gdata.youtube.com/feeds/api/videos/' . $videoID . '?v=2&alt=jsonc';
	// Decode the json data from YouTube and put it in a readable format
	$json = json_decode(file_get_contents( $thumb_query_url ));
	// Echo out the thumbnail, give it height and weight and set the alternate description to post title
	echo '<img src="' . $json->data->thumbnail->sqDefault . '" width="60" height="45" alt="' . the_title() . '">';
	echo '</a>';
	echo '</div>';				
						
} else { // else use the standard featured image
											
	the_post_thumbnail('tinyThumb', array('alt' => $postTitle, 'title' => $postTitle)); 
												
} 
?>

The above of course only works for YouTube videos, and only if they are entered with the full URL and none of the other junk that often comes along with YouTube video URLs. You could make a strict rule to only plug in the actual YouTube video ID in the field. If so you could omit the substr() function.

Categories
Code Snippets HTML Tutorials WordPress

Using the time tag in WordPress and when parsing RSS feeds

The <time> tag is a little used but very effective little HTML element that allows you to embed additional information to dates and times in your content. The idea is that in addition to the actual text that shows the visitor the time, you can provide the browser, search engines and other computers with actual time information they can understand. Very cool.

For a recent project I had to parse time tags both from WordPress and from an RSS feed. After some mucking about I found what I think is the optimal solution, so to save you some time I’ve put it all together for you.

Date stamp for WordPress using the <time> tag

WordPress can output the publishing date and time in pretty much any configuration you want. For the time tag to work you need the datetime variable to show the time in a specific format that looks like this:

2012-01-30T18:55:21+08:00

That’s year, month, date, time (international) and an optional time zone reference. I’m in Vancouver, Canada so that’s GMT+8 hours.

Using the get_the_date() function in WordPress you can get this time format and any other. In this case I wanted the format “Jan. 30, 2012”.

The end result:


<time class="entry-date" datetime="<?php echo get_the_date( 'c' ); ?>" pubdate><?php echo get_the_date('M. j, Y'); ?></time>

Date stamp when parsing RSS feeds using the <time> tag

For the project I also needed to parse an RSS feed and show the details of each item in an index page. RSS feeds output the date in a standardized format, but it is rather unsightly:

2012-01-30T23:00:00+00:00

I needed to get this parsed to match the example above. To do so I used a handy PHP function provided by Handy PHP called Reformat Date. This function uses the strtotime() PHP function to reformat dates into anything you want simply and easily.

First I added the function itself to the functions.php file in my theme like this (notice I append the name of the theme at the front of the function name to avoid any future clashes should WordPress decide to bake this feature in):


// Reformat date for RSS feed
function theme_reformat_date($date, $format){
// Function written by Marcus L. Griswold (vujsa)
// Can be found at http://www.handyphp.com
// Do not remove this header!

    $output = date($format, strtotime($date));
    return $output;
}

Second I grabbed the RSS feed using WordPress’ native RSS import function (I’ll write about that in a separate post but it’s pretty straight forward) and then I parsed the data.

Note: In an RSS feed the time is contained in each item under the handle pubdate so to get the raw time I use $item[‘pubdate’].


Note that the date has to be reformatted twice, once for machine readable output (‘c’) and once for the human readable output (‘M. j, Y’).

Categories
Tutorials WordPress

How to remove WP Geo plugin from specific pages

I ran a cross a rather interesting situation this week while working on the Vi Er Der Du Er site. The site uses the WP Geo plugin extensively on both pages, and posts, and custom post types but I needed to deactivate it for one particular page because I was embedding a different custom Google Map. Not surprisingly the scripts calling my custom map were conflicting with the scripts calling WP Geo and as a result the map on the page in question didn’t work.

At first I thought it was a matter of removing the actions that called the plugin itself. I’ve done this in the past and it works for some plugins. I also found a code snippet here that seemed to show it working. That unfortunately was not the case. So I had to keep digging. Then I found this excellent article How to disable scripts and styles by Justin Tadlock that explained it all: I needed to de-register the scripts, not simply remove the function.

After digging through the plugin code I found the script calls and ended up with this code snippet in my functions.php file:


<?php 

// remove WP Geo JS/CSS from the nybank page
add_action( 'wp_print_scripts', 'vierderduer_deregister_javascript', 100 );

function vierderduer_deregister_javascript() {

	if (is_page_template('page-nybank.php')) {

		wp_deregister_script( 'googe_jsapi' );
		wp_deregister_script( 'jquery' );
		wp_deregister_script( 'googlemaps' );
		wp_deregister_script( 'wpgeo' );
		wp_deregister_script( 'wpgeotooltip' );
		wp_deregister_script( 'wpgeo-admin-post' );

	}
}

?>

As you can see I made the function conditional so it only kicks in when a specific page template is used. You can swap out that condition for any other condition for the same result. Bottom line is it works and now WP Geo works on every page, post and post type except pages that use the page-nybank.php template file.

Categories
Lynda.com Tutorials

WordPress 3: Building Child Themes – new course at Lynda.com

LEGOs used as illustration for the WordPress 3: Building Child Themes course on lynda.comChild Themes are by far the easiest way of creating a new look and introduce new functionality to a WordPress powered site. By creating a WordPress child theme you get all the benefits of the parent theme while gaining the ability to create custom styles, custom layouts and custom functions just for you.

In May 2011 I went to Ventura, California to record my new course WordPress 3: Building Child Themes for lynda.com. The course takes you through the entire child theme building process – from picking a parent theme to creating new styles and layouts, customizing and adding menus, sidebars and footers, integrating the Featured Image (post thumbnail) functionality throughout the theme and even adding custom jQuery functions. Here’s a sneak preview:

The course and its materials were created to make it easy for everyone to get started customizing WordPress sites and comes as a direct extension to my WordPress 3 Essential Training course (also available from lynda.com). Although the course uses the Twenty Ten theme as the parent theme all the code samples and techniques demonstrated can be used to build child themes from any other theme.

I’m very excited to announce this new course and I hope you like it too. If you’re not already a member of lynda.com you can get a 7 day trial membership by visiting lynda.com/trial/rand-hendriksen.

Go forth and start child theming!

 

Categories
Tutorials WordPress

Custom Page Templates in TwentyTen


With the release of WordPress 3.1 came a new version of the stock TwentyTen theme with some subtle changes, most importantly the move of all the loop elements in the templates (the code that runs through the database and gathers info like title, date, author, categories, content, images etc) into their own files. In the first release of TwentyTen this was restricted to just the single post view (loop in loop-single.php) but now it also extends to among other files the page tempalte (loop-page.php).

The problem arises when you want to create custom page templates. Previously all you needed to do was copy the page.php file and make the changes you wanted in the loop. But with the new system copying the page.php file alone won’t let you make any changes to the loop, just the overall structure (header, sidebar, footer etc). To make changes to the loop you have to either copy the loop code out of loop-page.php and into your custom page template or use a conditional statement along with the is_page_template() function in the loop-page.php file to detect that a custom page template is being used and then make the changes. The video above demonstrates both approaches.

Categories
Tutorials WordPress

Add a Twitter-like “Published X Days Ago” timestamp to your WordPress posts

For the last couple of weeks I’ve been working on a massive WordPress project that has required a lot of interesting and unusual components that step well outsie of what is normally expected from WordPress and its plugins. Once the project is live I’ll write a longer article about all these components, but in the meantime I’m going to share some of the functions because I think you might find them useful.

“Published X Days Ago”

The first function I’ll feature is a small script that spits out a text telling the viewer how long ago a post was posted. I actually needed this script for a countdown so mine is a fair bit longer, but it can be used to create a Twitter-like time stamp just as easily.

To achieve this we’ll be using two functions, date() and get_the_time(). The former is a bona fide PHP function that grabs the current local time from the server while the latter is a WordPress function that grabs the time of publishing for the post.

It doesn’t take a genius to figure out how we’re going to use these two: Taking the current time and subtracting the published time will give you the time difference, in other words how long ago the post was published. The challenge is that you need to get the right time formats to actually output a rational result.

Getting the right kind of time

You’d think that if you want to count how many days ago a post was posted you could just grab the dates and count backwards. But that’s actually pretty hard because it relies on the counting mechanism knowing what day of the month it is and how many days each month has etc etc. A better solution is to grab a unified time value that doesn’t change in the same arbitrary way. Luckily programmers found this problem and its solution a long long time ago. It is called the the Unix Epoch and is the time, in seconds, since January 1, 1970 00:00:00 GMT). To get this value for each of our functions we simply add in the format string “U” like this:


date('U'); // outputs the current date and time in Unix Epoch terms
get_the_time('U'); // outputs the publishing date and time in Unix Epoch terms

Making the time make sense

Problem is this produces a weird long number like 6250458. This is the number of seconds since the article was published. We want the number of days, so we need to do some math.

If you have seconds and you want to make days you first have to divide them by 60 to make minutes, then divide it by 60 again to make hours and then finally divide it by 24 to make days. For 86399 out of every 86400 seconds of the day this will produce an integer (number with a comma) but we want whole numbers. So we utilize an extra function called round() that rounds out the number for us.

Putting it together

With that we have all the components we need to get the number of days since published. In PHP form the function looks like this:


<?php 
	$days = round((date('U') - get_the_time('U')) / (60*60*24)); 
	echo "Published " . $days . " days ago";
?>

This will output the number of days since published sandwhiched between the words “Published” and “days ago”. But what about the first day, when the number is zero, or the second day when the number is one? “Published 0 days ago” and “Publised 1 days ago” looks kind of sloppy, no? Well, it’s easy to fix with some conditional statements:


<?php 
	$days = round((date('U') - get_the_time('U')) / (60*60*24));
	if ($days==0) {
		echo "Published today"; 
	}
	elseif ($days==1) {
		echo "Published yesterday"; 
	}
	else {
		echo "Published" . $days . " days ago";
	} 
?>

All these conditional statements do is ask “if the number of days is 0, say “Published today”, if the nuber is 1, say “Published yesterda” and for all other cases say “Published X days ago”.

Copy this piece of code anywhere in your theme files within the WordPress Loop and it’ll spit out a published x days ago timestamp on your posts.

Easy as Pi.