Unit of Measure PHP Class

February 16, 2010

For a recent project, we developed a php class that made it easier to work with units of measure. I was surprised that there wasn’t anything like this available out there, so we decided to open source the code once it was in a good state. That day has come.

We will be updating this code (and this blog post) over the next few days and likely down the road as well. But in the meantime, here is a link to the GitHub repository: phpUOM on GitHub.

(If this goes well, we’ll hopefully be open sourcing a bit more of our code in the future.)

Hidden 404 Errors with Wordpress Plugin Pages

August 17, 2009

After a couple hours, I’ve tracked down and fixed a bug I was having with some of our Wordpress plugins. I believe that there are a few people out there having the same problem. I think there may be another solution online, but it is one of those issues that is difficult to pare down to a good search query.

Anyway here is a solution for “404 issues with plugin pages” or “lynx shows a 404, but the page still loads”, or “Google Webtools says there is a 404, but I can get to the page”, or “setting status to 200:OK still results in 404″, or “I get a 404 in IE, but refreshing the page brings it up”, or “I get random 404 errors in IE”, or “I’m getting an HTTP/1.1 404 Not Found error but the page still loads”.

You may skip ahead to the Final Solution code, but it is probably a good idea to read everything below to make sure that you are indeed having the same issue I had… and that this will actually fix your problem.

The Context

I have some Wordpress plguins (Stranger Products, Stranger Events) that generate pages outside of the core Wordpress system (i.e. they are not “wordpress pages” in the WP DB, they are web pages generated by our plugin script). To serve these pages, I add a bunch of rules to the .htaccess file to redirect stuff like /products/1/ to a product info page.

Some gallery plugins or other plugins that generate new pages may have a similar setup/issue.

The Problem

While the mod rewrite works fine, and the page loads fine, Wordpress doesn’t find a WP page or post for the query string and so sends a “HTTP/1.1 404 File Not Found” status in the header. Most web browsers will ignore this and show the content that comes after the header. It seems that IE will sometimes choke on this status, and other times show the page. Funny IE!

Google’s crawler however will not crawl that page and will let you know in a web toolkit report. Also, I noticed that the lynx command line browser for Linux would show the 404 error and then load the page.

The big issue here is that Google is not going to crawl our page.

The Fix

I spent a lot of time tracking down where in the Wordpress code the 404 status is set. Ideally, there would be a plugin “hook” near this that we could use to prevent the 404 status from reaching the browser.

The function that makes the 404 decision is handle_404(), which can be found in the /wp-includes/classes.php file. Here is the code (for Wordpress 2.8.4, similar for previous versions I looked at too):

459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
function handle_404() {
	global $wp_query;
	if ( (0 == count($wp_query->posts)) && !is_404() && !is_search() && ( $this->did_permalink || (!empty($_SERVER['QUERY_STRING']) && (false === strpos($_SERVER['REQUEST_URI'], '?'))) ) ) {
		// Don't 404 for these queries if they matched an object.
		if ( ( is_tag() || is_category() || is_author() ) && $wp_query->get_queried_object() ) {
			if ( !is_404() )
				status_header( 200 );
			return;
		}
		$wp_query->set_404();
		status_header( 404 );
		nocache_headers();
	} elseif ( !is_404() ) {
		status_header( 200 );
	}
}

This would be the ideal place to say, “Hey, don’t 404 this page”, but there is no hook in here. I tried setting the $wp->did_permalink flag to FALSE, which worked sometimes, but sometimes Wordpress would write that back to TRUE after I reset it. And I’m not even sure what that flag is doing; so playing with it might cause some bugs elsewhere.

The next place to check is the status_header() function called by handle_404. This function is found in the /wp-includes/functions.php file. Here is the code:

1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
function status_header( $header ) {
	$text = get_status_header_desc( $header );
 
	if ( empty( $text ) )
		return false;
 
	$protocol = $_SERVER["SERVER_PROTOCOL"];
	if ( 'HTTP/1.1' != $protocol && 'HTTP/1.0' != $protocol )
		$protocol = 'HTTP/1.0';
	$status_header = "$protocol $header $text";
	if ( function_exists( 'apply_filters' ) )
		$status_header = apply_filters( 'status_header', $status_header, $header, $text, $protocol );
 
	return @header( $status_header, true, $header );
}

Tada! This function uses the “status_header” hook/filter before updating the header. So we can create a function in our plugin to check the status for a 404 and then return false/NULL if we know that there really is a page to load. Here’s how I did it.


The Final Solution

In PHP code for my pages, I created a global variable called $isapage and set it to true. So at the very top of any page that is giving the 404 errors, add this code:

global $isapage;
$isapage = true;

Now I add the following function and filter to my plugin code:

