Using Constants to Streamline Your WordPress Theme

wordpress logo notext rgb Using Constants to Streamline Your WordPress ThemeWorking with a large corporate site that gets plenty of traffic and runs WordPress has taught me a few things about WordPress that I don’t particularly like.   The biggest complaint I have is that WordPress views the database like a swarm of bees views a bear attacking their hive: hit it repeatedly hoping that it goes down.  Doing a freelance gig and discovering that your client’s hosting has a database cap of 75000 hits/hour is not a fun situation when they’re getting around 1000 page views per hour and it’s pushing that cap.  Caching is great except that this was go-live, and there was a lot of data to cache for the first few hours.  Even still, caching doesn’t help everything.

So what can you do to help smoke those bees down?  Get a little nimble with your code and stop relying on WordPress conventions for everything.

bloginfo() and get_bloginfo()

These two functions are bad news, because they make a database request every time.  If you’re designing a custom theme for a site and you’re not expecting a lot of changes to the name and tagline, making heavy use of these functions is going to bog you down. Here’s what I did:

define('THM_TITLE', 'Page Title');

Then, where you’d be using bloginfo(‘name’), you just change that to echo THM_TITLE;

Instead of relying on get_bloginfo(‘name’) to hit the database just to figure out what my site’s name is, I just tell it in code with a constant.  I used the THM_ prefix to localize it for my theme and ensure I’m not crashing into any other defined constants (in practice I use a more descriptive prefix).  Obviously, hard-coding the name doesn’t work if you’re running a multisite or are building a theme for wide use, but if you’re building for a static installation to use WordPress as a CMS, you’ve just saved yourself one database call.  The name is just the first thing to tackle, though.  The biggest culprit I encountered was get_bloginfo(‘siteurl’);.  I used this all over my theme to make sure my images and stylesheets and script calls were all originating from the correct URL.  Now, it’s technically OK to leave this out, but let’s go for accuracy.  I work with development and integration servers, so this needs to be dynamic.  At the top of my functions.php, I added

