Archive for the ‘Website Development’ Category
Monday, August 15th, 2011
I’ve used the excellent Yet Another Related Posts Plugin (YARPP) for about a year-and-a-half now on various client websites. Overall, I’ve found that it works great and has a responsive author who cares about updating and performance issues.
Why this post then?
Because after experiencing deadly slow post updating and post saving on a client site over the span of more than 60 days, we were finally able to track down that YARPP was causing saving or updating posts and pages to take more than a minute (sometimes up to 5 minutes or just timing out) each. In turn, this caused severe site-wide slowdowns and timeout errors for site visitors.
The Conclusion
For those of you who don’t need the detail below, the overall conclusion here is that while a solid plugin, YARPP may cause severe site-wide slowdown and crashing for WordPress installations running on an average server with lots of posts and lots of tags.
Site Specs
First, the site specs so we’re all on the same page:
YARPP Version: 3.3.1 initially, then 3.3.2 mid-way through timeframe
WordPress Version: 3.2.x
Pages: 90
Posts: 2400+
Categories: 50
Tags: 5,000
Server: Windows machine, running WAMP 2.0
Apache Version: 2.2.11
PHP Version: 5.3
MySQL Version: 5.1.36
Other Plugins Installed Affecting Saving Posts: 3
Caching: W3 Total Cache
Symptoms
We had a staff of between 1 and 3 people daily updating post categories and tags to ensure the visitors were seeing the best content for their reading, searches, general experience.
The staff experience slowness intermittently and unpredictably when saving or updating posts. This happened when updating a single post through the normal ‘Edit Post’ screen and also the ‘Quick Edit’ mode on the post list page. Trying to bulk edit more than 1 post using quick edit usually resulted in a timeout and a blank screen or the never-ending spinning save icon.
On the front end, our site visitors would experience page hangs and slow page load times whenever a post save was happening on the back end.
Our teams experienced the same basic problem in different browsers, on different machines, with different setups, so the issue was clearly coming from how we had everything set up.
In Safari:
I’ll Hit “Submit” and the little ball next to submit will spin & spin & spin, I’ll move over to work on another window, look back, and it will have stopped spinning and will look as though I never clicked submit.
In Chrome:
I’ll click submit, the ball spins & spins… Then after a while it stops and there’s a very large 8 character column beneath “Title” that says something to the effect that “My SQL Server is gone…” generally I’ll click refresh and that clears it up for the most part…
Below the post’s title I’ll right click “View” and choose “Open in New Tab” and it’ll spin & spin then will stop with no content in the body of the tab. I tried refreshing to no avail, have to close tab and re-right click & “open in new tab” again.
Additionally, we were receiving odd errors in Firefox, Chrome, and IE, all with notices along the lines of the server having too much traffic, or the server sending a blank page, or the connection being reset.
Tracking Down the Problem
Turn off pinging
At first I searched through WordPress forums and Google for anything on “WordPress dies while saving” or “WordPress hangs while updating” or “Quick Edit posts hanging” and the like.
Most results on these pointed to some version of turning off pinging or notifying other sites on update. So, we turned off pinging for all posts and removed the pingomatic address from the general options. This gave no change in speed.
Permalinks Setup
Other results for searches on improving WordPress performance and speed generally or specifically when saving posts pointed to proper permalink setup. There’s a fair bit of documentation from WordPress and others that basically concludes, “don’t just use /%postname%/ for your permalink structure.” This is because of how WordPress handles redirecting.
Instead, we should use a structure that begins with a number–the post month, post year, post day, post id, or anything else that helps WordPress sort, search, and find the post more quickly.
This is great advice, but not applicable in my case because the site was already using a /%postid%/%postname%/ structure.
Optimize Tables
Then I thought, what if we’re just not keeping our database tidy enough? There are bunches of transactions going through every minute, maybe the tables just need to be optimized. So, I set up automatic table optimization of every table in the database every 24 hours. This gave us slight increases in speed, occasionally.
Follow the errors
Rather than continue to chase a ghost, I tasked the team with sending me actual error reports or screen captures or errors.
Timeouts
Sometimes we’d see a timeout error with a line number and reference to another plugin dying on issuing a php session id. Investigation showed that we didn’t need this session id in the admin area, so I updated the plugin to not make that call for admin pages. This seemed to help tremendously at first, but after a day we were back to the same incredibly slow post updates. At the least, the timeouts no longer occurred on that line in the plugin.
Generic Error

