blog
HOME · CREATIVE · WEB · TECH · BLOG
June 4th, 2009

Clients Who Try To Cut Down The Price

One of the things I learned many years ago was that if a client balks at the price, they're a problem client. There are exceptions, of course, but some clients do this routinely - they're the ones I'm talking about. IMHO, those clients are almost never profitable.

The same can be true of clients who just can't afford you. They want a $15,000 web site for $4,000 and they think they're spending a lot and should get all the bells and whistles. Again, there are exceptions to that rule as well, but generally it's true. The exception are people who understand your value, but can't afford you, but make it clear they're really grateful that you're cutting them a deal. But they're maybe 1 in 20 people in this group.

Here's a video from YouTube that puts a funny slant on it. If you prefer, you can watch it in HD on YouTube...

In these dire economic times it's tempting to take on clients - even when they can't come close to affording you. We had to turn down an interesting project lately because we got this sorta bad vibe off it. Just be careful - you may be better turning down the work.

Digg It!  Add to del.icio.us  Add to StumbleUpon  Add to Reddit  Add to Technorati  Add to Furl  Add to Netscape

May 30th, 2009

How Can Yahoo!’s Spam Filter Be THIS Bad?

Please explain to me how it is that Yahoo! can't figure out that the following e-mail messages are spam... It boggles my mind...

Example 1:

From: Jasmine Carter <eshulsenerman55@yahoo.co.uk> (was this sent from Yahoo! mail? Wouldn't the user hve a bad history?)

Subject: PrettybtP0rn0qshotswz NkLwEcPfjuBSvtYzMh

Body: http://74ce532cee461e8c.faceplanesize.com!}TrKbR3ineUtLzxINIU PJBgeXVHxUdnRToTQMqagL

Example 2:

From: Shelby Taylor <garlettabearden94@yahoo.co.uk> (again, a yahoo.co.uk e-mail address)

Subject: -SEX-U-A-LY_EX-PL_I_C_It SPzNynCLWiTnPJyPJmvU

Body: NpZnutWnmUdgdZuJZDfUVp{)dad4479785c30468.yessoontalk.com}&bcRREwMbmEcGfdoTH NgRIcnHXqsmQIZ1T

Example 3:

From: F-r_eePodrnoMotionpictureq <karynmarshi86@yahoo.co.uk>

Subject: [ No Subject ]

Body: hzxqipfrguknzsip{http://13e0754d679f4cd1.questionexamplehouse.com}!hjgfarfbHectcGu rPwwoRWqHyVpqXyPNrcIcVG

I just don't get it. How can their spam filters miss these e-mails? It can't be that hard to write a spam filter to detect messages like these... I wonder if Yahoo! UK isn't having some sort of problem - all the e-mails appear to come from there.

Digg It!  Add to del.icio.us  Add to StumbleUpon  Add to Reddit  Add to Technorati  Add to Furl  Add to Netscape

December 4th, 2008

Changing the look of your page for mobile devices and printing

Your site may look great on screen, but have you thought about what it looks like when it's printed or what it looks like when a mobile device accesses it? Take a moment and print a page from your site - you might be surprised with what comes out of the printer.

If you have white or off-white text on a dark background chances are nothing will come out at all since many browsers don't print the background color - so you wind up printing white on white. If your design depends on things like background colors, chances are it won't look the way you want it to when it's printed. Going to a grayscale color palette may cause problems as well. Add to that that Flash areas probably won't print. And the biggest problem may be the width of your web page - not all web browsers shrink the page to fit on the piece of paper and if your page is wider than 675px you may have a serious problem.

When it comes to mobile devices there are a number of issues...

While the iPhone and some other devices can deal with full size web pages, many can't, an even for devices that can it requires a lot of zooming in and zooming out and can be a bad user experience for the customer.

Then there's the issue of the "weight" of a page. With broadband connections being pretty standard for computers these days web designers don't think about the weight of their pages, but for mobile devices it's critical - most are on super slow network connections and even ones with 3G capabilities may not be in a location that has 3G speeds.

And lastly, people on mobile devices are generally looking for different things than people who are on a computer. They're far more likely to be looking for an address or phone number than a person using a computer.

The reason why printing and mobile devices are connected is because the same two strategies are used to address both problems - 1) alternate stylesheets, and 2) alternate pages - which you use really depends on your situation and how good of a solution you want to implement for printing and mobile devices. If you can't imagine anyone ever printing a page from your web site, then you don't need to spend much time implementing a solution.

