Category: WordPress

A Personal Note as WordPress Celebrates 10 Years

WordPress is ten years old. It’s been wildly successful and that’s putting it mildly. To celebrate, MarketPress released an interesting infographic. I think the most amazing figure mentioned here is the amount of code that has gone into WordPress. It’s over 200 thousand lines, which they estimate to equate to about 52 years worth of programming. Fifty-two years. Not only is that a testament to the sheer power of open source collaboration, it underlines just how valuable WordPress is as a tool. When you install a free copy of WordPress, you are using software worth millions and millions. I think that’s awesome.

In ten years, WordPress has come a long way. I think one of the most exciting things for me was the increased support for custom post types and taxonomies (strangely omitted from the infographic). I remember when I started my first blog in 2007 on WP 2.1 and was trying to integrate it with a forum software. That’s a 1 minute job these days and I spent weeks trying to figure that one out at the time. It was fun though and getting my hands dirty with code kindled my passion for WordPress and website development. It’s like building with Lego and I love it. With my 6 and a half years’ worth of experience, WordPress still feels fresh to me and I still love learning new things about it.

I expect great things from WordPress going forward, I can only see it growing forward. Future looks bright.

Differences between using get_post() and WP_Query()

WordPress gives developers a number of ways to grab post content from the database. A lot has been written about the differences between using query_posts(), get_posts() and WP_Query, with WP_query being generally favored in most situations. But there is another method called get_post() which can fetch content for a single post, page or custom post object. If you want to output content from a single post object, you could technically use any 4 of these methods.

The question is, where does get_post() fit in with these other methods and what is the best way fetch the content of a single content object in the posts table?

The answer depends on your use case. Let’s say you want to show an excerpt of a specific post in your sidebar, what are the considerations? The get_post() function seems tailor made from grabbing a singular content object, which would make it a pretty obvious choice, but the other methods could also be used. When do you use what?

Ruling out get_posts() and query_posts()

If you’re just polling one object, be it a post, custom post, attachment or page and you know the post id, slug or post title of the object, we can easily rule out query_posts() as it is not a good fit. It wasn’t designed for this purpose and really is about showing multiple posts in a loop.

The difference between get_posts() and get_post() is larger than it seems. The main under-the-hood difference here is that get_posts actually uses WP_query and get_post() does not. So while we can use get_posts just fine for picking a single object, it’s not going to be as efficient as get_post() or as powerful as a custom WP_query. For that reason, let’s talk about the differences between those two.

WP_query vs get_post()

Let’s first look at a simple code example that will give you the same exact output using either method. Following along the lines of our use case example, we are grabbing a post with id 5 and displaying a title and an excerpt to that post.

<?php
// suppose we want to display an excerpt from a post with a post id of 5

// with WP_query

$args = array(
    'p' => 5
);
$custom_query = new WP_query( $args );

if( $custom_query->have_posts() ) {
   $custom_query->the_post();
   the_title();
   the_excerpt();
   wp_reset_postdata();
}
wp_reset_query();

// With get_post()

$get_content = get_post( 5 );
setup_postdata( $get_content );
the_title();
the_excerpt();
wp_reset_postdata();

One of the first things that you might notice is that the WP_Query example uses a loop and the get_post() example does not. The second thing you might notice is that get_post has a simpler way of specifying the post id. Let’s dig deeper into these two visually apparent differences.

On selecting the post object: get_post() vs WP_query

With WP_query you have to take into consideration what post type the object is that you are fetching. It is not enough to supply the ID or name of the post object. For example if it’s a post, you pass a parameter ‘p’ with the value of the post id, or ‘name’ with the name of the post. If it’s a page, you have to supply the parameter ‘pageid’ or ‘pagename’ respectively*. If it’s a custom post type, you have to pass along the post type of the object as a parameter, along with the parameters ‘p’ or ‘name’. With get_post() on the other hand, it’s suffices to supply the ID, name or slug of the post object: it doesn’t matter what post type the object is.

All in all, get_post is simpler that way. If you are coding functionality that lets a user supply any kind of post type, you have add some logic to build your query arguments correctly for WP_query.

Loop vs Non-Loop

With the WP_query example, we are using a loop, with get_post we are not. Why would it matter? Loops are a fundamental part of how typical WordPress themes render content, it’s handy to know a little more about their inner workings. Using a loop comes with some perks, such as the ability to use conditional tags that relate to the post being shown. Various functions provided by WordPress, the theme or a plugin might only work inside a loop and this is something to keep in mind.

If all you want to do is show some basic content from a post object, you might not need the loop and it will be simpler and more efficient to not use a loop.

Under the hood

There is a big difference in the way get_post() and WP_Query fetch content. When using WP_Query, we are running 4 queries to the database by default. One query fetches the data from the posts table, another fetches the custom fields from the meta table, a third query grabs author data from the user table and a fourth query gets data on comments relating to the post object from the comments table. While it is fairly efficient, you may not need all of the extra data and so those calls to the database might be a bit of an unnecessary waste.

With get_post() on the other hand, only one database query is made. You’ll note in the example above though that I’m using the setup_postdata() function (which enables the use of template tags such as the_title() ), which actually makes a database query of its own to grab info about the author. If you want to display author info, custom fields and/or comment data, you might favour WP_Query as it grabs this info for you in one swoop.