define('THM_SITEURL', get_bloginfo('siteurl');

And then I replaced every instance of get_bloginfo(‘siteurl’) with THM_SITEURL.  That saved me 10 database calls on my home page alone.

Here’s a few others that I use:
Theme diretory URL:
define('THM_TEMPLATE_DIRECTORY', THM_SITEURL.'/wp-content/themes/theme_directory');

Pingback URL:
define('THM_PINGBACK_URL', THM_SITEURL.'/xmlrpc.php');

Charset:
define('THM_CHARSET', 'UTF-8');

All told, between those five defined constants, I reduced my database calls on my home page initiated by my theme from 22 to 5.

Don’t stop there, though.  Just about everything in get_bloginfo can be hard-coded for a standard, out-of-the-box WordPress setup.  And chances are, if you’re running a highly custom theme, you can deal with hard-coding the rest.

Go Live: Wharton Magazine

The process of designing and implementing a new website for Wharton Magazine was not a simple undertaking.  The magazine already had a website running OpenType/RedDot CMS, administered in large part by a third-party vendor.  Neither the CMS nor the maintenance arrangement were working very well for the magazine staff, which lead to discussions of what direction to go.  From the beginning of the process, I was an advocate for not only moving to WordPress, but also integrating with Wharton’s vast multi-site setup to take advantage of the existing framework and the resources it already had in place.

wharton 1 300x200 Go Live: Wharton Magazine

The existing Wharton Blog Network would also need to be integrated, moving it from its standalone setup into the larger framework while maintaining all of its functionality.  As the ‘users’ on the Blog Network did not need to be users in the traditional WordPress sense, the integration of the network proved to be a chance to streamline the posting process for the web principals on the magazine staff.

wharton 2 300x200 Go Live: Wharton Magazine

I took full advantage of the features in WordPress 3 to create multiple post types and taxonomies to support the various parts of the site.  The Issue archive took the old and complex CMS system and transformed it into a setup that would allow the staff to compile articles and create the entire online version over time and organize them correctly before launching them to the site.

The end result is a site that the Wharton Magazine staff can maintain and update autonomously, building a growing archive of back issues with a click of a button.

Go Live: LifeShield, Inc.

I joined the LifeShield team near the beginning of a site-wide overhaul to move from a static page framework to a more marketing-friendly CMS approach. The IT team had identified WordPress as their CMS of choice, and I moved into a lead role in customizing the site and integrating the existing framework.  The layout had been designed by third-party firm and required extensive modification to fit into the existing business model.  Additionally, there was a marketing and tracking codebase that didn’t play well with the way  WordPress runs.  Integrating the two was not straightforward, and involved a lot of dancing around the WordPress core.  My primary goal was to have a seamless integration that did not involve a single edit to a WordPress core file, and achieved that by making extensive use of WordPress hooks and error handling.

lifeshield 1 300x200 Go Live: LifeShield, Inc.

In addition to the WordPress core, I added a number of external pages for community crime stats using the Google Maps V3 engine and a third-party crime aggregator.  The first step was to format the data imports to be search-friendly, and then it was on to creating a JSON app to load new data points when the user scrolled around the map.  There was a lot of query-magic to generate the returns in a web-friendly time frame.

lifeshield 2 300x200 Go Live: LifeShield, Inc.

The database contains millions of records, and we only wanted around 1000 at any given time – in a particular radius around a particular point for a particular time frame.  The solution was to write a query that narrowed itself: first by calculating a box, then by calculating the radius, and finally narrowing by date.  My first attempt produced results in around 3 minutes, and the final production query returns in under a second.

For the curious:

SELECT
*
FROM
(SELECT
d.*,
FROM
[crime_table] d
WHERE
d.latitude > [latitude_minimum]
AND d.latitude < [latitude_maximum] AND d.longitude > [longitude_minimum]
AND d.longitude < [longitude_maximum]
AND ROUND(SQRT(POWER(69.1 * (d.latitude - [requested_latitude]), 2) + POWER(69.1 * ([requested_longitude] - d.longitude) * COS(d.latitude / 57.3), 2)), 0) AND timestamp(d.datetime) = DATE_SUB(now(), INTERVAL [requested_time_start] DAY);
) tt
ORDER BY
tt.datetime ASC
LIMIT
0, [requested_limit];

The latitude and longitude mins and maxes are calculated on the fly by adding or subtracting the following from each: (distance_in_miles + (distance_in_miles * .25)) / 69.

HTML5 Video Roundup

I’ve just jumped feet-first into HTML5, and I must say, it’s pretty awesome. I’m actually learning a lot about HTML4 as I go, due to the great writing by Mark Pilgrim (I’ve read the printed version).

My first HTML5 challenge was video, and a challenge it was. For as browser- and code-friendly as HTML5 is, getting all of the pieces to fall into place was still a daunting task. Thankfully, the internet provided all the answers that I needed. The problem, however, was asking the right questions. There was no one answer that I could find, so I’m writing it. This isn’t new information, it’s an assembly of all the pieces I needed to get video working correctly on my site.

Obviously, there are a number of browsers out there vying for market share, and to distinguish themselves from one another, they have collectively made the decision to not support a single standard of, well, anything. Video is no exception. The unfortunate truth is that you’re going to need four different video formats if you want to ensure that everyone is going to see your video. The good news is that HTML5 makes that a snap!

1 – HTML5 markup
Mark Pilgrim handles the gritty details of what video formats to choose and why (including how to encode your video), but after that, you need markup:

<video controls width="500" height="300" poster="poster.jpg">
<source src="video.mp4" type="video/mp4" />
<source src="video.ogv" type="video/ogg" />
<source src="video.webm" type="video/webm" />
</video>

This will display whichever version the browser can handle, with video controls, using the specified image as the first screen. Between MPG4, Theora/Vorbis and WebM, that takes care of playing your video on every browser capable of supporting HTML5, which at this point, is most of the market. Something else to note here is that iOS 3 apparently only reads the first <source /> tag, so you need to make sure that your MPG4 video source is first on the list (as in the example). This problem was fixed in iOS 4, but if it were as easy as a new version, you’d never again have heard “IE6″ after October 2006.

2 – Flash, for older browsers (and by “old” I mean “Internet Explorer”)
Next up, you’ll want your Flash. There are a number of ways to handle Flash, so I’m not going to get into them here. Whatever you were using to display Flash before will continue to work. You want to place it right before the </video> tag. If the browser doesn’t support HTML5, it will ignore the <video> tag and execute your Flash. Problem solved!

3 – A few stragglers
We’re three quarters of the way there. Just two more things to note:

A) MIME types! These are really really important. Make sure the MIME type you’re declaring in your <source /> tag is actually what you’re serving. If you’re hosting your videos on S3, make sure you set your MIME types for each file to what they should be. S3 defaults to application/octet, which will cause Firefox to stare blankly at you while you wonder why there’s a hole where your video should be. Other browsers fail a bit more gracefully.

B) The poster attribute. Again, iOS 3 is a troublemaker. It’s not that it ignores the poster attribute altogether (which would actually be nice) – no, it dumps it over the controls and wreaks havoc on the ability to play the video. After wading through a lot of conversations where people wondered if there was a solution, a coworker and I finally hit on a solution that works. I hate error trapping for one browser, but if you know you’re going to have people using it, then it’s a necessity.