Sometimes we’d get a generic “Error while saving the changes” on the Quick Edit screen.
This didn’t help much, but at least showed us that there was still a real issue on hand.
MySQL server has gone away
Our real break came when we captured the following error:
WordPress database error: [MySQL server has gone away]
insert into wp_yarpp_related_cache (reference_ID,ID,score) (SELECT…[specific long query info here]
WordPress database error:[MySQL server has gone away]
insert into wp_yarpp_related_cache (reference_ID,ID,score) values (6779,0,0) on duplicate key update date = now()
All other MySQL processes were working and other queries were passing through, but occasionally we would see a stack of errors that always started with these two from YARPP.
After reading through the YARPP documentation, I decided to turn off cross-relating pages and posts, turn off considering categories, and turn off considering tags. This didn’t help in a measurable way. We were still seeing 2-minute post saving.
So, I deactivated YARPP. We saw dramatic improvements immediately. The server CPU usage dropped, and more importantly, saving posts went back to a normal speed of under 15 seconds. At the same time, as a consequence, the page-load speed for visitors also increased.
After about 10 days, the site performance and saving speed has been consistently good–saving posts at under 15 seconds per. We’re also able to bulk edit posts again.
Conclusion
While a solid plugin, YARPP may cause severe site-wide slowdown and crashing for WordPress installations running on an average server with lots of posts and lots of tags.
It’s true that this issue may be limited to my client’s particular site/server/plugin setup. There’s no doubt that other plugins were interacting with YARPP to contribute to the slowness. However, the number of forum posts on this issue, the newest default settings for YARPP of not considering categories, and notes from the author on the intensive calculations being performed lead me to believe others may have the same problems too.
Tags: MySQL, Performance, Speed, Updating Page, Updating Post, wordpress, YARPP, Yet Another Related Posts Plugin
Posted in Website Development | 6 Comments »
Friday, August 12th, 2011
The CSS Scenario
Recently my graphic designer used a nice styling on a client’s webpage headlines–all words in the headline were one color and the last word was a different color.

It adds for a nice effect I think.
Of course, as the developer I’m the one who has the responsibility to bring that to life.
After a few quick searches on Google for phrases like,
- CSS Style Nth Word
- CSS style last word, CSS style first word
- php style nth word, php style first word, php get first word
- etc.
and getting results on how CSS doesn’t provide for this functionality–but does for just first letter–I quickly realized that I was going to have to roll my own.
Being in the midst of a big project, this is down and dirty code. There are likely faster or more elegant methods using regular expressions, but this gets the job done. I added in the ability to select a word by number or by specifying “first” or “last.” If you specify a word number that doesn’t exist (say a 4 word phrase is passed and you tell it to select the 6th word for instance), then just the last word is styled.
Enjoy, and please don’t hesitate to comment or send improvements my way.
The Code:
//returns a span with the class specified around the word specified within a phrase
//@text (str) is the text to look within
//@nth (mixed) is the word to style, either an integer or "first" or "last"
//@class is the span class name to apply.
function style_nth_word($text, $nth="last", $class="nth-word"){
$words = str_word_count(htmlspecialchars_decode(strip_tags($text)),1,"’'()");
$count = count($words);
if($nth == "first"){
$get = 0;
}elseif($nth=="last"){
$get = $count-1;
}elseif(is_numeric($nth) && $nth > 0){
if($nth > $count){
$get = $count-1;
}else{
$get = $nth - 1;
}
}else{
return false;
}
$words[$get]=('<span class="'.$class.' word-'.($get+1).'">'.$words[$get].'</span>');
return(implode(" ", $words));
}
Usage:
General Usage
<?php echo style_nth_word("Stand Up Paddleboard Rentals", "last"));?>
WordPress Page/Post Title Usage
(You’ll want to pass the unfiltered, or raw, post title. Otherwise formatting issues with punctuation can occur.)
<?php echo apply_filters('the_title',style_nth_word($post--->post_title, "last"));?>
Output:
Stand Up Paddleboard <span class="nth-word word-4">Rentals</span>
Tags: PHP, wordpress, wordpress development
Posted in Website Development | No Comments »
Friday, June 17th, 2011
I just launched the Hawaii Picture of the Day website. I’m particularly pleased with the widget and iGoogle gadget I wrote so people can add it to their own sites.
Here’s how the site widget looks in real time:
The site concept is simple: post good pictures of Hawaii to help people discover, be inspired, and be refreshed–daily.
The site is built on WordPress and integrates tightly with MailChimp for e-newsletter subscribing and sending. Just publish a new post and an email with the post’s content is automatically generated and sent to the list.
The site is also integrated with Facebook so that new posts automatically create a status update to the site’s companion Facebook page. Additionally, all posts can be “liked.”
I hope you enjoy it!
Tags: facebook, gadget, igoogle, mailchimp, widget, wordpress
Posted in Online Marketing, Website Development | Comments Off
Thursday, June 9th, 2011
I came across a problem today where I needed to convert a date in an MS Access Database to a MySQL timestamp using PHP.
The solution was pretty easy, but took some thinking through. Here is the answer to save you some time if you need it.
- Get the date from your MS Access database. If you’re using PHP to do this, you’ll likely use the odbc_exec($connection, $query) function and the odbc_fetch_array() function.
- Convert the MS Access date format into a UNIX Timestamp using PHP’s strtotime() function.
- Convert the UNIX Timestamp to MySQL Timestamp using PHP’s date() function and proper formatting.
In all it will look something like this:
$q = "SELECT startdate FROM datetable WHERE ID = 1";
$rs = odbc_exec($conn, $q);
while( $row = odbc_fetch_array($rs) ) {
$date = strtotime($row['startdate']);
$date = date('YmdHis',$date);
//do whatever you want with the date that is now in MySQL Timestamp form
}
One tricky part is that if you look at a MySQL Timestamp within the MySQL database itself, it will often have a form like ’2011-06-08 12:03:01′ with dashes and a space. Don’t let this fool you. If you add dashes and a space you’ll get a MySQL error for improper formatting.
Tags: database, handling dates, MS Access, MySQL, MySQL Timestamp, PHP, PHP Date, Unix Timestamp
Posted in Website Development | No Comments »
Friday, December 3rd, 2010