If you want to limit database queries to an absolute minimum and you’re only showing content contained in the posts table, there’s another way of writing the above get_post() implementation.

// accessing and rendering raw post data with get_post
$get_content = get_post( 5 );
echo apply_filters( 'the_title', $get_content->post_title ); 
if( $get_content->post_excerpt ) {
   echo apply_filters( 'the_excerpt', $get_content->post_excerpt );
} else {
   echo apply_filters( 'the_excerpt', $get_content->post_content );
}

This example should produce the same result as the previous examples, but it gives you a bit more control over what is going on.

Decision time

So when it comes to picking get_post() or WP_Query for displaying data from a specific post object, here’s a summary of considerations to keep in mind:

  • What data do you need to display? If you want to show comment counts, author data and custom fields, might as well use WP_Query. If you just need the data from the posts table, go with get_post(). You can save database queries with a get_post implementation.
  • Do you need a loop? If you need loop-specific functionality (conditional tags or certain plugin functionality that only works inside a loop), go with WP_Query. If you specifically want to avoid conditional tags working in relation to the post being grabbed, you should go with get_post().
  • UI consideration: Need to let users pick multiple kinds of post type in your user interface? It will be easier to code with get_post as passing parameters with WP_query is a bit more involved (you need to pass the post type as an argument). You’ll get slightly leaner, more elegant code with get_post().

Lastly – especially if you are going with WP_Query – and are concerned about performance you could consider a caching method to improve performance. This is pretty useful if, say, you want to show a certain post snippet in the sidebar on every page.

* With WP_Query you can also use the ‘p’ post id parameter to query a page providing you also set the ‘post_type’ parameter to page.

DesktopServer Review

If you do any kind of development on WordPress, you probably are using localhost to develop on your local machine. It’s noticeably faster than working with a live server, especially while working in the Admin screens of WordPress. For this reason, many people will be familiar with the oh so fun process of setting up local sites and moving sites to live servers. Well in this post I’m going to cover a product that makes local development a much more productive and efficient experience.

The process of setting up a local site for development and moving changes up to an online server is a tedious, painful, needlessly time consuming process. Just setting up a fresh WordPress site on your amp stack is annoying as it involves having to create a database manually, making changes to some configuration files, updating the hosts file and then running the WordPress installation. I was pleased to find a tool that automates all these tasks and it happened to be a tool that is perfect for WordPress development.

Enter DesktopServer

DesktopServer is a brilliant piece of software that is essentially a regular server stack that you will be used to if you have used WAMP, LAMP, XAMPP, MAMP or Uniserver. It actually is packaged with XAMPP Lite, the lite version of XAMPP. The real magic however comes from the logic they’ve included to work with XAMPP Lite. It comes with some powerful automation tools that make it very easy to create, import and export sites and do development on WordPress sites using popular tools.

Turning 10 minutes into less than a 1 minute

Setting up a locally hosted WordPress site in a snapSetting up a locally hosted WordPress site in a snapNow manually setting up a local site on your own machine isn’t terribly difficult once you know all the different steps, but it is a pain. If you’re used to something like Cpanel, which makes installing WordPress really easy, it feels even more annoying to have to manually create a database, configure a virtual host, adjust your hosts file and run through the installer. It can take a good 5-10 minutes if you know exactly what you are doing.

With DesktopServer you can painlessly create a new local site through a simple UI in a matter of seconds. It does all the configuration for you. That in itself is worth jumping for joy, but that’s only a start.

Quickly installing a preconfigured WordPress setup

DesktopServer uses a blueprint model for creating WordPress installations. In that blueprint you can preconfigure WordPress to install with certain plugins and themes. You can even auto-import settings. This is just awesome stuff and saves so much time having to install sets of plugins manually.

Quick Deploy a local site to a live server

A recently improved feature in DesktopServer Premium called quick deploy lets you upload a WordPress site complete with files and database directly to any server that supports Filesystem Direct (supported by many hosts). The resulting magic is facilitated through a plugin that you install on the destination site (you need to have WordPress pre-installed, a fresh install is fine). This is a really nice feature that cuts out a bunch of steps you would otherwise have to perform.

Migrating or moving a site is not a fun task and can be quite challenging. This built in solution let’s you do things at the push of a button while taking advantage of DesktopServer’s automatic scrubbing, so you don’t need to worry about fixing URLs after moving a site online.
Mobile Development options

Another great feature provided by DesktopServer solves the tricky issue of testing local sites on mobile devices. Through Lan sharing (which makes use of the computers IP address on the network), you can make a local site accessible on your mobile phones and tablets. The only caveat here seems to be that you can only share a single site at a time. While I haven’t given it a test turn yet, it also looks like you can make a site available to the web so that people outside your network can view your development site. This feature also uses an IP address which viewers will have to know to access the site. (Side note: I’ve previously covered some other ways to share local sites)

My concerns, squashed

I had a number of concerns prior to trying DesktopServer Premium and I figured I’d write it up in Q&A form.

I want to run a local site that has an extension other than .dev, is that possible?

No problem as it turns out. As you’re really running XAMPP lite, you can manage your own virtual host mappings as you see fit along side any .dev site DesktopServer creates. Setting up non .dev sites can be done manually like you would normally on any AMP setup. I use pagekite to host a private site straight from my computer and I was able to do so without any conflicts. Perfect! The only downer is that DesktopServer only manages and installs .dev sites through its GUI as far as I can tell.