Alternate Stylesheets

When you specify a stylesheet in HTML you typically have a link tag that looks like this:

<link rel="stylesheet" href="/resources/main.css" type="text/css">

If you've done some reading you may know that there's a "media" attribute that can be added to the link tag which would change it to look something like this:

<link rel="stylesheet" href="/resources/main.css" type="text/css" media="all">
<link rel="stylesheet" href="/resources/screen.css" type="text/css" media="screen">
<link rel="stylesheet" href="/resources/print.css" type="text/css" media="print">
<link rel="stylesheet" href="/resources/mobile.css" type="text/css" media="handheld">

The media attribute is the key to what we're talking about here. In the example above styles that will be used in all circumstances are defined in main.css. Styles that will only be used on computers are defined in screen.css. Styles that are only used for printing in print.css. And lastly styles that are only used by mobile devices in mobile.css. So when displayed on a computer main.css and screen.css will be loaded and print.css and mobile.css will be ignored, and so on...

Now think about the things you might want to change depending on how it's being used... Since you can't click on a nav bar on a printed page, you may want to hide them completely with display:none when printing. Or you may want to change the width of the page from an absolute value to 100% for printing and mobile devices. Or you may eliminate things like background images for printing and mobile devices. There's a lot you can customize.

Alternate Content

While having an alternate stylesheet is a quick and easy way to customize the look and feel for printing or mobile devices and it's usually better than doing nothing at all, it's often inadequate. The issue is the HTML document you're working with. You may not be able to do everything you want to do with CSS, or the page may just be too heavy to do well on a mobile device.

Remember, the general rule is to shoot for a total page weight (including CSS and graphics) of less than 20Kb when making a page for mobile devices. Pages over that weight will be penalized by the mobile search engines.

In fact there are many factors you should take into consideration when designing a page for a mobile device. The nav bar is just one example - it should be kept simple and put at both the top and bottom of the page, and possibly interspersed in the middle of the page if the page is long. There's a lot to properly designing a page for a mobile device (including special doc types). I highly recommend you read up on the subject before you go and spend time doing it the wrong way.

To implement an alternate page for printing or for a mobile device once again you use a link tag, but this time it's not rel="stylesheet" it's rel="alternate" and will look something like this...

<link rel="alternate" media="print" type="text/html" href="/image/detail-print.htm?variantid=2983" />

To see that in action. The original page was a page on Netter Images showing an illustration of malignant tumors. The alternate page used for printing scales the image down, uses desaturated header graphics, and presents the data on the page in a less interactive manner that looks like a printed document.

One thing you should be concerned with is the issue of duplicate content. For alternate versions used for printing, you'll want to either specify nofollow in a robots meta tag, or block access to the file completely with robots.txt. With mobile versions it's more complicated because you want spiders to crawl, but want the search engine to understand which page is targeted to which audience. You can try to use robots.txt to only allow mobile spiders to see the mobile pages, but that may be more trouble than it's worth.

Other Uses

Alternate stylesheets and alternate pages are important to the visually handicapped. The same strategies we used here are used to create pages that are friendly to them - just use media="aural". CSS supports "voices" - so you can specify the type of voice you think is approrpriate for you content, etc.

Digg It!  Add to del.icio.us  Add to StumbleUpon  Add to Reddit  Add to Technorati  Add to Furl  Add to Netscape