Image via Wikipedia
The Website Typography Battle
It turns out there is a battle raging on the best way to display fonts on websites.
Most website owners today can choose from about 10 fonts. A lot of work has been done in the past decade to give website designers, developers, and branding folks a way to display any font they want.
There is still no clear winner, but we’re getting closer.
If you’re looking to go beyond the basic web fonts, here are the options I’m aware of today (condensed version):
Is difficult to implement and takes very specialized knowledge to customize.
- Uses Flash, JavaScript, and CSS.
- Hosts the font on your server, usually.
- Works on IE5+, Firefox, Opera, Safari.
2. FontBurner, other font replacement services
Takes care of the Flash conversion part for you, which is the main benefit. Less customizable and can be a bit hacky.
- Uses the same as sIFR.
- Hosts the fonts on your server or theirs.
- Works on IE6+, Firefox, Opera, Safari.
Uses an easy online font generator for any font you want. The process is easy to implement and is CSS customizable. You may see some ‘flashing’ when the replacement loads, but there are work-arounds for this.
- Uses VML, JavaScript, and CSS.
- Hosts the font on your server, usually.
- Works on IE6+ (not yet IE9 beta though), Firefox, Opera, Safari.
Is very simple to implement and is CSS customizable. You may see some ‘flashing’ when the replacement loads, but there are work-arounds for this.
Is very simple to implement and totally customizable. For instance, there are 9 font-weights available instead of just normal and bold. Google has a font-repository that works with it.
- Uses CSS only, and is a W3C standard for CSS3. This is huge because it means eventually all browsers will support it and it doesn’t take any external coding whatsoever.
- Hosts font wherever you want.
- Works on IE5.5+ (but only with their proprietary font type), Firefox 3.5+, Opera 10+, Safari 3.1. (see a good implementation tutorial here)
Regardless of the way you implement it, you need to own the license to use any font you choose. Some fonts are free, some are licensed for print-only, etc. So whatever font you use, you need to know if you have the right to use it on a website.
I recommend option 3, Cufon, or option 4, Google Fonts. They are supported by older browsers and have plenty of free options.
I believe that option 5, @font-face will be the best in future, but not until most people have upgraded their browsers, which will be at least a few years. @font-face allows use of your own fonts or a font repository like Google fonts.
Because licensing issues can be hard to wrangle, I recommend selecting a free font if possible. Some sources for free fonts are:
Further resources:
A very well-done, in-depth comparison on Smashing Magazine on many more methods can be seen here.
Please let me know if there’s anything you would add to this.
Tags: @font-face, cufon, font burner, font replacement, sifr, web fonts, Web typography
Posted in Website Development | 1 Comment »
Thursday, December 2nd, 2010
wp_postmeta meta_keys
I recently needed to know the default key names WordPress uses in the wp_postmeta table. This information is found in the ‘meta_keys’ field of the wp_postmeta table.
I put this list together for my reference and in case anyone else is also in search of the native wp_postmeta meta_keys. For a detailed description of the wp_postmeta table, fields, and entity relationship diagram (ERD), go here.
The keys used by WordPress as of 3.0.1 were:
_edit_last
_edit_lock
_menu_item_classes
_menu_item_menu_item_parent
_menu_item_object
_menu_item_object_id
_menu_item_orphaned
_menu_item_target
_menu_item_type
_menu_item_url
_menu_item_xfn
_wp_attached_file
_wp_attachment_backup_sizes
_wp_attachment_image_alt
_wp_attachment_metadata
_wp_page_template
Tags: database, post_meta, wordpress
Posted in Website Development | No Comments »
Wednesday, October 13th, 2010