Will it mess with my custom hosts file?

Got a hosts file that you’ve customized with a certain configuration? You won’t have to worry about DesktopServer overwriting anything. It’s smart enough to manage it’s own additions within the file without touching any pre-existing mappings in the file.

Does it automatically adjust hardcoded site urls when migrating?

One of the beautiful things about DesktopServer is that you don’t have to run any kind of find and replace scripts  when you move a site to a different domain. It will do it for you and it even will search your php, css and js files so you’re covered all around.

Minor Niggles

My first month of using DesktopServer was largely positive, I did note a few minor things I’d love to see work their way into an upcoming release.

Live Deploy Progress Indicator

This is what happened when my hosting server failed during quick deploy. My Starcraft honed APM came in good hand closing all these alert boxes.
This is what happened when my hosting server failed during quick deploy. My Starcraft honed APM came in good hand closing all these alert boxes.

The live deploy feature is missing an informative progress indicator. As deploying can take a long time and it is co-dependent on whatever hosting you are using, it would be great to know what it is actually doing or where it is slowing down. Deploying to a live site can be unnerving experience. In my tests I did notice things do take quite long to transfer, but this is very much dependent on the hosting provider and the server’s upload speeds. If you happen to run into a problem during the transfer process, you might have a bit of a problem on your hands.

During one of my tests my (shared) hosting happened to crash, which left me with an incomplete install and a white screen. Of course, no matter what method you use, any migration process won’t fare well under those conditions, but it’s useful to have some kind of indication in case the connection does go wrong. If you’re uploading up a large site, it’s even more important.

One PHP version

DesktopServer ships with the most common PHP/Mysql configuration seen in the wild. If you want to test different versions of PHP, you’re out of luck as DesktopServer doesn’t let you do this out of the box. That would be a fantastic feature to add in the future.

Unmentioned goodness

DesktopServer plays very nicely with a host of other common developers tools, such as Dreamweaver, Xdebug, Coda 2, PHP Storm and popular backup utilities such as Backup Buddy, Duplicator and Infinite WP. So far I have only tested Duplicator, a fantastic free backup plugin and that worked very smoothly indeed.

It’s also worth noting that DesktopServer is not just for WordPress stuff. You can use DesktopServer to create non-WordPress sites for all your other site development and testing purposes

Bottom Line

If you are building WordPress themes/plugins or developing entire sites or applications on WordPress, this software should be part of your tool kit. It’s amazing to me how long this product has been around and I hadn’t really discovered it until recently. More people should be spreading the word.

* Note *
This review was written after using DesktopServer version 3.5 for about a month (I managed to get a review copy). I wasn’t paid to do this review and I do not have any financial ties to Virtuosoft, the company behind of DesktopServer.

Backbone.js And WordPress Resources

Backbone is a very popular lightweight javascript framework which greatly simplifies and structures complex javascript in websites and especially (web) applications. A lot of high performance websites now rely on backbone.js and underscore.js (a dependency of Backbone), from single page web apps to websites that have a lot of client side functionality. WordPress is becoming increasingly javascript-centric so it’s only natural that WordPress developers are starting to look at backbone to make developing rich javascript functionality in their WordPress projects easier. Since 3.5 WordPress ships with backbone and underscore so the presence of backbone in WordPress projects is bound to grow.

At the time of writing backbone and WordPress are a pretty new combination and there aren’t a whole lot of resources to be had yet. Backbone takes some getting used to, especially if you only have only used javascript and jquery for lightweight functionality in projects. As I’m only digging into backbone myself, I decided to start aggregate the best resources so I can speed up my own learning. I hope you find it useful too.

General Backbone Resources

Connected to the Backbone (Video Tutorial by Jeffrey Way at Tutsplus)
(Full tutorial requires Tutsplus premium at 18$/month)

Anatomy of Backbone.js – course on Codeschool
(codeschool offers its courses for a subscription of 25$/month)

Learn Backbone.js Completely (free)
Extensive resource, which takes about 30 hours to run through fully

Developing Backbone.js Applications
This is Addy Osmani’s book (available in print too)

A Curated List of Backbone.js resources
Provided by Mike Schinkel

Hello Backbone.js
An easy introductionary step by step tutorial to backbone.js (v 1.1.0) by Artur Adib

Building Backbone Plugins
A go-to book for intermediary and advanced developers using Backbone.js.

Full Stack Web Development with Backbone.js
A freshly published book on Backbone.js which, unlike some of the other books, covers the newer version of Backbone (1.1+).

WordPress & Backbone Tutorials

Tutorials by Shane Osbourne on WP Tuts

Using Backbone within the Admin (frontend)

Using Backbone within the Admin (backend)

Alex Bachuck shares a concise backbone.js tutorial:

Displaying recent posts with backbone.js in WordPress

Theme Foundry shares how they implemented Backbone.js in their Collections theme:

Backbone.js and Collections: Structure

Backbone.js and Collections: Routers

Backbone.js and Collections: Plugin compatibility

Rakhitha Nimesh Ratnayake wrote a book that has a chapter on Backbone.js:

WordPress Web Application Development

Alan Greenblatt of Adobe fame published a 3 part post series about Web apps involving backbone.js and also shared a webcast about this too:

