Archive for July, 2010

Importance of using 301 redirects

Tuesday, July 6th, 2010

You, my friend, must stretch the boundaries of your imagination and put yourself in the shoes of a web developer. You have been contracted to redesign Bob “The Sniper” Houlihan’s surprisingly popular History of Shoelaces site. During this process, you’re revamping his page titles, URLs, and overall site structure. Bob doesn’t want to lose his current place in search engine rankings in exchange for the long term success and usability improvements that you promise.

Fast forward a couple months and the site is ready to go live. You have the name server repointed to the new location. Everything works great… but you’re not done. It’s time for 301 redirects. 301s just tell the browser that what you’re looking for isn’t here, but it has moved to this other specified location. If you’re on Apache and able to use an .htaccess file, this is what a 301 redirect will look like:

redirect 301 /Before_Shoes.html http://www.thehistoryofshoelaces.biz/before-shoes

This tells the server that if Before_Shoes.html is requested by the browser, send them to http://www.thehistoryofshoelaces.biz/before-shoes instead. The most obvious reason to do this is so your site doesn’t serve up a 404 error. The user could possibly think that the site is down permanently. Any pages that are renamed, relocated, or content that is moved needs to be taken into consideration when creating 301s.

But, it’s not only people using the internet. There are also bots used by search engines. The 301 part speaks to them directly, saying this page has been permanently moved (not temporarily, that’s important and covered later). This helps new/moved pages to be indexed more quickly, get those old URLs replaced in the index, and maintain your page rank within the search engine.

But why 301 of all numbers? That, my friend, relates to the ubiquitous but little understood HTTP. Part of HTTP’s job is to serve up status codes when responding to a request which can be as simple as typing in a web address in your browser. Part of this response is the status code. Each status code is a three-digit number beginning with any number from 1 to 5 with 1 representing Informational responses, 2 a success, 3 redirection, 4 a client error, and 5 a server error. You’ve probably seen “500 Internal Server Error” or “404 Not Found.” You probably haven’t seen a 302 code which is a temporary redirect telling bots that the page will likely reappear at a later date. 301 redirects do not provide this likelihood. Go here [link to complete list] for a complete list.

Preparation for programming websites

Tuesday, July 6th, 2010

The programming phase of website development is usually the longest one. Before putting that design into code form, I suggest several preparations.

Know what you need

Knowing what you’ll need is important because it will help in mapping out the time frame. Of course, you’ll have HTML and CSS to work on, but you’ll probably have some dynamic portions of the site as well. Will you have to use Javascript or PHP? Almost undoubtedly. What about Flash and Flash components? What about widgets, APIs, and other tools?  Once you know what you need, you can begin to see what portions of the project will take more time than others, whether that’s research or programming.

Figure out your divs

Now it’s time to figure out your div tags. Looking at your potential site, you probably have several different page designs. Of course, each of these page designs will have a different coding structure. Repeatable code is the coders best friend. You can spend less time tweaking margins and padding and more time tackling the actual layout. Also, a consistent and clear naming convention is important, not only for you but also for anyone who looks at your code later. The most popular high level div naming convention seems to go wrapper > container > content. But, use what works for you while making it as understandable as possible.

Figure out your CSS

Using the divs discussion as a jumping-off point, many of the same rules apply to CSS programming. Clear and consistent names are important, and this is where your planning reveals its effectiveness. Your site-wide, high-level styles should not apply to just one page. If that has happened, planning has not been adequate. If your adding classes to each paragraph tag, for instance, you decided on the wrong highest level style for your paragraphs. It’s time-consuming and sloppy to tack a class onto any element that doesn’t fit the design or your preference. Plan your styles out beforehand. Sometimes this means making a “bold” class. Sometimes this means making a high-level item bold and removing the “boldness” on a per element basis. The latter option is only applicable if most elements of that kind are bold on most pages, and you only need to remove the bold attribute a few times.

CSS page organization is your preference, but make sure you have one. It makes finding and editing your styles later much easier. You can have your main, site-wide styles at the top, then separated according to webpage as you work on each one. Many people separate typography, forms, headers, and other elements by their aforementioned category. It’s up to you. This may go without saying, but label each section with a commented header. You can make it as decorative as you desire, maybe an ASCI flower is your style.

Programming for different browsers (warning: could get technical)

Just wanted to mention this quickly, you will have widely divergent looks in many web browsers (usually Internet Explorer). I try to blend preparation and procrastination for these bugs or inconsistencies. Certain bugs can be foreseen, and some of those are worth preparing for such as a div’s tendency to flatten if it contains floated elements or IE6′s inability to understand the hover pseudo element outside of a tags. Basically, if it’s not going to distract you from your main goal of a workable website in as timely a fashion as possible, a short detour to circumvent a later time commitment to fixing a bug is not a bad idea.

Multiple loops on one page in the same category

Tuesday, July 6th, 2010


Objective: Display two sets of data on one page both of which will be from the same category.

We are using Flutter for this example. Flutter uses write panels to create posts. Whenever a post is added through a write panel, it is automatically placed in a specific category. Within this category are two types of posts, one is an ongoing opportunity; the other type has an expiration date. For the first type, we can do a database query checking whether one piece of information exists or not. These days when you’re using WordPress and you want to access database information while in the Loop[codex link], you use the query_posts function [link to codex].  When you add the Flutter to the mix, you have new host of parameters to add to query_posts.

