From WordPress

The case against gratuitous Lorem Ipsum text

Caslon-schriftmusterblatt

My Lorem Ipsum tattoo on CheckOutMyInk.com

Let me preface this article by clearly stating that I’m not a designer. My background is solidly in the implementation side of things, which might be why I’m approaching this issue from what seems like a very biased viewpoint. If you are a designer, and you feel I’ve made some sort of horrible mistake, please don’t hesitate to let me know in the comments. Also, most of what I’m discussing here applies specifically to WordPress sites, which tend to be heavily publisher-focused and therefore contain user-generated content that the designer and engineer cannot control.

We’ve all seen the perils of using Lorem Ipsum or generic placeholder text to build static Photoshop mockups. Things like “Sample Title” never seem to work out right when translated to the web. A real headline, like, for example “The case against gratuitous Lorem Ipsum text” is a heck of a lot longer than the example, and forces the developer or web engineer to deal with the fallout.

The reason for this fallout, of course, is that the original design doesn’t account for flexible title lengths, and requires whoever implements it into the dynamic environment of the web to “guess” as to how the title element should flex to accommodate real-world content. In other words, by using generic text, the idea that the static mockup is just that–static–is reinforced to the client and even to the designer who created it.

Of course, as web design moves solidly away from static mockups and towards in-browser design, there’s a tendency to assume that the issue of design being too static is automatically eliminated. I’d argue this couldn’t be further from the truth. If an in-browser design uses generic titles and Lorem Ipsum content, anything can happen.

I’ve seen markup created that relied on a fixed-height title element. This created a huge problem when editors wanted to write an article with a title over 30 or so characters. I’ve also seen elements that relied on minimum content length that the generic copy provided. Once that markup intersected with real-world (sometimes very short) content, the sidebar collapsed underneath it. These are just a couple of examples–there are many more out there, and I’m sure everyone has their own stories about problematic user-generated content.

All of these problems end up being discovered during the implementation process, well into the process of designing and building a website. As a subscriber to Kevin Hoffman’s “iterate early” methodology, this late-round revision of markup and (maybe) design strikes me as highly inefficient and a major risk to on-time, on-budget project delivery.

So what’s the solution? Well, if you’re redesigning an existing site and have access to content, it’s probably best to use several examples of that content to test your in-browser design. It also helps (and this is admittedly difficult without trial and error) to think through possible content outliers and how they can affect design. While there are some seriously esoteric CSS bugs that will inevitably surface when a design is implemented into a dynamic website, testing a few common things can really help with most publishing-style sites:

  • A really short headline, e.g. “49ers Win
  • A really long headline, e.g. “Local residents up in arms over county officials’ stated desire to begin eradicating local mongoose population
  • Content that spans length from a few hundred characters up to several lengthy paragraphs
  • Enough navigation links in various nav bars to represent the actual number of options that will be on the site
  • A photo that is wider than it is tall; a photo that is taller than it is wide.

The good news here is that all of these things can be tested easily in your in-browser designs using some simple JavaScript. For example, by setting the text of the article title to several different lengths, you can easily test whether your design can handle flexible titles.

Similarly, if you’re unable to obtain actual short and long content examples (e.g. if you’re building an entirely new site), creating a small paragraph of sample text that you can then clone to create longer and longer articles is a handy trick for testing how your design handles different article content. I’ll be posting a couple of examples of these JS snippets in a follow-up to this article.

If you’re looking for some additional tips,¬†this article¬†provides a great walkthrough of how to overcome the Lorem Ipsum “crutch.”

Image source: http://www.checkoutmyink.com/tattoos/marquin23/my-lorem-ipsum-tattoo

Display Admin Notices in custom locations in the WordPress Dashboard

If you’ve used WordPress for a while, you’re probably familiar with the nice-looking notices (warnings and errors) that appear at the top of various admin pages:

Screen Shot 2013-02-05 at 2.46.59 PM