Modern Web App Design with WordPress

Building a REST interface with WordPress

Building Data-Driven Web Applications with WordPress

Video (1hr 4min): Building Data Driven Single Page Web Applications with WordPress

Write a backbone.js powered shortcode

How to make a TinyMCE view in WordPress

Video (1hr 53min) WordPress Theming with Backbone.js with Zack Tollman

Study these examples in the wild

PostListr – an example of what you can do with backbone.js and WP api’s by K.Adam White

The WordPress Media Uploader utilizes backbone since version 3.5

The notifcations system on WordPress.com

WP Posts to Posts plugin by Scribu

WP Ultimate Search, a backbone.js powered plugin

WisP: a Backbone.js client for the Thermal WordPress Api

Current Comments: Example plugin for using Backbone.js with WordPress

Collections – A Backbone Powered theme by Theme Foundry

o2, a WordPress app/theme/plugin evolving out of the p2 theme
(interesting details: slides and presentation about o2 by Lebens)

Use Case: A Project Management System using WordPress & Backbone
(not a lot of technical/code details)

Editr – the first themeforest theme using backbone.js? (link to demo page via affiliate link or normal link )

Backboned v2 is a backbone.js powered WP theme available on github created by the German front end dev Emanuel Kluge

EngineThemes have developed 3 commercial WordPress apps/themes called JobEngine, ForumEngine and ClassifiedsEngine that leverage backbone.js

Talks about WordPress and Backbone.js

Building Apps with Backbone.js and WordPress (WordCamp Chicago 28-30 June 2013)

From Adam White’s presentation

Developer: WordPress Loves Backbone JS (Portland WordPress meetup on 10 June 2013)

Evolving your JavaScript with BackBone.js(slides) . (also by Adam White from WordCamp Providence 2013), video available now on WordPress.tv.

WP Sessions: WordPress and Backbone.js is a (purchasable) webcast lead by K. Adam White, Carl Danley and Zack Tollman that aired 25 January 2014.

WordPress Applicaties met Backbone.js (dutch) [slides (nl)]There was a session on backbone.js apps in a dutch WordCamp in May 2014, given in dutch.

WordPress and BackBone – The Dawn of Web Apps. An introductionary type talk giving a window into the possibilities of using backbone and WP for web apps.

Tools for Backbone.js powered WordPress projects

A starting point for single page apps on WordPress using backbone and the json api plugin: WordPressSinglePage

Backbone Debugger – a chrome extension that let’s you see your views, models, collections and routers in realtime using Chrome Dev tools.

JSON api for WordPress – a plugin providing a full JSON Api for WordPress that will eventually merge with WordPress core.

WP-JS-Hooks – A very useful events manager similar to WordPress’ internal hooks and filters on the php side of things. May land in core!

AppPresser – Build iOS/Android Apps using WordPress. This new set of tools let’s you easily leverage PhoneGap’s power and turns any WordPress installation into a application that can tap into native mobile features such as a geolocation, microphone and camera.

_s_backbone – Backbone.js meets underscores, a starter theme that takes advantage of the JSON rest api (core included WP 4.0+).

Other learning

It’s worth going through some other courses before digging into Backbone, especially if your javascript skills are light. Underscore.js is worth learning in depth before going head first into backbone. Getting up to scratch with general javascript and jquery is highly recommended too.

Updates

I’ll be updating this page as more WordPress specific resources become available. If you sign up through this link I’ll send an email when the page is updated.

UPDATES 27 March 2013:

Over at WordPress.org a thread was started about creating new documentation for using Backbone.js and Underscore.js in WordPress projects. Official documentation should thus be on its way, that is great news!

UPDATES 17 April 2013:

Added WP Ultimate Search to the plugin examples and WordPressSinglePage which is a starting point for single page apps built on WordPress.

UPDATES 6 June 2013:

Added a few talks: There’s an upcoming WordCamp presentation at WordCamp Chicago about building Backbone.js apps with WordPress and a Portland meetup presentation with a few Automattic guys.
Added two plugins; an example backbone.js WordPress plugin and a client for the Thermal Api (a cool json api for WordPress)

UPDATES 3 July:

Added Adam White’s presentation slides and github example from WordCamp Chicago

UPDATES 15 July:

Added Mike Schinkel’s curated list of backbone.js resources
Added Backbone Debugger Chrome Extension

UPDATES 6 August:

Added Theme Foundry’s Backbone powered WordPress Theme called Collections. Looks really good btw.

UPDATES 13 September:

Added Theme Foundry backbone.js blog series
Added JSON REST api plugin by Ryan McCue
Added link to the forthcoming o2 theme (backbone.js powered evolution of the p2 theme)

UDPATES 22 November

Added new video presentation links to Adam White’s backbone presentations
Added Postlistr repo link
Added link to Editr, the first commercial theme on themeforest that is using backbone.js
Added a link to wp-js-hooks, a lightweight, js based filter/hooks library similar to the php based on in WP.
Added a use case write up about a project management system using backbone.js and WordPress

UPDATES 22 December

Added new tutorials from Theme Foundry with interesting details about their backbone.js powered theme
Added a link to AppPresser, a new tool for creating mobile Apps using WordPress.
Added a link to a book called ‘WordPress Web Application Development’

UPDATES 17 Januari 2014