Basically, we check for iOS 3, and create the video tag with JavaScript:

var osString = navigator.appVersion;
if (osString.indexOf("OS 3_") != -1 && osString.indexOf("like Mac") != -1) {
// create video tag for iOS 3
document.write('<video controls="true" width="500" height="300" id="video_player">');
}else{
// create video tag for the rest of civilization
document.write('<video controls="true" width="500" height="300" poster="/alumni/giving/images/The_Campaign_Final-poster.jpg" id="video_player">');
}

And that’s all there is too it. Hope this saves you some time.

Go Live: Wharton Alumni and Giving to Wharton

These two sites went live at the beginning of September, and while I’m still ironing out bugs, the public side of the sites is worth mentioning here.

wharton alumni site 300x200 Go Live: Wharton Alumni and Giving to Whartonwharton giving site 300x200 Go Live: Wharton Alumni and Giving to Wharton

Both of these sites are built in RedDot CMS (actually, it’s OpenText CMS now, but we still call it RedDot).  From January to, well, now, the majority of my job has been converting the old static site to RedDot.  I can’t say that this process has been an easy one.  I was responsible for the creation and implementation of the bulk of the pages and this required me to learn a completely new system that was coded in Germany.  I experienced European coding a few years ago after IQ outsourced a project to Poland.  Most of the syntax of languages is written in English (with the random Hebrew PHP error message), but that doesn’t mean that people who speak Polish or German are going to code in English.  What might seem like a perfectly logical variable name in Polish probably isn’t going to make nearly as much sense when it’s been run through Babelfish.  Likewise, Germans don’t have the same knack for writing concise English description as a native English speaker does.  The major impediment to learning RedDot was figuring out what exactly all the constructs inside it actually did, because the names given to a majority of them didn’t seem to accurately describe them.

The other major hurdle was that the team that manages the RedDot server is a school-wide resource, and a number of other departments were designing and launching sites in RedDot, often without the benefit of a developer.  This meant that the RedDot team was not only trying to build and launch a number of other sites, they were tackling my near-incessant questions, and dealing with an upgrade that resulted in a lot of things breaking.  On top of that, they were outsourcing major issues to one of the few RedDot vendors, a company of 15 people located somewhere near Vancouver.

So, here are the run-downs for both sites.  A quick note concerning the publishing:  Our RedDot setup has two publication packages: Staging and Production.  Additionally, we have three servers: Development, Staging and Production.  As these terms relate, it’s a bit confusing.  Ideally, RedDot Staging publishes to the Development server, and RedDot Production publishes to the Staging server.  The reason for that is that the Staging server pushes everything to the Production server once every 15 minutes.  We don’t have direct access to the Production server.

Giving to Wharton

This site actually went smoothly from start to (almost) finish.  The site itself was populated with content and, for all intents and purposes, ready to launch by the end of May.   As the project neared go-live, a number of the stakeholders came forward with content changes and section revamps.  All of these were handled fairly smoothly, and the only hang-up came right before go-live when we realized that the Staging publication package and the Production publication package were not mirroring each other.  The interim solution has been to publish both packages to the Development server, make necessary changes, and push them to the Staging server manually.

Wharton Alumni

This part of the project was a bear.  From the very beginning, the installation was fraught with problems that we kept attempting to address.  It seemed at every point that once one was fixed, two more would crop up.  Finally, nearing the go-live point, we decided to scrap the entire thing and re-create it.  This turned out to be a very effective tactic.  Scrapping 8 months of development wasn’t an easy argument to win, but the result was a completed site in just over two weeks.  The 8 months of combating bugs gave me a lot of good insight into RedDot’s inner workings, so once I had a bug-free environment, construction of the site went very smoothly.  The same publishing problem from the Giving site showed up, however, and at the moment, we’re still publishing manually.

All in all, it’s been a long, strange trip, but the reception has been amazing.  The new site is worlds better than the previous one, and it’s given the staff at External Affairs a much easier way to update their changing information than they had before.

Go Live: Wharton Blog Network

This site actually went live around a month ago, but I’m just getting around to the write-up.  I’m not sure what took me so long, considering I now have something to show to the public that has the Wharton name on it!

wharton magazine blog Go Live: Wharton Blog Network

The Wharton Magazine site itself is running RedDot CMS, but the blog segment has been running on WordPress for around two years. In its previous incarnation, it was a point of contact for the editorial staff. This concept was expanded to include relevant non-magazine article updates from faculty and alumni.

In the initial concept phase, I suggested the possibility of using WordPress MU to create a new blog for each user and then having the main blog page aggregate the posts. Within a few days of that proposal, WordPress 3.0 was released, and after a review of the features, I decided that the robust multi-user setup was actually too much bang for the buck and scaled back my proposal to a simpler WordPress installation with multiple contributing users.