//this function checks if we have set the $isapage variable, and if so prevents WP from sending a 404
function ssp_status_filter($s)
{
	global $isapage;
	if($isapage && strpos($s, "404"))
		return false;	//don't send the 404
	else
		return $s;
}
add_filter('status_header', 'ssp_status_filter');

I hope this helps some people out there.

Feel free to critique this solution. Let me know if I missed something or if there are better ways to do this.

Feel free to post related issues. I may have found solutions to those along the way… or maybe a commenter can help you out.

Editing the StudioPress Lifestyle Theme

June 24, 2009

A client contracted us to make some updates to the StudioPress Lifestyle Wordpress theme. I’m documenting the changes here so our client can possibly do this work themselves in the future, and it may also help others out there looking to tweak the StudioPress (or really any) premium theme.

Changing the Menu Colors

Changing the color scheme involves updating the style.css stylsheet and creating new versions of various images. I did a rough mockup of the color changes in Photoshop, and then went to work on the images.

To change the header and headline elements from blue to orange, I did the following steps to these files:  header.png, header_blank.png, logo_blank.png, headline.png, and topnav.png.

  1. Open the image in Photoshop.
  2. Goto Image –> Mode –> RGB Color to change the mode.
  3. Create a new layer on top of the background.
  4. Use the paint can tool to fill the new layer with your new color.
  5. Change the layer type from “Normal” to “Color”.
  6. (optional) If the brightness of the image is off now, create a new layer filled with the new color and change the layer type to “Luminosity”.
  7. Save the image for web as a PNG 24.