Added tutorials by Alan Greenblatt
Added link to a WordPress session covering Backbone.js and WordPressAdded link to EngineThemes’s backbone.js powered app themes
Added link to Backboned v2, a free backbone.js oriented theme on github

UPDATES 18 April 2014

Added example plugin showing how to create a backbone.js powered shortcode for TinyMCE
Added hello backbone.js which is a simple tutorial for backbone that uses backbone 1.1.0 (A lot of other tutorials and links cover older versions of backbone)
Added link to an upcoming WordCamp session (takes place in May in the Netherlands)

UPDATES 19 June 2014

Added a great session (video) by Zack Tollman called WordPress Themeing with Backbone.js
Added an introductionary talk about WordPres, Backbone and Web Apps by Jesper Bylund
Added slides to a dutch talk by Luc Princen, called “WordPress Applicaties”

UPDATES 11 July 2014

Added two new books to the general backbone resources section

UPDATES 19 August 2014

Added _s_backbone, a starter theme that utilizes backbone.js

Excerpt Confusion: Making Sense Of WordPress Excerpt Display

WordPress offers a number of ways to show an introduction to a post that then links to the full post. They are commonly used on the home page of a site, or in category archive pages when you don’t want to list the full post content. Because there are different ways of accomplishing this, it can be a bit confusing as to how each method works.

To understand how WordPress deals with these post introductions, you have to know the distinction between manual excerpts, auto-generated excerpts, and posts that utilize the

<!--more-->

tag.

The More Tag

The more tag let’s you define the part of the content that forms an introduction to the full post. To use it, you can either type in

<!--more-->

(while in HTML mode) or use the more button inside the post editor. You have to place this tag in the right position in your content (effectively splitting the content). Now the interesting part is how the display is done. The more tag is only respected if the page it’s being displayed isn’t a singular post, page or custom post page. This makes sense in so far that if you are on the actual page of your post, you would want to show the full post. That’s great.

But what if you are on a different singular page and you want to display the teaser of a different post with a link to the full post? If your theme is using

the_content()

to display this content it will show a full post regardless. That’s something to keep in mind.

Another interesting thing about using the more tag and having it displayed with the_content() is that you can specify a ‘more link text’.

the_content( 'continue reading...' );

This function also gives you the option to hide the introduction of the post when it is displayed on the actual post page.

the_content( 'continue reading...', true ); // default is false

That way you can write a custom teaser that will only show on your home page, but the teaser text isn’t repeated on the full post page.

If you don’t hide the teaser, the read more link will send the reader straight through to the section after the introduction. In the actual markup of the actual post page, a span element is inserted that has an id that is used to target that section directly from the link. Some people do choose to remove this default behavior however.

Automatic Excerpts

So apart from

the_content()

, another function exists for displaying a post excerpt, which is appropriately called

the_excerpt()

.You could use the above mentioned technique for creating a post excerpt for your home page, but the_excerpt() is another way to show a post introduction. It’s conceptually different compared to using the more tag. When the_excerpt() is used, it will look to see if a manual excerpt has been set and if there is none, it generates an excerpt automatically. The automatic excerpt generator will grab the first x amount of words from the post content and render that content with plain formatting (ignoring images, headings and stylings that were applied to the post text). That’s a big difference compared to using the_content() with a more tag defined in the post, which will respect the original markup of the post.

You can customize the appearance of the rendering of the_excerpt by adding your own ‘read more’ link or altering the amount of words it uses to generate the excerpt. But really, the usefulness of automatically generated excerpts pales in comparison to using the more tag or using manual excerpts.

Manual Excerpts

A lot of WordPress users don’t even know it exists, but you can set manual excerpts from the post editing screen. It may appear hidden if your screen settings are set to hide the excerpt meta box. That is easily remedied though. While manual excerpts are (by default) only activated for normal posts, you can add support for excerpts to any other post type (such as pages) with a line of code.

Manual excerpts give you full control over the excerpt and so they give you a means to define what is shown when the theme is using the_excerpt() to display content. Manual excerpts are also sometimes used for supplying summaries, or for descriptions of the page that appear in the head section of the page (not visible to users, but used by search engines and apps). Those are entirely different functions compared to the aim of providing an enticing introduction for a post. Because the manual excerpt also runs through the_excerpt, the output format is pure text (no images, special styles etc).

Making Sense Of Excerpts

The three built-in ways of displaying excerpts each have their pros and cons. It’s easy to get a little confused when you are trying to make the excerpts on your site display as you want them to. Context matters, you really have to understand what you are trying to achieve with the excerpt so you can use the most appropriate method.

The more tag approach is best for showing a teaser, a few lines that make visitors click through to the full page. You then have the power to hide the teaser from the full page, making the teaser purely function as a means to invite people to read the page. The downside to the more tag is that it requires an author to remember to manually insert the tag. If you don’t supply a more tag, the full post may be rendered and you also have the limitation of not being able to show just the teaser on pages that have a dedicated permalink.

Automatic excerpts are a crude means to provide introductions, because they are pure text and consist of a fixed amount of words with no regard for sentences and special formatting. They also make for lousy summaries unless the first sentences of a post are formulated in a favorable way.

Manual excerpts give a user a lot of flexibility. You can utilize them as summaries of a post and they don’t have to repeat a post’s content verbatim. By default, the formatting is bare bones, just like the automatically generated excerpt is. The downside to these manual excerpts is that user’s often don’t understand the benefits and it is an extra thing to remember while writing a post.

