Archive for the ‘Web Development’ Category

jQuery Degradable Popups

Monday, January 28th, 2008
Posted in Web Development · Tags: ,

Do you want to have image preview popups, but want the links to still work if JavaScript is disabled? The following just changes the href value of the link by inserting the URL it was pointing to into a JavaScript function call.

function pu_preview(url)
{
var width = 760;
var height = 360;
var win_left = (screen.width-width)/2;
var win_top = (screen.height-height)/2;
new_window = window.open(url,'video_player_popup','width='+width+',height='+height+',top='+win_top+',left='+win_left+',toolbar=no,directories=no,status=no,scrollbars=yes,resizable=yes');
if (window.focus)
{
new_window.focus()
}
}
$(document).ready(function(){
$("#gallery a").attr("href", function() { return "javascript:pu_preview('"+this.href+"');" });
});

Here is what your HTML might look like

<a href="http://example.com/images/image.jpg"><img src="http://example.com/images/image_thumb.jpg" alt="" /></a>

Stop Using Email Addresses for Validation

Monday, January 21st, 2008
Posted in Web Development · Tags:

I still see a lot of forms require email address to post comments or for simple verification. It doesn’t stop spam at all.

You should only ask for a person’s email address if:

  • You require registration to access part of the site.
  • They have a password and will need to be able to reset it.
  • You will have an option to notify them of new comments or a response to their comment.
  • It’s an email form (then you need it, because how else will you respond).
  • It’s for a newsletter.
  • It’s an online purchase.

I’m probably forgetting a few other instances where its needed, but I think you get the idea. Using a email address to send a user a link to click on to verify it is inconvenient as well. You might as well just have them register and send them a initial verification link.

I understand spam is out of hand, but I’ve written an email form awhile back that gets very little.

Here are some things I do to prevent spam:

  • Filter HTML.
  • Filter any unsafe characters.
  • Prevent blank fields not only with JavaScript but on server side also.
  • Check field lengths not only with JavaScript but on server side also, don’t let them try to send a longer text than what your form is set to, this should be a red flag that they are trying to do something fishy. You can trim whitespace characters with JavaScript.
  • Look for any attempts of e-mail injection. Often times spammers try to trick your email form to spam others by putting in CC:, Content-Type:, To: and so on.
  • If its a email form and the email address is required, make sure the email address is in a valid syntax. Also make sure the domain part of the email address is one that really exists (PHP can do this).
  • Check the email address thats supposedly sending it and see if it is on my ban list.
  • Check the ip address thats supposedly sending it and see if it is on my ban list.
  • Check the words in the title and subject and see if they are on my censor list. Censored words will be let through but will be filled with asterisks.
  • Check the words in the title and subject and see if they are on my ban list. Bots are dumb and sometimes will send UBB code like [url=http://example.com]my nasty site[/url] because they thought the form was part of a forum. Just makes it easier for me to filter.
  • I like to filter out @ with (a) and replace any http://, https://, http://www. or https://www. with LINK: because often email clients will render these as links and I don’t want to accidentally click on them.
  • Count how many links are being sent and compare it to my limit. Some spam bots go insane and try to send 50 links per email.
  • Compare what domain the form was referred from with my allowed list, helps prevent cross-site scripting. For example, if your form on http://example.com/email.php sends data to http://example.com/processor.php, it should only allow http://example.com and http://www.example.com to do that. You could add more subdomains if you want to. I’ve seen server logs coming form some pretty nasty sites and the pages with forms get the most hits, so I know what they are doing.
  • Check the token, helps prevent cross-site scripting. Chris Shiflett has a good tutorial on this. It’s in PHP but you can use the principles for any language.
  • I usually ban the emails from the domain the form is on. For example, if your domain is example.com, a lot of bots will simply just fill out the email form as bob123@example.com because they assume you would never ban your own domain.
  • Check the timestamp, any forms that are older than X minutes wont be sent.
  • See if the same email address or IP address sent an email recently (flood protection).

I also log things at the end of my email, so I can monitor what is going on, incase I get a spammer that is getting through. Often I can see what pattern they follow, such as using the same IP address, email address, words, etc. and I can modify my filters accordingly.

JavaScript Image Slideshow Galleries Like Lightbox

Sunday, August 12th, 2007
Posted in Web Development · Tags: ,

Recently I’ve been wanting to use something like Lightbox but without all the bloated code. Prototype (a JavaScript framework) and script.aculo.us (interface library for Prototype) can be quite big, or at least bigger than I like my scripts to be. Of course thats why I prefer jQuery, but I recently read about mootools which lets you pick and choose what you need and will compress it before you download it. However, I’m not sure if mootools is as easy to write scripts with as jQuery is, but I figured I’d just throw that alternative out there.

Anyway back to the list of scripts that will work like Lightbox

  • Lightbox - the original (requires Prototype and script.aculo.us)
  • Lightbox 2 - even prettier than the original (requires Prototype and script.aculo.us)
  • Lightbox Plus - like Lightbox 2 but will resize the image to fit the window
  • Lightbox++ - based on Lightbox 2 but supports Flash, was once known as SWFBox (requires Prototype and script.aculo.us)
  • Slimbox - visual clone of Lightbox 2 but much smaller (requires mootools)
  • Thickbox - not as pretty as Lightbox 2 but it supports images, IFRAME, Flash, PDFs and more. It will also resize the image to fit the window (requires jQuery)
  • Suckerfish HoverLightbox Redux - based on several other well known effects
  • ModalBox - it will also create modal dialogs or even wizards
  • LightWindow - supports images, IFRAME, Flash, PDFs (requires Prototype and script.aculo.us)
  • sLightbox a SmoothGallery extension (requires mootools)
  • GreyBox - yet another image gallery
  • Litebox - uses moo.fx and prototype.lite
  • FancyZoom - Nice Mac looking zoom effect
  • iBox - It automatically scales the image to the size of the browser’s viewing pane if it’s too big (Thickbox does that also). The JavaScript is 19kb and it uses target attribute for a CSS popup if JavaScript is disabled.

There are probably about 20 other variations of Lightbox and Lightbox 2, other homegrown versions and even some commercial versions, but I think this list is the best of the best (plus many of them are up to date and in constant development). Slimbox, Thickbox and Litebox are the lightweights in the list.

Added Litebox
Added FancyZoom
Added iBox

CSS Class Based on Date

Wednesday, August 1st, 2007
Posted in Web Development · Tags: , , ,

I recently saw a tutorial on SimplePie’s site about using relative dates and I modified the function to output a CSS class rather than text. That way you can make newer stories bold, brighter, or bigger and older stories dimmed out or smaller. Use your imagination with CSS. :)