To change the background color of the higlighted/active submenu item, I changed the background color of line 381 (the “#subnav li a:hover, #subnav li:active” declaration).

You can also edit the navbar.png and navhov.png files to change the main menu.

Changing the Header

To change the logo from an image to plaintext, in the WP admin goto Appearance –> Lifestyle Theme Options and change the Header Blog Title setting from “Image” to “Text”.

You can also edit the file in the /images/psds folder to use an Image logo in the header.

Changing the Body/Page Background Colors

I used the Firebug plugin for Firefox to inspect the original website to find out where certain colors and styles were set in the style.css file.

Using Firebug, I learned that the body’s background color is set on line 19. I changed this color from #E2DDCB to #1462A6.

You could also do a search and replace, but this color was only used in one spot in the style.css file.

Moving inward from the background, the next band of color is actually the border of the “wrap” element. I changed the color of the border declaration on line 35 to #6595BF.

Changing Link and Text Colors

The hyperlink colors are declared between lines 40 and 60.  The lifestyle theme uses the same color for links and visited links. I wanted a different visited color, so I changed that section of code to look like this:

a {
color: #1462A6;
text-decoration: none;
}

a:visited {
color: #6595BF;
}

a:hover {
color: #6595BF;
text-decoration: underline;
}

a img {
border: none;
}

a:focus, a:hover, a:active {
outline: none;
}

To change the article heading link colors, search for “#content h1 a, #content h1 a:visited” and “#content h1 a:hover”. (I changed the colors around lines 586 and 595.)

Hiding the Post Meta (“by”, “posted on”, “filed under”, “tags”, etc)

I hid these using CSS. I added a “display: none;” line to the .date  declarations in style.css on line 779. To hide the tags (postmeta2) section, I add these lines under the .postmeta2 declaration around line 841:

.postmeta p,  .postmeta2 p {
display: none;
}

This will hide everything inside the postmeta2 section, but will still show the bottom border and bottom margin.

Changing the Sidebar

I removed the Blog Roll and Admin sections by commenting out lines 9 through 25 of the sidebar_right.php file in the theme directory.

I then added the following widgets:

  • I added a “text” widget to “Sidebar Top” with some Google Adsense code for a 300×250 ad.
  • I added a “text” widget to “Sidebar Top” with the title “Featured Video” and some embed code from YouTube. (Note: it didn’t seem to matter that the YouTube embed width was greater than 300 pixels. YouTube must size it to fit the page.)
  • I added a “recent posts” widget to “Sidebar Top” with the default settings.
  • I added a “text” widget to “Sidebar Bottom Right” with the title “Advertisement” and some code for a custom 120px x 600px ad.

Updating the Homepage

The first thing we need to do is enable the home.php file as a template for our pages. We need to change this line in home.php:

<?php get_header();  ?>

to:

<?php
/*
Template Name: Homepage
*/
get_header();
?>

Save and upload the file. Now edit the “Home” page in WP and choose “Homepage” as the page template. Save the page.

To choose which blog categories are used for the featured content areas, in WP Admin goto Appearance –> Lifestyle Theme Options. Change the appropriate settings.

To get thumbnails to show up in the featured sections, add a custom field called “thumbnail” pointing to an image (70×70 pixels is good) to use. You can upload these images to the post first and then copy the src url.

To set the thumbnails for the last (bottom) featured section, use “hpbottom” as the name of the custom field.

Setting up the Featured Gallery (Fading Script)

The first step here is to install the “featured content gallery” plugin. (It wasn’t included with my install, but it’s a freely available plugin.) In the WP Admin goto Plugins –> Add New. Search for “featured content gallery”. Install the plugin. Activate the plugin.

Now goto Settings –> Featured Content Gallery and choose either the category or page/post IDs to use for the gallery. You must also set a height and width and text area height in the next section (I used 588 width, 400 height, 100 height for the text). I left the colors as default. Update the settings.

The last thing you need to do is make sure you upload a picture (mine were 588×400) and set a custom field called “articleimg” that points to the URL of the image you want to show up. The gallery will not show up unless you set this custom field.

Testing a Plugin

February 24, 2009

Just testing a plugin. Ignore this.

Introducing TopWhatever

February 5, 2009

TopWhateverA new product from Stranger Studios. TopWhatever will change your life. From the about page:

TopWhatever helps you make decisions by walking you through the process of creating a “decision matrix”. Using the matrix, you can weigh your options against the criteria that are important to you.

Some decisions can get complicated quickly. The decisions you end up making can feel subjective rather than objective. TopWhatever helps you take things step by step. You end up with a decision that is sound, with the math to prove it.

The best way to understand how TopWhatever works is to view decisions that have already been made.

So check it out already. Use TopWhatever to make a decision that has been on your mind lately.

Reported Questions on Interactive 8Ball Now Going into Oblivion

April 7, 2008

We used to have an option on the Interactive 8Ball search page to “show reported questions”. We recently received an email from someone who objected to some of the questions submitted and didn’t like that the questions he reported were still available. Upon further reflection, we also decided that it doesn’t make sense for the reported questions to still be available on the site.

And so, without addressing the issue that people are still going to be mean on the site (which we’ve discussed before), we are no longer showing reported items on the site anywhere.

Here’s the email we received:

I think your interactive 8-ball “game” encourages stupid and crude behavior.

By googling my son’s name, the interctive 8-ball site came up. I have never heard of this site before.
I found references on the site to my son and other students from his school which are offensive, crude, and hurtful. I “reported” them as offensive and I reported them to the school. I want them removed from the site, and thought that they were removed by the act of reporting. However, I see that you can access them by clicking on ’see reported questions’. They are also available in the “cached” items on the google site.

I find this very disturbing. He had nothing to do with these words appearing here and does not even know of their existence.

Please tell me what you can do about this. I want all questions or answers with his name removed. Can you do this? I am certain the are him because of the other names of students in his classes also being present.

Please respond.
_____ ______________

… and my response …

Mr. _________,

Thank you for contacting us about this. Before launching the site, we never understood how base and downright mean people who use Interactive 8Ball. It quickly became apparent though that most people who use the site use it to hide behind the anonymity and write hurtful things about other people.

Still the site can be fun for some… enlightening for others, and we’ve kept it online.

However, due to your email, we’ve re-evaluated our reporting system and agree that reported items should be removed forever. All of the question/answer pairs you reported will no longer be accessible on the site.

Please know that we have no control over Google’s indexing or caching, and so cannot immediately remove the content from Google’s site. However, they keep their index and cache fairly current, and after about a month or so our pages which were indexed there should disappear.

Regards,

Jason Coleman
Stranger Studios, Interactive 8Ball

Play the Interactive 8Ball now and see what all the fuss is about.

I’m on UStream RIGHT NOW At Bryn Mawr College

March 19, 2008

I’m speaking on a panel that will hopefully help some Bryn Mawr and Haverford students get jobs after college. You can see me 7pm EST on 3/18/2008 at this link:

 http://www.haverford.edu/cdo/opportunities/events/

Web Hosting

October 9, 2007

Over the past year, we’ve helped launch over 20 new or refurbished websites. We’ve used just two hosting companies to host the majority of those sites.

1and1
We use 1and1 to purchase and manage all of our domains. At just ~$7 per year, it’s hard to beat. We also use 1and1’s Linux Business package to host the Stranger Studios website and a number of smaller internal websites. For just $9.99 per month, you get 250GB of storage space, 2500GB of bandwidth, and the ability to host up to 100 domains. If you don’t understand those numbers, just know that it is much more than need.

1and1 has great uptime. They offer both MS and Linux packages, including everything up to dedicated servers. In our experience, the packages below “business” level suffer from some performance issues, as there are a large number of websites running on the same server. However, the business packages have been great for sites of our that receive fewer than 1000 visitors per day. For sites that require greater performance or more flexibility, we suggest…

Update: Myriad Network is no more. At least not the Myriad we knew and loved. Seems that they’ve been sold to EMC Telecommunications (though they are not admitting). Ever since, we’ve had nothing but problems. I’m currently looking for new VPS/Dedicated hosting.

Myriad Network
WineLog.net is hosting on a Myriad Network Virtual Dedicated Server. People moving from a regular shared server to a VDS will notice a huge difference in performance. Another reason to look into VDS options is if your application requires databases larger than 100MB (1and1 and other shared hosts limit on MySQL DBs). Our Mobilicio.us application with hundreds of thousands of rows of data zings on a new Myriad Network server. And Myriad makes it easy to scale to multiple servers or larger dedicated servers.

When moving to a VDS, you’re going to have to do a lot more of the nitty gritty at the server level. For our clients, we handle all the nonsense. But even we get confused sometime with some of the more subtle aspects of running a server. In these cases, the Myriad support has been nothing but great with us. They are always timely in their responses and very helpful.

And, yes, those are affiliate links above. For over a year now, we’ve been referring clients and friends to both of these hosting companies without using affiliate links. A little bit of math showed us that we were leaving some money on the table here. Not a lot of money, but maybe enough for a trip to Vegas. So we appreciate your support by using the links above to sign up for these great companies. We wouldn’t recommend them unless we thought they were the best. And they are.

We’ve been busy rolling out new websites!

September 9, 2007

Stranger Studios has recently launched several great new websites. Check them out!

ComiteSkin.com
Philadelphia-area Dermatologist, Harriet Comite, came to us for a total revamp of her growing practice’s (Advanced Skin Care) existing website. The site is balanced in its appeal to masculine and feminine audiences and conveys loads and loads of information in an easy-to-digest format.
Learn more about this project »

Garrett-Olsen.com
Up-and-coming Kart racer Garrett Olsen needed a web home-base for his growing stardom. The site is built on the Wordpress CMS to allow easy updating by the client and his web team. The site is also enhanced by the use of third party sites like Viddler and YouTube, and Flickr.
Learn more about this project »

LuxuryBabyBlog.com
A blog for hip parents to keep track of all that’s cool and “luxurious” for their growing families. The project includes our proprietary mailing list application (that we will hopefully make available as a Wordpress plugin shortly), as well as integration with Feedburner for email delivery of blog updates.
Learn more about this project »

VanessaPeanFoundation.org
Stranger Studios has a heart! We helped develop a web presence for the Vanessa Péan Foundation to serve as a hub for all of the foundation’s many meaningful efforts.
Learn more about this project »

Interactive 8-Ball Facebook App

June 28, 2007

So we’ve jumped on the Facebook bandwagon a bit. You can now install the Interactive 8-Ball application to your Facebook profile.

Why would you want to install I8B on your Facebook profile?
I don’t know, but if you use Facebook as your homepage instead of iGoogle it’s nice to have I8B right there. We also update your profile and mini feed every time you ask a question through Facebook. Although this last bit can get tricky; we had a lady email us to take down a question she asked about a love prospect for fear of being had. (Which only gave us another idea for a Facebook app that we might share at some point.)

And What Happened?
I8B got a ton of traffic. In three days, we got 400 people to install the new application. Traffic to I8B trippled to 800 visits a day and then… leveled out. We actually lost 5-10 users today as people have started to uninstall the application. So growth is not exactly parabolic so far.

I guess we need something more to help the spread. (This blog post? A mention at TechCrunch? Maybe I’ll resubmit I8B to Emily Chang’s eHub.) It would be nice to have the 20,000 users that the other lame-o eight ball application on there has. Of course they got there first and so are high in the app directory and have the catchy URL at apps.facebook.com/eightball. (ours is apps.facebook.com/bettereightball) ;)