These notices are great for posting generic information relevant to a particular page up near the top, where they’ll be easily seen. But what if you want to use the .updated and .error classes to create messaging in other parts of the page? If you just add markup, it will move up to the heading of the page, because of the following JS that runs in wp-admin/js/common.js:

// Move .updated and .error alert boxes. Don't move boxes designed to be inline.
$('div.wrap h2:first').nextAll('div.updated, div.error').addClass('below-h2');
$('div.updated, div.error').not('.below-h2, .inline').insertAfter( $('div.wrap h2:first') );

This explains why messages get pushed to the top of the window regardless of where they are actually placed in the server-side markup. Also, it proveds a really easy way to put the message where you want it: just add a class of .inline and your message will stay where you want it.

Facebook JavaScript SDK “Uncaught RangeError: Maximum call stack size exceeded” error

volcano-ecuador-825x558

I’ve been dealing with an issue for a couple of months where the Facebook JavaScript SDK wouldn’t function properly on my local development instance, even though it was working fine in our testing and production environments. I tried all the obvious things–confirmed the correct URLs in the Facebook App settings, made sure I was using the right App ID and Secret, etc. The weird thing is, according to the console FB was an object, and XFBML was an object, but parse() was not a method of XFBML.

I wasn’t seeing any of the usual JS errors in the console in Chrome either, which was a bit confusing, at least until I opened Safari and saw this:

Uncaught RangeError: Maximum call stack size exceeded

According to this question on StackOverflow, the problem is caused by running the old Facebook SDK (FeatureLoader.js) alongside the new one (all.js). I was positive that FeatureLoader.js wasn’t loading anywhere in my codebase, and a quick check with ack didn’t show anything either. FeatureLoader.js definitely was getting loaded though, and when I double-checked I saw that it was being loaded by a locally-installed dev plugin that I have running (but that isn’t on our dev or production sites). Plugin removed, problem solved.

Lazy-load a LinkedIn Sharing button after the JavaScript window.load event

Adding social networking sharing buttons to your site has become almost a ubiquitous step in Web development, to the point when some designers have stopped thinking about the performance impact of rendering multiple buttons via JavaScript while a page is still loading. The delay might not be noticeable for, say, 1 or 2 buttons, but when you’re rendering multiple buttons per page (when you have a button to share individual Tweets on a page, for example), it can get out of hand (turns out JavaScript crashing the browser creates a user-unfriendly experience for most people).

The solution is to lazy-load the buttons when you need them, either when a user clicks to expose a previously hidden div, or at the very least after the window.load JavaScript event, to prevent slowing your pageload times down. Here’s an example of a simple way to lazy-load a LinkedIn Share button on window.load:

First, include the necessary scripts (LinkedIn’s in.js and jQuery). You can do this in the footer if you want…after all, you’re not doing anything with them until much later in JavaScript-time:



Next, add some jQuery in a script tag that looks for any script tag with a type of ‘unparsed-IN/Share’ (the name doesn’t matter, as long as it’s NOT IN/Share, since the whole point here is you don’t want the in.js script to parse the tag). Depending on the size of your DOM, you may want to be more specific with your jQuery selector…a div or a section of content is fine, and you can bind to a click event, a scroll event, or whatever else you’d like to initiate the parsing of your LinkedIn buttons:

 jQuery(window).load(function(){
    jQuery('body').find('script[type="unparsed-IN/Share"]').each(function(){
      jQuery(this).attr('type', 'IN/Share');
      IN.parse(document); //you can also use getElementById('id') in place of document here
    });
  });