Here is the function

//CREATE CSS BASED ON DATE
function create_age_css_class($date_sent)
{
/**
$date_sent should be in the following format: YYYYMMDDHHMMSS
Based on doRelativeDate() By Garrett Murray, http://graveyard.maniacalrage.net/etc/relative/
**/
$in_seconds = strtotime(substr($date_sent,0,8).' '.
substr($date_sent,8,2).':'.
substr($date_sent,10,2).':'.
substr($date_sent,12,2));
$diff = time()-$in_seconds;
if ($diff < 86400)
$css_class = 'age_today';
else if ($diff < 604800)
$css_class = 'age_days';
else if ($diff < 1209600)
$css_class = 'age_week';
else if ($diff < 2630880)
$css_class = 'age_weeks';
else
$css_class = 'age_month';
return $css_class;
}

Here is how I call it

$data .= '<li><a href="'. $item->get_permalink();
//SET CLASS BASED ON DATE/AGE
$data .= ' class="' . create_age_css_class($item->get_date('YmdHis')) . '"';
$data .= '>';

You don’t have to use SimplePie for this function, but it’s what inspired me to modify it.

Now for an screenshot

Here is the HTML I used for that

<ul id="type3">
<li class="age_today">Lorem ipsum dolor sit amet</li>
<li class="age_days">Etiam iaculis nulla iaculis mauris</li>
<li class="age_week">Suspendisse at odio</li>
<li class="age_week">Nullam volutpat aliquam lacus</li>
<li class="age_weeks">Nunc dapibus eros vitae mauris rutrum laoreet</li>
<li class="age_weeks">Suspendisse sed nisl</li>
<li class="age_month">Nulla scelerisque gravida neque</li>
<li class="age_month">Leo imperdiet metus, ut adipiscing nisi lacus et pede</li>
</ul>

And here is the CSS used

<style type="text/css">
body {font-family:Verdana, Arial, Helvetica, sans-serif; color:#000; background-color:#fff;}
ul {list-style:none;}
#type3 .age_days {font-size:150%; color:#555;}
#type3 .age_week {font-size:100%; color:#777;}
#type3 .age_weeks {font-size:80%; color:#999;}
#type3 .age_month {font-size:60%; color:#ccc;}
</style>

Added screenshot and sample CSS

SimplePie and Digg’s RSS Feeds

Thursday, July 26th, 2007
Posted in Web Development · Tags: , ,

Been playing with SimplePie some more and here is some code for dealing with Digg’s RSS feed. I included some stuff in comments that just shows how their namespaces look.


/*
<digg:diggCount>95</digg:diggCount>
<digg:submitter>
<digg:username>kilooneniner</digg:username>
<digg:userimage>http://digg.com/userimages/k/i/l/kilooneniner/medium9515.jpg</digg:userimage>
</digg:submitter>
<digg:category>Political News</digg:category>
<digg:commentCount>9</digg:commentCount>
*/
//DIGG NAMESPACES
$digg_count = $item->get_item_tags('http://digg.com/docs/diggrss/', 'diggCount');
$digg_comments = $item->get_item_tags('http://digg.com/docs/diggrss/', 'commentCount');
$digg_category = $item->get_item_tags('http://digg.com/docs/diggrss/', 'category');
$digg_submitter = $item->get_item_tags('http://digg.com/docs/diggrss/', 'submitter');
$digg_username = $digg_submitter[0]['child']['http://digg.com/docs/diggrss/']['username'];
$digg_userimage = $digg_submitter[0]['child']['http://digg.com/docs/diggrss/']['userimage'];
if (!empty($digg_count[0]['data']))
$data .= '<br /><span class="minor">' . $digg_count[0]['data'] . ' diggs &middot; ' . $digg_comments[0]['data'] . ' comments &middot; ' . $digg_category[0]['data'] . ' &middot; ' . $digg_username[0]['data'] . ' &middot; ' . $digg_userimage[0]['data'] . '</span>';

Using something like the following helps traverse the arrays to figure out how to get the data.

print_r($digg_submitter);//will show array to parse to get stuff