Image via Wikipedia
VB.NET Problem
You need to see (write out on your browser’s screen) all of the table names and field names in your back end SQL database and the application is written in .NET, specifically VB.NET on an .aspx page.
VB.NET Resolution
Create a page that uses a connection to your database, the database schema, and the tables it finds to loop through and write the results your browser window.
Background
I came across this need working on a client’s site recently and spent too long searching .NET programming forums for answers. For one reason or another, all of the solutions I encountered didn’t work in my situation. So, here’s another option that will hopefully save you the time.
Copy this file, change the connection string, save it, and upload it to your server.
As always, feel free to contact me with any questions.
Using this code means you agree it is at your own risk, and so forth.
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Testing</title>
</head>
<body>
<script type="text/vb" runat="server">
sub showSchema()
Dim constring as string = "paste your connection string here, it will look something like:
Data Source=data.source.com; Initial Catalog=DbaseName; User ID=someuser; Password=somepassword;"
Dim NewConnection As SqlClient.SqlConnection = New SqlClient.SqlConnection(constring)
dim query as string = "select * from INFORMATION_SCHEMA.tables"
dim myCmd as SqlDataAdapter = New SqlDataAdapter(query,NewConnection)
dim myData as new DataSet()
myCmd.Fill(myData)
for each table as DataTable in myData.Tables
for each row as DataRow in table.Rows
for each col as DataColumn in table.Columns
Response.Write ( row ( col ).ToString ( ) )
Response.Write ("<br>")
next
next
next
end sub
sub showTables()
Dim NewConnection As SqlClient.SqlConnection = New SqlClient.SqlConnection("paste your connection string here,
it will look something like:
Data Source=data.source.com; Initial Catalog=DbaseName; User ID=someuser; Password=somepassword;")
dim query as string = "select * from INFORMATION_SCHEMA.tables"
dim myCmd as SqlDataAdapter = New SqlDataAdapter(query,NewConnection)
dim myData as new DataSet()
myCmd.Fill(myData)
dim tableName as string
for each table as DataTable in myData.Tables
for each row as DataRow in table.Rows
Response.Write ( "<h2>" & row ( 2 ).ToString ( ) & "</h2>" )
tableName = ( row ( 2 ).ToString ( ) )
'get table data
dim query2 as string = "select * from " & tableName
dim myCmd2 as SqlDataAdapter = New SqlDataAdapter(query2,NewConnection)
dim myData2 as new DataSet()
myCmd2.Fill(myData2)
for each table2 as DataTable in myData2.Tables
'for each row2 as DataRow in table2.Rows
for each col2 as DataColumn in table2.Columns
Response.Write ( ( col2 ).ToString ( ) )
Response.Write ("<br>")
next
'next
next
next
next
end sub
</script>
<% showSchema %>
<% showTables %>
</body>
</html>

Posted in Website Development | 2 Comments »
Friday, September 10th, 2010
WordPress Situation
Want to have a way to format a link in the WordPress content editor box using only the “Visual” tab (ie not having to go to the “HTML” tab and manually type in a class for the link.
Solution
Add a CSS class to the insert/edit link dropdown menu

The Reason
Although we (developers and designers) tell our clients that Content Management Systems like WordPress are “really easy to use, you’ll have no problem at all,” we know that pages still tend to get broken…often.
So, I’m always looking for better ways to “foolproof” and help my clients add and edit their content using WordPress.
When adding link in WordPress’s content editor recently I realized that to format the link the way I wanted (and the way the designer designed it), I was going to have to view the HTML tab and assign the link a CSS class. I can manage that no problem, but 9 out of 10 of my clients can’t or don’t think it should be that hard.
How To
I found some simple, effective information on a few options on the WordPress Support site here (especially kchevalier’s response).
If you want a plugin for this, here’s one called Link Indication.
Or, if you want to set it up yourself, here’s how:
- Create a stylesheet in your theme directory and name it whatever you’d like ‘dropdowns.css’ (for example).
- Add your desired link classes in there, like so:
a.bigbold {
font-size: big;
font-weight: bold;
}
- Then, in your theme’s functions.php add the following:
function addLinkClasses( $wp ) {
$wp .= ',' . get_bloginfo('stylesheet_directory') . '/dropdowns.css';
return $wp;
}
if ( function_exists( 'add_filter' ) ) {
add_filter( 'mce_css', 'addLinkClasses' );
}
That’s it. Simple, yet effective for your clients (or you) to try to stay within the look and feel you designed for them.
Tags: customization, wordpress
Posted in Website Development | No Comments »
Wednesday, March 31st, 2010
WP Super Cache and PHP Cookies Don’t Mix

Website Development Challenge: Setting PHP Cookies While Using WP Super Cache
When I created the First Touch Referral Tracking plugin, it seemed like it should be pretty straight forward: check for a cookie with a referrer and set a cookie with the referrer if there’s not one. Then, simply grab the cookie whenever it’s needed and calculate a referral coupon code.
So, I wrote the code using PHP’s setcookie() function, put it place, and tested it. Everything worked like a charm…until I logged out of my WordPress admin account. That’s when I noticed some really strange things happening. Most notably, when I was not logged in as an admin, the cookie did not set. After a few hours of narrowing down the problem, I pinpointed WP Super Cache as the culprit.
The Issue in Detail
The issue is that by default WP Super Cache loads different pages to admins than non-logged-in visitors. For a non-logged-in visitor, Super Cache serves up a cached page, like it’s supposed to, in order to save your server work and round trips between the visitor’s computer and your website.
This means:
- Plugins in wp-super-cache/plugins/ are loaded *before* any of WordPress is
- PHP setcookie() will not work correctly with Super Cache “out of the box”
- Cookies and WP Super Cache can work together, you just have to change some stuff
To get the referrer, I used $_Server['HTTP_REFERER']
When my plugin ran without being logged in this was the rough sequence of events:
- Page begins loading
- WP Super Cache returns page
- My plugin grabs the $_Server['HTTP_REFERER'] and sets it in the cookie
- Other WordPress plugins run
- Page is returned to the visitor
This meant that the referrer was always my root domain. Regardless of where I actually came from, because Super Cache loads first, the last referrer is now my domain.
So, the question became, “How do I set a cookie before WP Super Cache loads?”
The solutions
Luckily, a few other developers had encountered this same WP Super Cache cookie issue and pointed me in the right direction, although some of what worked for them didn’t work for me, hence the reason for writing this post.
The solution that ultimately worked for me was option 5 here: setting the cookie using JavaScript.
Option 1—Turn off Super Cache
If you’re having a big enough issue and need a specific functionality, unless Super Cache is really helping you out, ditch it.
Option 2—Write your plugin in WP Super Cache’s plugin area instead of WordPress’s
WP Super Cache gives the option to use a specially created cache plugin area to make it play nice with other WordPress plugins. When you use the super cache plugin area, it will load those plugins first.
This uses the commands do_cacheaction() and add_cacheaction(). You can see the specs on how to use these here.
For some reason unknown to me, after re-writing my plugin to be a Super Cache plugin, it still didn’t solve the problem.
Option 3—Use the Super Cache “Half-On” option and edit wp-cache-phase1.php before line 110
A good post on the WordPress Hackers mailing list by William Canino gives instructions on how to edit the phase1.php file to set the cookie earlier:
header( 'WP-Super-Cache: WP-Cache' );
// <-- add your Cookie-setting PHP here. Go nuts.
if ( $meta[ 'dynamic' ] ) {
include($cache_file);
} else {
readfile( $cache_file );
}
die();
Again, for some reason, this did not work for me.
Option 4—Edit your .htaccess file
Michael Kimb Jones’ post WP Cache and Cookies do not mix details getting rid of the offending .htaccess code.
Most of us though, cannot choose to ditch the .htaccess details. So, others on the Internet (I can’t find their posts now) say that simply adding the name of your cookie to the list of super cache cookies in the .htaccess file fixes the problem 95% of the time.
It looks like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Specifically at issue are the 2 lines with HTTP_COOKIE in them:
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
The theory is that if you add your cookie name to the list you should be good to go: “(comment_author_|wordpress|wp-postpass_|your-cookie-name-here)”
However, this also did not work for me.
Option 5—Set the cookie using Javascript
This is the one that worked for me.
Setting a cookie in Javascript takes place apart from Super Cache. This means that the page loads completely, the browser keeps the http_referer we want intact, then we set the cookie with that information.
To use this method:
- Write the JavaScript to get, check, and set the cookie (see examples at w3schools.com)
- Write the plugin to use the cookie in PHP
- Once the cookie is set by JavaScript you can now use PHP isset() and $_COOKIE to retrieve it for your purposes
- Use wp_enqueue_script to point to your JavaScript file
- Use add_action(‘init’,'your-function-name-here) to load your JavaScript file at initialization
Conclusions
- It takes some extra work to get cookies, http_referer, and WP Super Cache to work together, but it is possible.
- There are several possible solutions.
- My recommendation is to set the cookie using JavaScript, thereby bypassing Super Cache
I hope you found this post helpful. If so, follow me on Twitter here, or fan me on Facebook here.
Don’t hesitate to contact me if you have questions or other suggestions. You can also leave a reply below.
Aloha.
Tags: Cookies, Javascript, PHP, wordpress, WP Super Cache
Posted in Website Development | No Comments »