November 20th, 2008

Use Apache’s .htaccess To Accomplish Cool And Useful Tasks

One of the reasons why Apache is such a popular web server is because it's almost infinitely expandable and flexible. There are some incredibly powerful things you can do with Apache's config settings, and .htaccess is the most common way to modify those settings.

First a little background. .htaccess is the name of the file. Yes, it starts with a dot which means on Unix based systems (like Linux and Apple's OS X) the file will be invisible. However, web authoring programs like Dreamweaver make it visible in their programs because they know it's power and importance.

You place the .htaccess file in a directory and the rules in that .htaccess file will affect that directory as well as all the subdirectories of that directory. It should be mentioned that .htaccess is a little inefficient. If you have access to your site's virtual host file, you can do pretty much the same things there more efficiently.

There are far too many things that are possible with .htaccess to discuss all of them here, so we'll just touch on some of the more common and useful things you can do.

One thing we should mention is that .htaccess is often used in combination with mod_rewrite. Apache is a modcular web application. There are probably 20-30 common modules that are used with Apache and mod_rewrite is one of them. mod_rewrite lets you do things to the URLs and based on the URLs. That may sound confusing, but it will make more sense in a moment. When you use mod_rewrite you need to have a line that reads:

RewriteEngine On

I'll be putting that in each of the examples, but when you use the code from this page you only need to have that line once in your .htaccess file - before the first mod_rewrite command.

The other thing I want to mention is that mod_rewrite is based on "regular expressions". If you really want to get into using mod_rewrite I suggest getting a book on regular expressions. You want a book that's concise and to the point since regular expresssions can get pretty complicated, but the basics are pretty straightforward.

Enforcing a canonical domain name

As you may know you can have often leave the www. out of a URL and the URL will work fine. The problem is that if you let people get to your site however they want and don't enforce either always having www or always not having www the search engines may think www and non-www are two different sites, since that's theoretically possible and was true in the early days of the world wide web. The problem with the search engines thinking you have two sites instead of one is that the authority of your site will be split and you'll have duplicate content issues. In fact the seach engine may even think one site is stealing content from the other site. The bottom line is that the search engines get confused and it's never good to get search engines confused.

The way to fix this with .htaccess is to have a statement that looks like this...

RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.slicksurface\.com$
RewriteRule ^(.*)$ http://www.slicksurface.com$1 [R=301,L]

Notice there is a RewriteCond line and a RewriteRule line. There will always be a RewriteRule line with mod_rewrite, and there can be zero or many RewriteCond lines. Think of RewriteCond as defining conditions that must be met before executing the rule.

You may know from scripting languages like Javascript that an ! means "not". Add to that the regular expression syntax ^ means "starts with" and $ means "ends with" and the first line is saying if the HTTP_HOST is NOT www.slicksurface.com. The backslashes are just there because the periods need to be escaped. And you should know (or at least guess) that HTTP_HOST is the Apache environment variable that tells you the host name of the site.

So it's going to do something if the site name is now www.slicksurface.com - that 'something' is defined in the second line. (.*) is the way in regular expressions that you grab a bunch of characters. So ^(.*)$ is saying everything from the start to the end. But realize that RewriteRule acts on only the part of the URL that's in youru directory. So if you put the .htaccess file in http://www.slicksurface.com/blog/ Then it would be working on anything that came after that in the URL.

OK, so it's grabbed everything in the URL (not including the host name) and the second part of the second line uses $1 to tack that onto the end of http://www.slicksurface.com. The third part (the portion in brackets) tells Apache that you want to do a 301 (permanent) redirect (R=301), and that RewriteRule is the last line in what you're trying to do (L).

So try it out... Click on this link and see where you go...

http://slicksurface.com/blog/

Notice it looks like www. gets added to the URL, which is basically true (in fact it wasn't "added" the user was quickly redirected to the URL with the www in it).

Page Moved Redirects

There are times when you want to move a page from one URL to another. You try to minimize doing these types of things, but sometimes they're just unavoidable. When you do need to move a page you want to put a redirect in place to let search engine spiders and people who may be following links from other sites know that the page has moved and be able to find what they're looking for.

A while back we migrated from using Blogger to using WordPress. This meant that all the URLs changed. We could write a general rule that covered many instances (see below), but some URLs didn't work with the rule. In those cases we had to have a simple RewriteRule to handle the rewrites. Here's an example of one of them...

RewriteEngine On
RewriteRule ^2007/04/4d-backup-improves-creation-of-log.html$ http://www.slicksurface.com/blog/2007-04/4d-backup-improves-creation-of-log-files [NC,R=301,L]

So, if it's in a .htaccess file in the /blog/ directory, that will take the URL http://www.slicksurface.com/blog/2007/04/4d-backup-improves-creation-of-log.html and redirects it to http://www.slicksurface.com/blog/2007-04/4d-backup-improves-creation-of-log-files - notice that I'm doing a permanent 301 redirect. And lastly, the NC means that the rule is not case sensitive.

There are few ways to do redirects with Apache, but that's how you'd do it with mod_rewrite.

Rules To Redirect Pages Based On A Pattern

When we migrated from Blogger to WordPress the directory structure went from /blog/YYYY/MM/file.htm to /blog/YYYY-MM/file - that's a pretty easy pattern to migrate and we did so with the following mod_rewrite rule:

RewriteEngine On
RewriteRule ^(\d{4})/(\d{2})/(.+)\.html$   http://www.slicksurface.com/blog/$1-$2/$3  [NC,R=301,L]

Let's look at this closely. While the regular expression code will probably be beyon your level of expertise - you can see that it's looking for something 4 and then something 2 and you'd be right if you guessed that's the 4 digit year followed by the 2 digit month. In other words (\d{4}) gets a 4 digit numeric string and (\d{2}) a 2 digit numeric string. (.+) is much like (.*) we saw above except (.+) requires that there be characters, where (.*) can work when there's nothing there. By putting those things in parentheses, we can pull them out in the URL we want to redirect to. They simply go in order $1, $2, $3...

Making The URL Different Than The File Name & Location

Rewriting the URL is the reason mod_rewrite is named what it is. Let's say you have some files on disk but you don't want their folder structure and file names to be the actual URL. An example is the MeSH medical thesaurus we put up here on slicksurface.com. It has over a hundred thousand files that needed to be organized in folders, but we didn't want those folders to be part of the URL, so we use mod_rewrite to accomplish our goal.

Let's take an example... We have the page on "Fungi" which has the following URL:

http://www.slicksurface.com/medical-thesaurus/descriptor/D005658/fungi.htm

But there's no actual document named fungi.htm in a folder named D005658. Instead the real file is at:

http://www.slicksurface.com/medical-thesaurus/descriptor/8/D005658.htm

What I did was randomize the files into 10 directories based on the last number in their ID. Then when I write files that refer to those files I add on the title of the page as a fake file name.

Here's the mod_rewrite syntax:

RewriteEngine On
RewriteRule ^descriptor/D(\d\{5})(\d)/   descriptor/$2/D$1$2.htm [L]

So what that did was serve one file when another file was requested. If you notice the virtual file name isn't used at all, so the following URL would work just as well...

http://www.slicksurface.com/medical-thesaurus/descriptor/D005658/foo.htm

Another thing you might notice is no $ was used - we just defined the beginning of the pattern and that was enough.

Having One Template Control Everything In A Directory

Another example similar to the one we just covered is having a single template control all the URLs for a directory. For example, let's say you have a file named index.php that takes a GET parameter of 'id'. The URL might look something like this if you were calling the template directly:

http://www.slicksurface.com/test/index.php?id=1234

But you don't want to have it look like that, you want the URLs to look like this:

http://www.slicksurface.com/test/1234.htm

All the numbered pages don't have to actually exist - all those URLs can be passed onto the template using something like the following:

RewriteEngine On
RewriteRule ^(.+).htm index.php?id=$1

Using a strategy like that can be very powerful and let you have one PHP template that can be thousands of URLs that are more search engine friendly than index.php?id=1234. You can do something similar with text, but it's more complicated to handle things like spaces and special characters.

Serving Pages From Other Sites As URLs On Your Site

.htaccess can be used with more than mod_rewrite. Another use is with mod_proxy. mod_proxy pulls pages from other sites and can show them as pages on your site, though there are some issues.

Let's take the following page on Dan Wong's site - it's the home page for the advanced web site design course.

http://www.dan-wong.com/advanced-web-design.htm

Here's a mod_rewrite rule that has the P parameter specifying that it's a mod_proxy situation, not a redirect.

RewriteEngine On
RewriteRule ^test/adv-3650$ http://www.dan-wong.com/advanced-web-design.htm [P,L]

With that you can see the content of the page at the following URL:

http://www.slicksurface.com/test/adv-3650

But notice that the page doesn't look right. That's because it's not being served from the correct site, so all of the links to stylesheets and images are broken. If he had started all of the references with http://wwww.dan-wong.com/... then the page would actually look correct.

When this is useful is when you have an web application server that is responsible for some, but not all of the files on your website. In that case you can proxy the web application server, pehaps through a secure firewall, and because it's part of an overall system, where the web application server may actually think it is the entire site, the pages will render correctly.

You don't have to use mod_rewrite to use mod_proxy. Here is an example of a mod_proxy statement that you might find in an .htaccess file:

ProxyPass customer/ http://127.0.0.1:8080/customer/

That will pass all of the URLs from the customer directory onto a web application server that's responding to the 8080 port on the same machine as the web site.

Excluding Directories From Being Controlled by WordPress

WordPress controls everything in the directory it's installed in. If you want to have say a resources directory that WordPress doesn't control, or a robots.txt file that WordPress doesn't control, then you can use something like this:

RewriteEngine On
RewriteCond %{REQUEST_URI} !^resources/
RewriteCond %{REQUEST_URI} !^robots.txt
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]

The bottom three lines are standard for WordPress, but the top two exclude the resources directory and the robots.txt file.

Making HTM Files Execute PHP

Sometimes you want to hide the fact that a php file is really a php file, or you just like your URLs to end with .htm rather than PHP. To make it so you can put PHP in .htm files you put the following in the .htaccess file:

AddType application/x-httpd-php .htm

Wrap Up

So there's a lot you can do with .htaccess files. Chances are if you're hitting a wall and need to do something special there's a way to do it with an htaccess file.

Digg It!  Add to del.icio.us  Add to StumbleUpon  Add to Reddit  Add to Technorati  Add to Furl  Add to Netscape

November 13th, 2008

How To Do An Outbound Link Script For Affiliate Links To Sponsors

In the last post I discussed how to do a script to randomly display banner ads on a site. The next step is how to handle the clicks on those ads (or on text ads).

You might just think you should embed the links directly in the HTML, but that's often a bad idea. Let's say your sponsor runs a special promotion that uses a special promo link code. You may have the links all throughout your site in blog posts, banner ads, sidebar text ads, etc. There will be too many things to change to take advantage of the special promotion. Having all your outbound sponsor links go through a single script will fix that problem - change things in one place and all your links are changed.

The way this works is we want to pass into a script URL the ad number (or name) that you want to display. So your URL would look something like this:

http://www.domain.com/scripts/ad-links.php?adid=1234

So ads.php is the script we'll create, and adid is the ad ID for your outbound link.

Sometimes you have to enter other parameters into the ad URLs to meet sponsor guidelines, You can do that as well with a URL that looks something like this:

http://www.domain.com/scripts/ad-links.php?adid=1234&param1=ABC&param2=XYZ

So in that case the sponsor is asking for other information that may vary depending on the context of the ad, so there are two parameters that you can pass into the script which you can insert into the code displaying the banner ad - param1 and param2.

Now, before you start it's a good idea to think about what you want to do with search engine spiders. Search engine spiders don't want to see paid links and affiliate links to sponsors definitely fall into the "paid links" category. You have two options. One is to exclude them completely using robots.txt, the other is to let them crawl the links, but send them to a different URL than a real customer would go to - send them to a relevant page on one of your own sites.

So, let's say your link is to a company that sells pop corn. The best page to send the search engine spider to would be the tag page on your blog that has all the posts about the different types of pop corn offered by the company in question. If you don't have a page like that then you could send them to the page with all the posts about their company or a page with all the different pop corn reviews you might have. The point is, keep it relevant. If you keep it relevant the search engines shouldn't say you're cloaking. If you don't have a relevant page, then 302 them to the main page of your site. The 302 redirect doesn't pass page rank, so this should be a harmless way of keeping them away from paid links without them thinking your playing page rank sculpting games to deceive them.

Now, onto the script... Here's a brief version of the script:

<?php
if (stripos($_SERVER['HTTP_USER_AGENT'], 'googlebot') > 0) { $spider = TRUE; }
elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'msnbot') > 0) { $spider = TRUE; }
elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'teoma') > 0) { $spider = TRUE; }
elseif (stripos($_SERVER['HTTP_USER_AGENT'], 'slurp') > 0) { $spider = TRUE; }
else { $spider = FALSE; }
/* Pop Corn Sponsor */
if (($_GET['adid'] == 1) && ($spider)) { header("Location:http://www.your-domain.com/tag/pop-corn-sponsor-posts",TRUE,301); }
elseif ($_GET['adid'] == 1) { header("Location:http://join.pop-corn-sponsor.com/track/ODM4NzA1NzozMzoxNQ/",TRUE,302); }
/* Pop Corn Maker Sponsor */
elseif (($_GET['adid'] == 2) && ($spider)) { header("Location:http://www.your-domain.com/
",TRUE,302); }
elseif ($_GET['adid'] == 2) { header("Location:http://
join.pop-corn-machine-sponsor.com/track/ODM4NzA1NzozMzoxNg/",TRUE,302); }
else

header("HTTP/1.0 404 Not Found");
echo "<html><head><title>Link Error</title></head><body>Link Error<br />".$_GET['lnk']."<br />".$_SERVER['HTTP_USER_AGENT']."</body></html>";
?>

You can see why we started with a discussion of search engine spiders - it's the first thing the script deals with - the first if statement tests to see if the request is coming from one of the 4 big search engine spiders. If so, it sets the $spider variable to a value of TRUE.

Then there's a if, elseif statment where we go through all the possible adid values. There are two cases for each value - one for what do do with a spider, and the other for what do do with regular users. The PHP header function is used to do 301 (permanent) and 302 (temporary) redirects. Notice that I always send people off to other sites with 302 redirects (so no PageRank is given to the sponsors site), and I also use 302 redirects when I don't have a good page on one of my sites to send spiders. 301 redirects are only used for relevant redirects for spiders so PageRank doesn't accumulate in the redirect script itself.

And lastly there's an else case for what to do if I don't find the adid. First I want to indicate that the link was not found with a 404 (page not found) response code. This makes sure the error will show up as an error in my analytics. Next, I want to tell the user what happened with some very simple HTML code.

So there you have it - an outbound link script that's easy to maintain and SEO friendly.

Digg It!  Add to del.icio.us  Add to StumbleUpon  Add to Reddit  Add to Technorati  Add to Furl  Add to Netscape

HOME · CREATIVE · WEB · TECH · BLOG