What’s next?
A WineLog app for Facebook, duh. The I8B stuff was kind of a primer for work on a WineLog application. And good thing too. It is nice to work out all of the kinks using a brand that we aren’t as invested in. This article helped me a bunch, but it also took a lot of hacking around to figure out what he meant by everything. The toughest part was fixing Facebook’s broken PHP4 client. Don’t even try messing with that unofficial one. If anyone needs help, shoot me an email or IM.

Anyway, a WineLog app would be fun. Again, I would rather just go to WineLog to see what my friends are drinking. But if you spend your day at Facebook, it’s sweet to get notifications on what people are logging. And it will hopefully introduce WineLog to some new folks. Cross your fingers.

UPDATE: Here are links to my versions of the facebook api scripts. Download them and rename them to .php. I hope to comment up the code when I get a chance, so you can see what I changed. But in the meantime, this might be a better starting place for you than Facebook’s version.

facebook.php
facebookapi_php4_restlib.php
IsterXmlSimpleXMLImpl.php

Download all of the above files, rename them to .php, and follow the tutorial instructions here (or do whatever you’re doing). The strange one at the bottom is a library to handle XML objects (PHP5 does this natively I suppose). Read here for more on simplexml44. Or here is the entire simplexml gzip file as I unzipped and installed it on my server.