Recently (a couple versions ago), WordPress added new parameters related to meta values or custom fields. So, you can access Flutter custom fields through these meta values. These parameters are all we need for the first set of data that displays ongoing opportunities. However, you can only access one key/value [link to PHP Array page] pair at a time. That throws a small wrench into things later. For now, this is all we need:

<code>
<?php
$thequery = “meta_key=ONGOING-OPPORTUNITY&meta_value=true”;
$pageposts1 = query_posts($thequery);
?>
</code>

In the backend under the Flutter write panel we are accessing, is a checkbox labeled “ONGOING-OPPORTUNITY.” That is the key of our key/value pair. We are simply determining whether it is checked or not i.e. true or false.

I’ll explain why we use the variable $pageposts1 later. To display our recently queried data, do this:

<code>
<?php
foreach($pageposts1 as $post):
?>
<tr>
<td><a href=”<?php the_permalink() ?>” title=”<?php the_title_attribute(); ?>”><?php the_title(); ?></a></td>
</tr>
<?php endforeach; ?>
</code>

Troubleshooting Tip: Echo the query which should give you SQL code. Use the SQL option in your database to run the query to see if anything is returned.

Now for the more complicated part. We are going to overwrite the previous query so that it does not interfere with our work going forward. We want to exclude the previous posts (so unchecked ONGOING-OPPORTUNITY) and include all those with expiration dates that are yet to have passed. Here’s what we have:

<code>
<?php
$thequery = “meta_key=ONGOING-OPPORTUNITY&meta_value=false&customorderby=x_OPPORTUNITY-EXPIRES&order=ASC”;
$pageposts2 = query_posts($thequery);
?>
</code>

Here you see that ONGOING-OPPORTUNITY is false, but we have also added a Flutter-only parameter “customorderby=x.” We are custom ordering by another Flutter field called OPPORTUNITY-EXPIRES. This is a date field. Remember that. The order parameter set to “ASC” merely makes upcoming dates to appear at the top before dates further down the road.

The next step is preparation for displaying the content.
<code>
<?php
$fd = 0;
foreach($pageposts2 as $post):
$expire_date = get(‘OPPORTUNITY-EXPIRES’);
if( (date(‘Ymd’, strtotime($expire_date))) >= (date(‘Ymd’)) ) {
$fd++;
?>
</code>

Lots to look at here. I’ll explain the variable $fd while I’m explaining $pageposts1. $expire_date uses a Flutter function to “get” the value in the OPPORTUNITY-EXPIRES field. The next line begins an if statement that first converts $expire_date to a manageable format then compares it to today’s date. So, if the expiration date of the post is greater than or equal to today’s date, it will be displayed (e.g. 20100408 [April 8, 2010] is greater than 20100301 [March 1, 2010]). We now just need to show our results and put our date back into a readable format.

<code>
<tr>
<td align=”left” valign=”top”><a href=”<?php the_permalink() ?>” title=”<?php the_title_attribute(); ?>”><?php the_title(); ?></a></td>
<td align=”left” valign=”top”><?php echo date(‘n/j/Y’, strtotime($expire_date)); ?></td>
<?php } endforeach; ?>
</code>

And there it is. We have one more contingency to account for, and that is empty queries. Here’s where $pageposts1 and $fd come into play.

<code>
<?php
if(($pageposts1 == 0) && ($fd== 0)) { echo ‘<p>No current funding opportunities were found.</p>’; }
?>
</code>

$pageposts1 is a count of the first query; $fd is a count of the second. They are counted differently because the second query has to have the expiration date compared to today’s date. So $fd, instead of counting every post retrieved by the query, only counts those that will be displayed based on the aforementioned dates.

And that’s all there is to it. Here’s the full code:
<code>
<?php
$thequery = “meta_key=ONGOING-OPPORTUNITY&meta_value=true”;
$pageposts1 = query_posts($thequery);

foreach($pageposts1 as $post):
?>
<tr>
<td><a href=”<?php the_permalink() ?>” title=”<?php the_title_attribute(); ?>”><?php the_title(); ?></a></td>
</tr>
<?php
endforeach;

$thequery = “meta_key=ONGOING-OPPORTUNITY&meta_value=false&customorderby=x_OPPORTUNITY-EXPIRES&order=ASC”;
$pageposts2 = query_posts($thequery);

$fd = 0;
foreach($pageposts2 as $post):
$expire_date = get(‘OPPORTUNITY-EXPIRES’);
if( (date(‘Ymd’, strtotime($expire_date))) >= (date(‘Ymd’)) ) {
$fd++;
?>
<tr>
<td align=”left” valign=”top”><a href=”<?php the_permalink() ?>” title=”<?php the_title_attribute(); ?>”><?php the_title(); ?></a></td>
<td align=”left” valign=”top”><?php echo date(‘n/j/Y’, strtotime($expire_date)); ?></td>
<?php
} //end if
endforeach;

if(($pageposts1 == 0) && ($fd== 0)) { echo ‘<p>No current funding opportunities were found.</p>’; }
?>
</code>