If you are setting manual excerpts as well as using the more tag to create teasers, know that

the_excerpt()

will show the manual excerpt and

the_content()

will show the teaser as specified by the more tag placement.

Your Own Excerpt Display Functions

Given the limitations of each of the discussed methods, you may find that you need something custom. I’ve previously written about how to make an rss feed show teasers set by the more tag placement here. You may want show an excerpt with certain formatting preserved from the original post. You might want to set a character limit for the excerpt for tighter control. You can even write a function that automatically inserts a more tag if none is specified to have auto-generated teasers.

CSS3 PIE 2 and WordPress integration

A new release of CSS3 Pie has been announced, PIE 2.0 Beta 1. It comes with lots of goodies such as a bit of background size support and rgba support in simple linear gradients and box-shadow rendering. For a more precise break down check out the release post, as not all of the newly supported features work in all contexts.

I had written a method for integrating version 1 of PIE into WordPress for plugin and theme authors but as the new version of PIE uses a different load method, I found it useful to post an updated method. The main difference with PIE 2.0 is that the htc file is very small now (<2kB) and it will conditionally load javascript files based on the version of IE. The advantages are that you can load these js files from any server (such as a CDN) and now that unnecessary code is left out, the download will be a lot smaller. Caching works a lot better out of the box as well.

The method I’ve suggested for PIE remains mostly the same except we now have to add in a custom load path so PIE.htc will load the javascript files from the right location. By default, PIE will look for the javascript files in the same folder PIE.htc is located. Because the implementation I’m detailing here doesn’t point straight to the PIE.htc file, the script won’t be able to find the javascript by itself. A custom path to the javascript files can be specified with a pie specific css rule called ‘-pie-load-path’. You could hardcode this rule in your stylesheet and be done with it, but it’s more flexible to do this dynamically with an inline style element.

note: It’s important to note that the implementation I’m detailing here is geared toward plugin and theme authors looking to package PIE with their distribution. If you’re just trying to get PIE working on your own sites it’s easier to move the PIE files to the root folder of the domain, in a folder right off the root or in the wp-content folder. You can just follow the normal instructions and forgo with having to set a custom load path and simply point directly to PIE.htc.

The benefits to the method I’m using are the same as before:

  • avoid having to hardcode the path to PIE.htc in your css
  • avoid having to mess with php in your stylesheets to insert the path to PIE.htc dynamically
  • avoid having to move PIE.htc to the domain root or elsewhere
  • avoid having to mess with relative urls when pointing to PIE, just use an easy to remember absolute url
  • a short url and easy to remember url for referring to the PIE file in your css

The Implementation

Normally, when inserting scripts and styles, you would want to hook into wp_enqueue_scripts and use a WordPress function such a wp_add_inline_style for inline style elements. In this case, we only want to have the browser read the style element if it’s Internet Explorer, so we want to wrap our style element in the familiar conditional code to target IE only. For that reason, I opted to go for a more straight forward approach and attach the function that prints this code straight in the head section through the wp_head hook. Another benefit to this is that we can place this code before other stylesheets are loaded. (I haven’t tested to see if this makes an actual difference in terms of how fast PIE applies its styling, but it makes sense on paper)

if( ! function_exists( 'css_pie' ) ) {
	function css_pie ( $vars ) {
		$vars[] = 'pie';
		return $vars;
	}
	add_filter( 'query_vars' , 'css_pie');
}

if( ! function_exists( 'load_pie' ) ) {
	function load_pie() {
		if ( get_query_var( 'pie' ) == "true" ) {
			header( 'Content-type: text/x-component' );
			header( 'Cache-Control: max-age=2592000' );
			readfile( get_stylesheet_directory() . '/inc/PIE/PIE.htc' );    
			// Stop WordPress from loading further
			exit;
		}
	}
	add_action( 'template_redirect', 'load_pie' );
}

if( ! function_exists( 'set_pie_path' ) ) {
	function set_pie_path(){
		$piepath = get_stylesheet_directory_uri() . '/inc/PIE/';
		?>
		<!--[if IE]>
		<style type="text/css">
		html { -pie-load-path:"<?php echo $piepath;?>";}                
		</style>
                <![endif]-->
		<?php    
	}
	add_action( 'wp_head', 'set_pie_path', 7 ); // just before stylesheets are printed
}

To adjust this code to your project, keep in mind where your PIE files can be found. In this example I created a folder called PIE in the includes folder of my theme directory. You’ll need a different url path if you’re including PIE from within a plugin. If you are loading PIE within your theme – which is probably going to be the case most of the time – you may want to set the paths to look for the parent theme instead of checking the child theme. In that case you can replace get_stylesheet_directory() and get_stylesheet_directory_uri() with get_template_directory() and get_template_directory_uri() respectively.

Applying PIE in your css is as easy as cake, just use:

behavior: url(?pie=true);

 

Woocommerce Tutorial: Better Product Listings For Imageless Products

Recently I’ve been working on my second WooCommerce project and I’ve found it quite a flexible solution so far. Woocommerce pretty much expects products to have images and the templates expect there to be a product image, so when you have a product without an image (because it’s a service and not a physical product for example), things don’t look that good. The following solution allows you to selectively modify the appearance of imageless product listings.