Most of the functionality comes straight from the proverbial box. I developed a simple plugin for the sidebar in order to display the editor’s most recent post in a styled box.  There is also a custom work-around to allow a specific author’s most recent posts and user profile to be two separate pages.  User profile pages is one of the things that I wish WordPress did a bit better, but the solution I came up with is fairly simple to use but not very intuitive, so I wouldn’t recommend it as a good solution.

Going forward, I’d love to spend some time playing with the Contributors section on the sidebar.  As it stands, it’s simply a text widget that I’ve hard coded.  I’d like to expand that into an automated widget that the administrator (which at the moment is me) can control from the back end.

New WordPress Widgets

Having been kicking around the exciting world of installing and customizing WordPress, I felt it was high time I launched myself into the even more exciting world of developing for WordPress.  And here’s what I’ve come up with:

Recent User Posts

Recent Category Posts

Both of these are widgets that do basically the same thing, so I’ll describe them together here.

In developing the new Wharton Magazine blog, we needed a widget to display the Editor’s most recent post.  I poked around for a bit, and realized that there really wasn’t a plugin to handle this, so the need for one was obvious.  After getting the basics down, I decided that it actually had more applications than just a single post, and started adding features.

So, the end result is two widgets.  Enter a title, select the user/category you want to display, enter the number of posts to display, and select if you want to display a link to the user/category and the time and date.  Not complicated to use and does just what it says it does.

Before I release it to the WordPress Plugins Codex, I’d like to see if anyone wants a shot at debugging or can offer any tips or suggestions.  Files are at the links above, and thanks in advance!

WordPress 3.0

I’m getting really drawn into WordPress and all its wonderful functionality, especially with the release of 3.0.  I retooled the back end of this site to run on WordPress MU a few months ago, because I run a few separate blogs and am in the process of expanding that for family members.

I was happy to see that WordPress merged the base and MU codebases into one, fully-functional software package.  The upgrade wasn’t as smooth as I’d have liked it, but I guess they figure that if you’ve managed to install and maintain MU, you shouldn’t have a problem editing PHP and .htaccess files on your own (as opposed to automating what boils down to three lines of code).   Stupid me misread one of the steps and wound up with no images displaying sitewide for 24 hours, and wondering if I was going to have to re-import all of them.  Once I figured out my mistake, though, the problem seemed pretty trivial.  Other than that, installing and upgrading are remarkably simple.

WordPress has been getting better and better for the end user and administrator since I began using it about two years ago, and now that I’ve begun really getting into the heart of it, I’m really glad that the development has gone toward all of those things that I wish it did.  It’s like they’re reading my mind!

So, on the horizon are three projects that I’d love to tackle.  One is a freelance job that I’m hoping pans out, because it’s a site that I’d love to do.  The second is here at Wharton, which again, I’d love to do.  The third is a complete revamp of PennridgeAlumni.com, a site that I’ve been studiously avoiding for far, far too long.  Redoing it entirely in WordPress now seems like a possibility, and I’m already working on a development version of that.  Let’s see how far I get…

Go Live – Alternate Universes

I was hoping to post a lot more go lives here, but I’ve changed jobs to a position at UPenn’s Wharton School of Business External Affairs, and I’m working mainly on internal projects.

However, I’ve just completed a website for my Friendly Local Gaming Store, Alternate Universes.

alternate universes Go Live   Alternate Universes

Alternate Universes had an existing website, but it was built using static HTML that wasn’t very easy to update. The new site uses WordPress as a CMS, offering much greater ease of updating, as well as being able to update multiple pages using a single post. This allows for various pages to keep important content without the need to move content to those pages or clutter up the homepage for weeks or months.

Individual sub-pages are coded to include their related categories, allowing for general information for that page and a listing of pertinent posts.

The old site had an outdated calendar system, so I integrated Google Calendars using the wpng-calendar plugin for the site’s sidebar, as well as a static instance of the full calendar. This allows for much easier management and import of calendar data.

I converted the old phpBB3 forum to myBB, which was a bit more difficult than anticipated, even with a conversion app. The app didn’t accurately convert the forum settings, which necessitated a lot of snooping around in the database to get everything matched up. Once I found the broken relationships, though, it went rather quickly. There were also a few glitches with forum caches and settings files needing to be rebuilt, but all-in-all, the structure converted quite nicely. The new system will very aggressively tackle the issues they’d been having with Russian spambots filling their forum with Viagra ads and the like.

And finally, I get to take credit for the design. I don’t tackle design very often, because this is about the best I’m capable of.