Finally, you just need to add LinkedIn sharing tags in the following manner. The key here is to change the JS script type from IN/Share to unparsed-IN/Share (or whatever you chose in the jQuery above), which will cause the tag not to be rendered when in.js is loaded, allowing you to control with the JS when the tag is actually parsed, using IN.parse (which can be applied to the document as a whole, or an element as retrieved by the built-in JS document.getElementById method.


Update: As Howard points out in the comment section, if you don’t need to load the in.js script to render any LinkedIn buttons or content earlier, you can always accomplish lazy-loading by simply deferring the script load until you want to render the buttons. This allows you to avoid parsing and replacing the ‘type’ on each JavaScript snippet. If you need LinkedIn content to render both before the onload event as well as after, though, you’ll still need to do the replacement.

WPTouch: WordPress theming for mobile devices that just works

[simage=153,288,y,left,]I just installed WPTouch, the WordPress plugin that serves up a clean and simple mobile version of your site to visitors using smartphones and other mobile devices. A couple of years back, I tried to do the same thing with a different WP plugin, but at that point things just weren’t ready (for one thing, there were so many different devices and user agent strings that detection was iffy at best), and I ended up having to remove the plugin. WPTouch, on the other hand, was pretty much ready to go right out of the box.

[simage=154,288,y,right,]Immediately after downloading and installing the plugin, I tried to load the page on my Motorola Droid. Everything looked good without any customization. The layout is nice and clean, and the additional functionality for touchscreen phones is nice. For example, there’s a menu system that allows navigation by tag and category that’s very well suited to a mobile phone screen, and is a nice replacement for the wide and JavaScript-heavy popup navigation on the main version of this site.

[simage=155,288,y,left,]After initial testing, I enabled Google AdSense for Mobile, which was as simple as pasting in my publisher ID. The ads show up fine on a stock Motorola Droid and an iPhone emulator, but failed to appear on my Droid, which is running Bugless Beast 0.6. I’m not too worried about that, though, as I suspect the hacked browser might have an ad-blocker in there, and either way, I don’t see the Bugless Beast user community as being a source of significant ad revenue for me, so I’m holding off on investigating the issue further. For now, I’m just glad that there’s finally a plugin like WPTouch out there, that just works like it claims it does.

Refresh Twitter and Facebook social icons after an Ajax request

I recently found myself dealing with the following problem: I wanted to lazy-load as much of the social networking components of a site as possible, which meant deferring the load of both the Twitter and Facebook JS until after the document finished rendering. This process was relatively straightforward, but in the course of implementing the buttons I discovered something interesting: when you do an Ajax request to refresh a portion of the page, buttons in there are not dynamically refreshed. This makes sense–there’s nothing to re-run the appropriate JS methods to render them–but it’s not good.

My quest on Google first took me to this forum, where the exact same problem I was having was discussed back in Sept-Oct. Since a new version of the Twitter @anywhere API came out today, and doesn’t include a TweetButton, that wasn’t going to be an option either.

Thankfully, I found this post, which outlined the best workaround I’d seen yet for interacting with Twitter’s widgets.js file. It’s worth a quick aside here: the problem is created because the @anywhere API, which has all named functions, does not have a method to create a TweetButton. That is handled instead within widgets.js, which is all wrapped in one big anonymous function. There’s a render() method hiding pitifully inside, but it took someone with JS skills beyond mine to coax it out of hiding.

Both of the examples in the previous link work great, and can be cut-and-paste. In my case, however, I didn’t want to mess with the actual $.get request, which was happening in a completely different script file, and was written years ago. Thankfully, a few quick tweaks resulted in this:

$('.topic-term-link').ajaxComplete(function(){
   //re-render the facebook icons (in a div with id of 'content')     
   FB.XFBML.parse(document.getElementById('content'));

  //re-render twitter icons by calling the render() method on each
  $('#content').find('a.twitter-share-button').each(function(){
     var tweet_button = new twttr.TweetButton( $( this ).get( 0 ) );
     tweet_button.render();
  });
});

Since jQuery lets me bind directly to the ajaxComplete event, I didn’t even need control over the Ajax call, which is good, because it wasn’t an option. Now, maybe Twitter will name the main function in widgets.js and we can just call a single line like for Facebook in the above example.

Tagline Rotator plugin v2.0 is now available

NB: If you are having any problems with taglines not rotating after the upgrade, please de-activate and re-activate the plugin. This is due to WordPress no longer calling the activation hook when you upgrade a plugin through the Dashboard.

As is often the case over the holidays, I had a little free time to update my Tagline Rotator plugin, which was in need of some serious cleaning up. Version 2.0 is now available on the WordPress plugin repository, and includes the following improvements:

  • Entire plugin is now class-based and the code is significantly cleaned up and better organized
  • All the MySQL queries that the plugin used are eliminated. Instead of using a separate table, the plugin now stores its data in the wp_options table
  • If you’re upgrading from a previous version, the plugin will pull your current taglines from the table and save them to the wp_options table. It will not delete the old table (something like wp_tagline_rotator), so your old taglines will still be there. Once you’ve confirmed the taglines are working properly, you can safely delete the table. I’ll be adding an option to delete any tables created by the plugin thru the admin dashboard in a future version.

As always, if you encounter any problems or have any suggestions, please leave a comment on the plugin’s homepage.

jQuery – Excluding elements with attributes ending in a particular string

Ok, let’s say you have some data that looks like this:

A title
Some content
A title
Some content

Now, if you need to style just the elements that are NOT post-modal, you have a problem. You can’t just select elements that start with an id value of ‘post,’ because then you will be selecting all the divs within the container. You could style the html with an additional class, but in this case the html wasn’t changeable, and adding a class with jQuery presents the same problem as selecting the elements–they’ll all match at the start of the id, even the ones we don’t want. The solution is this:

$(".container").children().not('[id$=modal]').each(function(){
//you can do something to each non-modal element in here
});

Now we’ve selected only the elements within our container that don’t contain the word ‘modal’ at the end, and we’re free to do whatever we need to them (in my case, it was pagination). For additional info on the .not() method, check out the jQuery doc.

WordCamp Boulder 11 a.m. update

I’m attending WordCamp Boulder today, and as of now I’ve seen a couple of sessions. I have to say the Caching talk was quite informative and entertaining, and on a personal note was a source of some working nginx rewrite rules for WP Super Cache. Thanks to vocecommunications.com‘s Chris and Sean for an entertaining and informative talk. The only complaint I have is that the venue, TechStars’ office environment, was way too small for the group that attended. Don’t think that’s anyone’s fault, just the downside of an awesome talk with great attendance.

The second talk I attended focused on design. Some of the interesting notes I took away from that were that talk were to avoid ‘lorem ipsum’ default content, design for mobile by creating scalable CSS, and that designers should know at least HTML and CSS, even if they’re just ‘frontend’ people. The lorem ipsum issue made good sense–if you don’t know what kind of content you’re designing for, it’s likely your design will be generic and not help the content stand out for what it is. It’s worth spending the time to create some sample posts that actually represent the specific content you will be showing on the production site. Along the lines of mobile styling, the design panel agreed that scaling is the best way to address the needs of diverse resolutions. As we add things like smartphones, iPads, etc., the ability to target inidividual browsers becomes cumbersome, and something like http://simplebits.com/, which uses a design that scales quite nicely from iPhone to full desktop resolution, becomes a better choice.

I’ve definitely gotten my $25 worth so far.

WP-dBug

A colleague at work found dBug, a sweet PHP class for creating nice, clean debug output and implemented it into our framework. While debugging a different WordPress plugin, I realized how nice it would be to have similar output in WordPress. Thanks to some planned system downtime during a major datacenter move where I work, I finally had a chance to create a plugin to implement the dBug class. It’s basically a wrapper for the original class–all the credit should and does go to Kwaku Otchere for creating what is (in my opinion) the nicest-looking debug output I’ve ever seen. It’s simple as heck to use the plugin: just install it, activate, and call it like this:

[cc lang=”php”]
function fill_my_screen_with_stuffs (){
global $wpdb;
wp_dbug( $wpdb );
wp_die( ‘Did you know WP 3.0 has a cool new wp_die() function?’ );
}

[/cc]

As a side note, you can use dBug for whatever code you want–just include the single PHP file and use it according to the author’s instructions.