Notes: This is a good solution if you have a mix of products/services with and without images, or you have imageless products for which you may want to add product images later. You could also write your own template which overrides the default template. This solution however works well with the default template WooCommerce provides.

Because WooCommerce inserts an image element with a placeholder if no image was set for the product, the first thing we need to do is to prevent the image tag from showing up. We can do that by calling a custom funtion from the appropriate WooCommerce hook. For product listings that are shown in loops, the action hook that adds the function for the image display is called ‘woo_commerce_before_shop_loop_item’. There is another action hook called ‘woocommerce_before_shop_loop_item’ that runs before the image – which is wrapped in a link – is outputted. That’s the point where we want to run our modifications.

function before_imageless_product() {
	if( !has_post_thumbnail( get_the_id() ) ){
		remove_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
		echo '<div class="no-image">';
	}
}
add_action( 'woocommerce_before_shop_loop_item', 'before_imageless_product', 9 );

So what’s going on here? Well, we first check to see if the product in question has a thumbnail associated with it. If it has, we can maintain the normal templating, if it hasn’t we want to prevent an image element containing a placeholder from being inserted. We do that by calling remove_action on the ‘woocommerce_template_loop_product_thumbnail’ function. Because we want products with images to maintain their templating, we have to remember to add this function back. We do that by adding the call back right after, which we’ll get to next.

You’ll see we’re also inserting a div when there is no image present. Why? Well, the chances are you want to modify the layout in CSS so that the display looks nice in your theme. In that case we’ll need a way to style the product listings that have no image separately from those products that do have an image. Because there are no filters that are run on the CSS classes of the product listing that we can tap into easily, another way to do this is to simply wrap the product output in a div with its own class name. That way we can target the product listing in CSS without having to write a different template from scratch.

Now that we have implemented to code to remove the image from imageless product listings, we complete the modification by adding the image function back in and closing the div element we just inserted before the loop continues.

function after_imageless_product() {
	if( !has_post_thumbnail( get_the_id() ) ){
		add_action( 'woocommerce_before_shop_loop_item_title', 'woocommerce_template_loop_product_thumbnail', 10 );
		echo '</div>';
	}
}
add_action( 'woocommerce_after_shop_loop_item', 'after_imageless_product', 9 );

You should now see that default placeholder isn’t being outputted. You may want to tweak the css to make the imageless products look better. You can now easily do so by targeting those listings with the .no-image class.

* This example assumes a default-ish WooCommerce setup, if you have customized WooCommerce or are running a WooCommerce theme, there is a small possibility that the display is handled differently and the code might not work as intended.

Short Body Classes For Page Templates [WordPress]

Styling page templates with CSS is made even easier with the body_class() function which appends all kinds of handy classes to the body element. If you want to make the home page have a unique style, you could do things like:

.home {
   background-image: url(awesomebackgroundimage.jpg);
}

Targeting specific page templates is possible to, but the naming convention is very ugly. The default page template (page.php) would get a body class of page-template-default. A full width template with a filename like full-width-page.php would get a body class of page-template-full-width-php. Basically it adds page-template as a prefix and uss the full file name including the ‘php’ file extension. It’s not just ugly, but it also makes the css file grow if you are using the body class extensively, not to mention making the css harder to read. Oh, and it sucks typing out long class names.

Fortunately, it’s very easy to hook into the body_class function and add your own classes with a shorter naming convention. Here is a snippet that will display a body class of full-width when using full-width.php as the page template.

function my_short_page_template_body_classes( $classes ){
	if( is_page() ){
		$template = get_page_template_slug(); // returns an empty string if it's loading the default template (page.php)
		if( $template === '' ){
			$classes[] = 'default-page';
		} else {
			$classes[] = sanitize_html_class( str_replace( '.php', '', $template ) );
		}
	}
	return $classes;
}
add_filter( 'body_class', 'my_short_page_template_body_classes' );

This function doesn’t replace the longer naming convention WordPress uses by default (so those class names will still be injected too), it just adds a brief class name whenever a page template is being used.

Which would you rather type?

.full-width{
 width: 960px;
}

.page-template-full-width-php {
 width: 960px;
}

Easy choice.

How To Show A Sortable Last Modified Column In The Manage Posts Screen [WP]

So you want to quickly find posts that were recently edited? Here’s a quick WordPress guide to adding a sortable column to the post managing screen that displays the last modified date. This example can be easily modified to work with another type of field or a specific post type.

Step 1

So to start, let’s register the column we want to have appear. We’ll have a function to add our column name to the columns array. A filter hook will call this function.

function add_last_modified_column($columns) {
    return array_merge( $columns,
              array("last_modified" => __("Last Modified")) );
}
add_filter("manage_posts_columns" , "add_last_modified_column");

Step 2

Let’s create a function that will output our column’s data and hook it into the posts column. Depending on what kind of content screen (pages/posts/custom posts) you want to show the column, there are different action hooks that you can apply. To target a specific custom post type you use the following naming convention:

manage_${post_type}_posts_custom_column() // for posts (non-hierarchical)
manage_pages_custom_column() // for pages (hierarchical)

The basic one is the general manage_posts_columns action hook, which we’ll be using here.

function last_modified_column( $column, $post_id ){
  if( "last_modified" == $column ) {
    the_modified_time( "F j, Y" );
  }
}
add_action( "manage_posts_custom_column" , "last_modified_column", 10, 2 );

What’s happening here is that when the columns are being processed one by one, when it matches the column called ‘last_modified’  it will output the last modified time of the post. We’re using the_modified_time() function to render the time the post was last updated. We can control the formatting date and time by passing parameters you might already be familiar with. The action hook registers our function so that it’s run when it processes the columns.

Step 3

Next we want to tell WordPress that this column should be sortable by registering our interest. We’ll be using an action hook that follows a familiar naming convention.

function last_modified_column_register_sortable( $columns ) {
	$columns["last_modified"] = "last_modified";

	return $columns;
}
add_filter( "manage_edit-post_sortable_columns", "last_modified_column_register_sortable" ); // replace "post" with the slug of your custom post type

Step 4

We need one extra step to make this column sortable. To do this will create a function that modifies the request with an extra query parameter that enables the sorting.

function sort_column_by_modified( $vars ){
	if ( isset( $vars["orderby"] ) && "last_modified" == $vars["orderby"] ) {
		$vars = array_merge( $vars, array(
			"orderby" => "modified"
		) );
	}
	return $vars;
}
add_filter( "request", "sort_column_by_modified" );

To get it all working, we now only have to make sure this code is loaded by adding it to a custom plugin, or the theme’s functions.php file. Personally I would recommend creating a small custom plugin for this. The great thing about having the last modified data at a glance is that you can see what posts were recently edited, and which haven’t been touched in a long time.

Fear And Surprise: Improving A Widespread WordPress Pattern

A very common pattern used in WordPress core, plugins and themes is way of dealing with supplying arguments to functions and merging them with default values. This pattern is documented in the codex here and utilizes wp_parse_args() and extract().

What does it do? Well a look at the actual wp_parse_args function shows us that it’s a glorified version of array_merge. What array_merge does is combine two arrays into one, overwriting duplicate keys supplied by the first array. That’s exactly what you’d want right? You see if your function requires a value and none is set by the user, a default would be used. Merging the defaults with the user supplied arguments ensures that you always have your required values set.

As a matter of convenience extract() is often called straight after wp_parse_args(). Extract will take all the variables in an array and import them as individually named local variables based on the array key value. An example:

$my_array_of_settings = array( "my_setting" => "wonderful" );
extract($my_array_of_settings);
echo $my_setting; // prints "wonderful"

The problem with extract() is that it is also a potential vector for insecure behaviors since it will try to import every value that is contained in the supplied array. It also can result in unpredictable results. That’s not a good thing when you are not in full control of how arguments are passed to your functions (which is certainly the case for distributed plugins and themes). The alternative, and most advised practice is to avoid the use of extract altogether and just use other ways of accessing the values.

I’m not one to throw the baby out with the bathwater and what I really wanted was a stricter version of wp_parse_args(), one that will limit the variable set based on those defined in the defaults. Instead of importing all the variables in a supplied array, it will only import those that are also specified in the array of defaults. (This behaviour is actually what I was intuitively expecting from wp_parse_args in the first place.)

function custom_parse_args( $args, $defaults ){
	if ( is_object( $args ) ) {
		$r = get_object_vars( $args );
	} elseif ( is_array( $args ) ) {
		$r =& $args;
	} else {
		wp_parse_str( $args, $r );
	}

	if( is_array( $defaults ) ) {
		foreach( $defaults as $default_key => $default_var ) {
			$vars[ $default_key ] = ( $r[ $default_key ] ) ? $r[ $default_key ] : $default_var;
		}
	}
	return $vars;
}

So what does this do differently? Let’s compare this function with wp_parse_args. Let’s have an array with defaults and an array with our arguments, some of which the function is not expecting.

$defaults = array ( "title" => "parsing arguments test");
$args = array(
	"title" => "I was not expecting some kind of Spanish Inquisition",
	"unexpected_response" => "Nobody expects the Spanish Inquisition",
	"chief_weapon" => "fear and surprise",
	"three_weapons" => "fear, surprise and a ruthless efficiency",
	"ah_four_weapons" => "fear, surprise, a ruthless efficiency and an almost fanatical devotion to the pope",
);

$wp_parse_test = wp_parse_args( $args, $defaults );
$custom_parse_test = custom_parse_args( $args, $defaults );

If we now inspect the resulting variables, you’ll find that the wp_parse_args method leaves us with:

// var_dump( $wp_parse_test ); outputs:
array(5) {
  ["title"]=>
  string(52) "I was not expecting some kind of Spanish Inquisition"
  ["unexpected_response"]=>
  string(38) "Nobody expects the Spanish Inquisition"
  ["chief_weapon"]=>
  string(17) "fear and surprise"
  ["three_weapons"]=>
  string(40) "fear, surprise and a ruthless efficiency"
  ["ah_four_weapons"]=>
  string(82) "fear, surprise, a ruthless efficiency and an almost fanatical devotion to the pope"
}

But our custom function filters out the unwanted variables automatically:

// var_dump( $custom_parse_test ); outputs:
array(1) {
  ["title"]=>
  string(52) "I was not expecting some kind of Spanish Inquisition"
}

Because we better control what variables can be used inside the function, using extract() becomes a whole lot safer.

For even more control, you could even run data sanitization and validation checks on each variable before they are allowed to overwrite a default variable.