Archive for Web Development

  • 06
  • Jan

If any of you guys follow Digg closely, you might have noticed an amusing article to hit the homepage a few days ago called You Might Be Addicted to Digg If. If you’re a keen observer, you might have also noticed this list was hosted on a new startup site called ListZe. This is a fun project I built with a buddy of mine (Parker) to help fill an untapped market of social organization and list management.

Lots of people out there have great ideas of informative or comical information they’d like to toss out as a list and submit to digg or reddit, but they don’t want to setup a whole blog or website, and then get limited static functionality from it. ListZe is a bit different. On this site, anyone can create a list and add items to it. Then other members can come along and add their own items that might have been forgotten originally. This is a great social collaboration tool in itself. Next members can vote items on any list up and down, effectively sorting the list in decreasing order, polarizing the items with the best (usually the funniest) up top, and the worst items on the bottom.

It’s a great site that could prove very useful to a number of people. Here are a few example lists for you to see the kinds of lists we serve:
Funny Bumper Stickers
2008 Presidential Candidates
Funny Blonde Jokes
Excuses for Sleeping at Work
Funny AIM Away Messages
The Best Movies of 2007
Amazing but True Facts
Fun things to do at Walmart
And many more. View the complete list.

  • 18
  • Oct

Since launching Desktop Nexus, we’ve experienced astronomical growth. We’re now seeing over 20,000 downloads a day and visitors from all around the world. We’ve formed a number of partnerships, including one a content distribution agreement with Pixsy. We have over 11,200 wallpapers and are quickly approaching 2,000 users, contributing an overall total of 2,000,000 downloads. Wow!

Well, we’ve been working night and day for weeks now on something big for Desktop Nexus, and hopefully we’ll launch it by November 1st, so stay tuned. :)

Until then, here are a few popular galleries on the site the past few days:
- Ubuntu Wallpapers
- BMW Wallpaper
- Family Guy Wallpaper
- Car Wallpapers
- Hannah Montana Wallpaper
- Abstract Wallpapers
- BMW Wallpapers
- Car Backgrounds
- Mini Cooper Wallpaper
- Graffiti Wallpapers

So if anyone is looking for fresh desktop wallpapers, check out Desktop Nexus. :)

  • 10
  • May

I just noticed we have some beautiful waterfall wallpapers on Desktop Nexus, so I threw up a quick Digg article: http://www.digg.com/design/Beautiful_Waterfall_Wallpapers

If you have a Digg account, I’d appreciate the support. :)

  • 03
  • May

Desktop Nexus is a wallpaper site with the vision of stepping over the boundaries of traditional wallpaper sharing… and I will go as far as saying that it is currently one of the most technologically advanced wallpaper galleries in the entire world.

Completely member oriented, anyone can upload wallpapers, then the community votes if they’re a high enough quality to be added to the galleries, or if they should be deleted forever… all driven through the “Pending Additions” categories. Heavily endowed with AJAX and RSS, meta-moderation, voting and tagging, it’s truly fresh in this industry.

For example, if someone uploads a 1024×768 wallpaper, Desktop Nexus will automatically resize and remaster that wallpaper for another visitor who requests it in say, 1600×1200. It then goes a step farther and will show an AJAX script to allow any user to instantly crop (interactive) or stretch the wallpaper to create a widescreen version for anyone who requests it… so essentially one wallpaper of any size is uploaded, and Desktop Nexus will make it available to anyone with any resolution… completely bypassing previous limitations of wallpaper sharing, standard aspect ratio or widescreen.

Now, let’s take a quick visual tour of the coolest parts of Desktop Nexus.

AJAX Wallpaper Uploads, plus the ability to upload ZIP files for Mass Uploads (upload dozens of wallpapers at a time!):

AJAX Uploading

And after the wallpaper is uploaded, it undergoes a voting process where the community decides if it’s quality is good enough to be added to the galleries:

Community Voting

Wallpapers can be tagged with descriptive words to link similar ones together. AJAX technology helps suggest commonly used tags as you type.

AJAX Tagging

Our tag clouds are a great way of quickly seeing what’s popular in each gallery.

Tag Cloud

Every member (quick, free signup) gets a My Desktop Nexus profile they can tweak and customize, allowing them to share everything from their hobbies to their favorite wallpapers.

My Desktop Nexus

I have big dreams for this site, and for nearly a year I’ve poured my heart into it, spending a week on a small detail most users would never even notice. I honestly believe this site could become the next YouTube, as to this day there is no household name for wallpaper sites. There is a dominate site in almost every industry, but wallpapers is 95% scattered small sites. Before when I wanted a wallpaper, I went digging through Google Images, sorting through the low quality and odd size images. Sure, Webshots did pretty well, but I believe they shot themselves in the foot with advertising in their downloadable client. We can do better. I want someone to be sitting in their chair and decide their desktop background is getting old, and for the first thought through their mind to be “Desktop Nexus”.

We’re still tweaking the site and adding new functionality all the time, so stay tuned. I’d also appreciate any feedback you have on Desktop Nexus. Thanks!

Go There -> Desktop Nexus Wallpapers

  • 24
  • Mar

I’ve gotten quite a few comments on my recent post about creating a sliding, collapsible DIV, and while I like to leave some things unsaid, to be figured out by the reader… one question that repeated kept coming up was how to toggle the sliding with a single button/link.

This is a quite simple process. Let’s assume we have all the code already in place from the last tutorial. In your motionpack.js file, let’s add a new function at the very bottom, looking like this:

function toggleSlide(objname){
  if(document.getElementById(objname).style.display == "none"){
    // div is hidden, so let's slide down
    slidedown(objname);
  }else{
    // div is not hidden, so slide up
    slideup(objname);
  }
}

Now, stepping though this function is very simple. There’s an if-statement to check is the DIV is already hidden, or if it’s still visible. If the style.display property is set to “none”, then it’s hidden, so we slide the DIV down. If it is visible, the code jumps to the else statement, and slides the DIV up, using the same slidedown() and slideup() functions we used in the last tutorial.

Now, your link itself would look like this:

<a href="javascript:;" onmousedown="toggleSlide('mydiv');">Toggle DIV Slide</a>

This is assuming your DIV still has the ID of ‘mydiv’.

And finally, here is the new code in action:


Toggle DIV Slide

Enjoy! And also, I’m always listening for new ideas for tutorials. If there’s something you’d like me to explain, ask! :)

  • 18
  • Mar

On the heels of two very successful tutorials on creating a collapsible div and an animated sliding div, I’ve decided to write another. It seems my last few helped a number of programmers learn a simple trick, and hopefully this one will do the same.

Note, I’ve also upgraded to a much newer, faster server, so hopefully the social networking sites won’t “collapse my server” again, as one Digger so eloquently put it. :)

Hearing about AJAX constantly, but never have found time to read a lengthy, frustrating, complex tutorial? In the following post, I’m going to explain how to add AJAX functionality to your website in three easy steps. It’s actually quite simple, and I’m going to try and be clear and to the point, but not over or under-explain anything like most tutorials have a tendency to do.

Before you begin, decide what purpose or additional functionality adding AJAX to your website will accomplish. Will it be a live search feature? Something to save user preferences? In this example, we’re developing a simple calculator. Let’s dive in.

Step 1: Create the Intelligence
First let’s make the brain of the system. In our calculator, we’re going to need a PHP function to actually perform the operations. We’ll handle the front-end later, but for this file, we’ll take our input from GET request strings (variables passed through the URL itself, such as file.php?var=value&var2=test).

Name this file: backend.php
<?
  if($_GET['op']=="" || $_GET['num1']=="" || $_GET['num2']==""){
    echo "Error: Please complete all fields.";
    exit;
  }
 
  if($_GET['op'] == "divide" && $_GET['num2'] == "0"){
    echo "Error: Division by zero.";
    exit;
  }
 
  if(!is_numeric($_GET['num1']) || !is_numeric($_GET['num2'])){
    echo "Error: Invalid numbers.";
    exit;
  }
 
 
  switch($_GET['op']){
    case "add":
      echo $_GET['num1'] + $_GET['num2'];
      break;
    case "subtract":
      echo $_GET['num1'] - $_GET['num2'];
      break;
    case "multiply":
      echo $_GET['num1'] * $_GET['num2'];
      break;
    case "divide":
      echo $_GET['num1'] / $_GET['num2'];
      break;
  }
?>

Now, let’s take a look at this file. We’re working with three variables passed from the GET string: the operation such as add/subtract/divide/multiple ($_GET['op']), and the two numbers we’re performing the math on ($_GET['num1'] and $_GET['num2']). For example, we might call this page like this: backend.php?op=add&num1=12&num2=4 . This is running our above file (backend.php), passing “add” as the ‘op’ variable, and 12 and 4 as the two numbers.

The first four lines of the above backend.php script checks to make sure all the variables were entered. If any of the three values are blank (“”), then it errors and exits. The next if-block is checking for a divide by zero error. If the op variable is divide and the num2 variable is zero, it errors and exits. Simple.

Next it checks to ensure you entered valid numbers with the is_numeric() function in PHP. If you enter a letter or something else in the field, it will show and error and exit.

The next (and last) block we get to is the switch statement. This goes through and checks the op variable to see what we’re trying to do here. Every case-statement represents one of the possible operations (add/subtract/divide/multiply). When it figures out which operation is being requested, it performs the math on num1 and num2, echo’s the result, and breaks out of the switch statement, thus ending the file. If you need to brushen up on how switch statements work, php.net has a great tutorial.

There, now you’re 1/3rd done with adding interactive AJAX functionality to your web application. Easy right?

Step 2: Create the Form
Now we’re going to create the frontend to the AJAX. This is the part the user sees, and is mostly basic HTML. You can add this to any PHP or HTML file you have, anywhere you want.

Here’s the frontend code for our calculator:
<input type="text" id="num1" size="6">
<select id="op">
<option value="add">+</option>
<option value="subtract">-</option>
<option value="multiply">*</option>
<option value="divide">/</option>
</select>
<input type="text" id="num2" size="6">
<input type="button" value=" = " onClick="doMath();">
<div id="answer" style="display: inline; font-size: 16px"></div>

This is simple HTML, adding two textboxes, a drop-down (with values corresponding to the values of the case statement in backend.php), a button, and a DIV. Notice I’m not using a submit button (it doesn’t matter) because I’m not using a form. This might not be best practice, but it goes to show you’re not submitting anything to another page, like you traditionally would. The button has a function “doMath()” which is called from the onClick attribute. We’ll explain this function in step 3, but for now, just know that begins the AJAX and solves the math problem. Also notice we’re using id’s instead of names for the textboxes and drop-down field (select)- this is for us to reference the fields from Javascript in the next step. The last line is a simple DIV with a bit of CSS styling (display: inline makes it appear after the equals button, rather than on it’s own line, and the font size is for aesthetics). We set the id of this div to “answer”, and we’ll be using it later from the Javascript to output the answer.

Very easy. Now we have the backend setup to do the math, and the frontend to ask the user what kind of math he wants to do… so now the only piece left is connecting them together!

Step 3: Connecting the Frontend and Backend Together
This step is the trickiest, but stick with me, and you’ll see how easy it really is. We use Javascript (AJAX = Asynchronous Javascript and XML) to talk between the HTML and the PHP.

For this step, let’s create another new file, and call it ajax.js.

http = getHTTPObject();
 
function getHTTPObject(){
  var xmlhttp;
 
  /*@cc_on
 
  @if (@_jscript_version >= 5)
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }catch(e){
      try{
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }catch(E){
      xmlhttp = false;
    }
  }
  @else
    xmlhttp = false;
  @end @*/
 
  if(!xmlhttp && typeof XMLHttpRequest != 'undefined'){
    try {
      xmlhttp = new XMLHttpRequest();
    }catch(e){
      xmlhttp = false;
    }
  }
 
  return xmlhttp;
}
 
function doMath(){
  var url = "backend.php?op=" + document.getElementById('op').value;
  url += "&num1=" + document.getElementById('num1').value;
  url += "&num2=" + document.getElementById('num2').value;
 
  http.open("GET", url, true);
  http.onreadystatechange = handleHttpResponse;
 
  http.send(null);
}
 
function handleHttpResponse(){
  if(http.readyState == 4){
    document.getElementById('answer').innerHTML = http.responseText;
  }
}

Now, your first reaction might be to panic, but stay calm, it’s not that bad. The entire getHTTPObject() function (half the file) you do not need to understand. It’s a standard function included in almost every AJAX script out there… simply copy and past that exactly as it is, and forget about it. There, now you’re just left with the first line, the doMath() function, and a small function called handleHttpResponse.

The first line is declaring an object to ask PHP for it’s result. Think of it as a mini web browser.

The doMath() function is where you actually send the AJAX request. Remember it being called when you click that button in the frontend? This is what’s run. The first three lines of this function are building a variable (url) that is the PHP page we’re going to request. It begins with “backend.php?op=” and grabs the value of the drop-down from the frontend to find out if we’re adding, subtracting, multiplying, or dividing. Then it adds the two numbers from the frontend on to the end of URL request string as well, using document.getElementById to find them (the textboxes’ values). Now the url variable is left with something similar to the example I gave right after the code in step 1. You could in theory plug this URL into your web browser, and see the result yourself, but instead we’ll let Javascript do it for us. The last three lines of the doMath() function pass that URL to our mini web browser (variable “http”), and essentially press the Go button. It sends the request, and tells it to notify us when it gets a response back, via the handleHttpResponse() function.

Now, the last function of our Javascript file is the handleHttpResponse() function… called automatically by our mini web browser when our PHP page finishes downloading (and it has an answer). The if-statement is basically saying “if the PHP site is done loading and you have an answer, continue.” The middle line is a call to set the innerHTML property of the answer DIV on the frontend to whatever the PHP page says…. in our case… the math answer.

Important!
Now, for this to work, you need to call the ajax.js file from the file where your frontend is. This is done by simply placing this line above the frontend somewhere in the code:
<script language="javascript" src="ajax.js"></script>
The best place to put this is between the HEAD tags of the file, but anywhere would work. If you do not add this line, your website will give errors when someone tries the AJAX, and it won’t work.

And you’re done!

Now, I’m sure critics are going to ask why do this with AJAX when I could easily accomplish the same thing with pure Javascript, and the answer is this is a tutorial to learn. Often times the PHP backend does MySQL calls, or things that Javascript couldn’t do. For example, live searches (results below the textbox as you type) are this same basic framework, but the backend searches a database for what the user is typing, and returns the results to set in the answer div (equivalent). Simple! :)

And as always, here is a live, working demonstration of the tutorial in action:

I enjoy your comments and requests for future tutorials!

  • 06
  • Mar

Well, my last tutorial post about creating a collapsible div (no animation) was a huge hit, receiving over 1100 diggs.

I actually learned quite a bit from the comments. First of all, I implemented the wp-cache 2.0 so my server doesn’t go down after 70-100 diggs again, haha. Secondly, I found people wanted animation… Digg comment style sliding. I can do that. :)

So, expanding on the last tutorial, I’ve coded a small Javascript library that will allow that functionality. It’s not meant to be a mootools or a script.aculo.us replacement… those are far more advanced libraries. This is just a simple, quick bit of code you can apply to your websites to improve the user experience a bit.

In this tutorial, we will create functions to slide DIVs up and down. It supports multiple animations happening simultaneously, as well as a variable animation length. It’s also time-based, rather than increment based, so it’ll animate the same speed on most computers; old computers won’t take 10 minutes for a DIV to slide down.

Click here to see the final product.

First, create a new file on your webserver called motionpack.js – this is where we will store all the javascript functions for the animations, rather than cluttering up the top of the webpage itself, and slowing down it’s load time. In the beginning of that file, let’s first declare some initial variables:
var timerlen = 5;
var slideAniLen = 500;
These are the variables you will change if you want to tweak the speed of the animation on your site. timerlen is how often the Javascript function will run to alter the DIV’s properties (altering height or opacity)… it’s probably best to leave this at 5. Any lower will be slightly smoother, but will require your visitors have a better computer (otherwise it’ll be choppy), and much higher will be choppy on everyone, because it’s not updating enough to look smooth. The next variable, slideAniLen, is how long it should take a DIV to completely slide up or completely slide down. This is in milliseconds, so setting it to 500 means it’ll take half a second to complete the animation effect. This is fairly quick, so some people might want to increase and make it a bit slower.

Now, the next part of the JS file:
var timerID = new Array();
var startTime = new Array();
var obj = new Array();
var endHeight = new Array();
var moving = new Array();
var dir = new Array();
These are some variables we’ll use throughout the code below to keep track of our animations. We use arrays for each object to allow multiple animations to happen simultaneously. We’ll explain where each of these are used later on, but for now, simply paste them into your JS file.

Now we’re getting to the actual functions. These first functions are what we call from our website itself. They essentially serve as the API for this mini-library.
function slidedown(objname){
  if(moving[objname])
    return;
 
  if(document.getElementById(objname).style.display != "none")
    return; // cannot slide down something that is already visible
 
  moving[objname] = true;
  dir[objname] = "down";
  startslide(objname);
}
 
function slideup(objname){
  if(moving[objname])
    return;
 
  if(document.getElementById(objname).style.display == "none")
    return; // cannot slide up something that is already hidden
 
  moving[objname] = true;
  dir[objname] = "up";
  startslide(objname);
}
This code adds the functions to call when requesting a DIV start sliding up or down. Let’s first look at the slideup() function. We pass it a single parameter- the DIV’s id (objname). The first line checks if the moving variable is set to true for that DIV, so we don’t begin animation on one that’s already moving. Once an animation starts, it will finish uninterrupted. If it is moving, on line 3, we return (exit from the function) so no further animation begins. The next line is a sanity checking if-statement. This function is beginning the slide down process of a DIV, and if a DIV’s display attribute is not set to none (not visible), we assume it’s already slid down and visible, so we can exit the function (abort the process), since there’s nothing else for us to do here. If those checks complete without any complications, we’re now ready to begin the sliding process, so we set the moving variable to true (so no other animation can start until we’re done), we set the direction variable to down (so it knows which way to move), and we call the function startslide(), which we’ll get to in a moment. The slideup() function is very similar, except it checks on the 3rd line inside that function to ensure the display property is not set to “none”, so the DIV is not visible, otherwise we have nothing to slide up, and we can abort the start slide process.

Now, I hope you guys are hanging in there, we’re almost through the tricky parts. :)

The next function we’ll throw in the file is the startslide() function mentioned above:
function startslide(objname){
  obj[objname] = document.getElementById(objname);
 
  endHeight[objname] = parseInt(obj[objname].style.height);
  startTime[objname] = (new Date()).getTime();
 
  if(dir[objname] == "down"){
    obj[objname].style.height = "1px";
  }
 
  obj[objname].style.display = "block";
 
  timerID[objname] = setInterval('slidetick('' + objname + '');',timerlen);
}
Okay, the last two functions were for making sure we really want to start the slide, and doing all the initial preparations. This function, startslide(), is where we actually begin the sliding process. We, as always, pass the DIV’s id (objname) that we’re working with as the function’s parameter. On the first line of this function, we set it in the obj[] array, so we can keep track of the id throughout the animation process. The next two lines set the endHeight to the original height (so we know where to start sliding from, or how far down to slide to), and the startTime, so we can keep track of how long this animation has been going on. Following this we have a nice three line if-statement that checks if we’re sliding down, and if we are, resizes the DIV’s height to 1px… a starting point to slide down from. Next it sets the object’s display attribute to “block”, making it visible (redundant if sliding up, but a good just-in-case measure never-the-less). Note: You might want to use “inline” instead of “block”, depending on your circumstances (inline will allow the DIV to have other content to the left and right of it, rather than adding a line break before and after it like block does), just be aware to change the other occurrences of “block” to “inline” if you do this. Finally the last line of the function is where we’ve set the initial timer, which will call the sliding function ever few milliseconds (depending on your settings of timerlen up top), and actually perform the animation itself.

Now, the function the above timer called was slidetick(), which is the next part of our motionpack.js file.
function slidetick(objname){
  var elapsed = (new Date()).getTime() - startTime[objname];
 
  if (elapsed > slideAniLen)
    endSlide(objname)
  else {
    var d =Math.round(elapsed / slideAniLen * endHeight[objname]);
    if(dir[objname] == "up")
      d = endHeight[objname] - d;
 
    obj[objname].style.height = d + "px";
  }
 
  return;
}
This function is what actually does the animation itself. The first line checks how long the animation has been in progress, by subtracting the animation’s start time from the current time. There’s then an if-statement that checks if the animation has exceeded the preset time (at the top of this file) for an animation’s length, and if so, it calls the endSlide() function, which cleans up (discussed below). If the elapsed time is not greater than the max time (the else-statement), it calculates the variable “d”. This calculation takes the ratio of time that’s progressed so far in the animation, and multiplies it by the final height of the DIV, so if half the time has progressed, for example, the variable d will contain half the height. Then it checks the direction, and if we’re sliding up, it alters d to it’s inflection… sliding the opposite direction (three quarters the way through the time would either be three quarters the way down if sliding down, or a quarter of the way from the top, if sliding up). Next we set the DIV’s height to “d” using it’s CSS style.height property.

Now, the last function we’re needing in the motionpack.js file is the endSlide() function:
function endSlide(objname){
  clearInterval(timerID[objname]);
 
  if(dir[objname] == "up")
    obj[objname].style.display = "none";
 
  obj[objname].style.height = endHeight[objname] + "px";
 
  delete(moving[objname]);
  delete(timerID[objname]);
  delete(startTime[objname]);
  delete(endHeight[objname]);
  delete(obj[objname]);
  delete(dir[objname]);
 
  return;
}
This is the function that’s called when the time runs out on an animation. It finishes everything and cleans up. The first line kills the animation timer, so it doesn’t keep trying to slide. The if-statement checks, and if it was sliding up, it hides the DIV by changing it’s display attribute to “none”. It readjusts the DIV’s height to the original height, so future animations will work fine on it. Then finally there are all those delete lines, deleting any array element we created to keep track of the different animations throughout the process. This cleans up a bit to ensure there are no memory leaks (for sites with lots of animations), etc. After this function is completed, the animation process is done.

Now you can save that file, with all the pieces above saved up, and upload it to your webserver.

To download the entire above JS file, you can get it here.

Now, we have our entire mini-library done…. so how do we use it?

First we need to include it in our website. This is done by adding this quick line to your website on every page that you’re using the animation, preferably in the HEAD tag:
<script language="JavaScript" src="motionpack.js"></script> This code assumes the file you uploaded is named “motionpack.js” and is in the same folder as your website source code itself. Another common practice is to create a folder called js/ and put all your javascript include files there together, and in that case, you’d change the src tag above line to “js/motionpack.js”. Easy.

Now that page of your website has sliding abilities! But how do we use them?

First, let’s create a DIV, like we did with our last collapsible DIV tutorial:
<div id="mydiv" style="display:none; overflow:hidden; height:95px;"><h3>This is a test!<br>Can you see me?</h3></div> Notice we did make one change though. We added an “overflow: hidden” attribute and “height:95px” to the style property of the DIV. These property MUST be present on all DIVs you use for sliding. If you don’t include the overflow attribute, it’ll look very ugly, with text overlapping on other content and such. If you don’t include a static height here, it won’t know how far to slide, so it won’t work at all. Aside from that, it’s virtually the same. You can put whatever you want inside the div, just be sure to adjust the height accordingly.

The difference is this time our link calls functions from our library above. Here’s an example of what a Slide Down link might look like:
<a href="javascript:;" onmousedown="slidedown('mydiv');">Slide Down</a> Notice in the onmousedown function we call the slidedown() function from our above library. This will begin the animation and slide the DIV down, until it’s completely visible. You can replace slidedown() with slideup() to do just that, slide the DIV up.

As a challenge to you, try using what you’ve learned in this tutorial and the last to create a toggleSlide() function. It would be a simple if-statement to check if the link’s “display” property, and either slide it up or down, depending on it’s state. We did something very similar in the last tutorial, so try applying that here!

And finally, he’s a working example of it:

Slide Down   |   Slide Back Up

Hope this helps!

Edit: Due to a high number of requests, I’ve made a followup post explaining how to use this code in a one-click toggle situation: Toggle Sliding DIV :)

  • 05
  • Mar

Note, I’ve since made an updated post to this, with Digg comment style sliding animation included. Digg LinkActual Link

One of the most handy (and cool) tricks a web developer could learn to use is collapsible DIVs. This allows you to make a page that will only show the user what they want to see. If they’re interested in some part of content, such as a “mail to friend” or an expanded definition, they could click a link or image and make the page dynamically grow in size to show that added bit of content.

This was inspired by some comments in a post on Aaron’s SEO Buzz Box, and while I think he might be looking for a slightly more advanced solution, it gave me the idea to type up this post.

There’s a few different bits of code we’ll use in this. First we’ll create a div we want to expand or contract. For example:
<div id="mydiv" style="display:none"><h3>This is a test!<br>Can you see me?</h3></div> Notice our tagging the div with a unique id. This allows our Javascript to be able to find it when we alter it’s visibility. We also added a style property, setting it’s display attribute to “none”, which makes that DIV hidden when the page loads originally.

Next we’ll create a link with some inline Javascript to hide or show our div. It’s quite a bit to take in at once, but don’t worry I’ll explain it in depth in a second. Here it is:
<a href="javascript:;" onmousedown="if(document.getElementById('mydiv').style.display == 'none'){ document.getElementById('mydiv').style.display = 'block'; }else{ document.getElementById('mydiv').style.display = 'none'; }">Toggle Div Visibility</a> Whew! It’s so complicated because it’s done with inline Javascript. I’ll show an alternate method that’s much cleaner a bit later. But first, let’s tackle this. It’s a simple anchor tag, but you’ll notice the href is “javascript:;”. The purpose of this is to basically do nothing. You don’t want to direct to any other page, and if you put everything in the onmousedown property in the href property, it would work the exact same, but the user would see a mess of javascript in his status bar when he moused over the link, so this keeps it cleaner. Another common do-nothing insert to use for the href property is a pound sign (#), and while that will work, it’ll also move the user’s scroll bar to the very top of your website, which can get quite annoying.

Note, the following explanation is very detailed and assumes virtually no knowledge of Javascript… so if this seems basic to you, feel free to skip it.

Now, we have the href property clean so there’s nothing ugly in the status bar on mouseover, but we still need to actually do the hiding or showing of the div. We call this through the onmousedown property of the anchor tag. We can find the DIV we created earlier by document.getElementById(‘mydiv’), so we decide to first check if it’s already visible or hidden by running a simple if-statement of if(document.getElementById(‘mydiv’).style.display == ‘none’){. If this returns true, meaning the display property is set to none (hidden), we continue past the first bracket and change it’s display property to “block”, which means visible. This will also create a line break before and after our div, so if you want it to appear in the middle of your text or other content, without line breaks, change “block” to “inline”. Following that setting statement, we have our else block, which it run if the first clause isn’t met (the display is NOT set to ‘none’). If it’s not set to none, we assume the div is visible, so we toggle it and hide the div, setting it’s display property to “none” (hidden) again.

An alternative which is a bit cleaner than that inline anchor tag (above) is creating a javascript function for toggling the DIV’s visibility. For this method, use the following anchor tag:
<a href="javascript:;" onmousedown="toggleDiv('mydiv');">Toggle Div Visibility</a>This anchor tag behaves like the above inline javascript, except instead of executing the change in the anchor tag itself (inline), it instead calls the toggleDiv function, passing the div name as a parameter.

This anchor tag above calls the following function. Simply insert this text (the function) somewhere in your document above the link in the body tag, or in the HEAD tag of the HTML itself:
<script language="javascript">
  function toggleDiv(divid){
    if(document.getElementById(divid).style.display == 'none'){
      document.getElementById(divid).style.display = 'block';
    }else{
      document.getElementById(divid).style.display = 'none';
    }
  }
</script>
This function does exactly what the above inline javascript does, only it’s a bit cleaner. When it’s called by the anchor tag, it checks the div with the name passed to see if it’s currently not visible (display set to “none”), and if so, it shows it by changing the display to “block”. If the original if statement fails (display is not set to “none”), then it assumes the DIV is visible and hides it again (sets the display property to “none”).

Finally, here’s an example of it in action:

Toggle Div Visibility

Also note, search engines WILL read and index the content in these DIVs, so don’t worry about using collapsible DIVs hurting your SEO.

I’m planning on making another tutorial later talking about how to do this with a bit of animation (sliding the div down and back up again). Hope this is helpful!

  • 27
  • Feb

I just noticed something quirky.

When my homepage shows up in Google, it’s not cached. Every other page on this blog is cached, but not the homepage for some reason. There are no meta tags blocking it, and the robots.txt file doesn’t have anything unusual. I’m not sure if it was cached at some point in the past, but I’d assume so. What could have changed? Doesn’t Google cache all the pages it indexes (without overriding instructions)?

Can any SEO buffs out there help me shine some light on this? Thanks.

  • 26
  • Feb

Seven ways, because lists of ten are overdone, and seven was all that was needed (without losing quality, or having to think really, really hard). :D

1. Over-monetizing

Sure, everyone wants to make thousands of dollars a month from their blog, but that parallels elementry school kids saying they want to grow up and play professional football. It could happen, but the odds are stacked against you. People come to your blog for information. Without good content, there’s no reason for them to stick around. Blogs are much more useful to use them a promotion medium. Use your blog to gain weight in search engines and recognition in the community. That’ll help you much more than a few dollars a day from Adsense. For instance, if you build a blog up, then use it to promote a new product you launch down the line. You’re already starting ahead, since you can use your blog’s weight to give your new website a jump-start. Think Google… first build a quality site people will use and benefit from, then the monetizing aspect comes later on. One of the internet’s few exceptions to this rule is John Chow. There’s a man who monitized his blog inside and out, but still maintained a high level of quality.

2. Attention Whoring

There’s a few sides of this that tie together. First off all, there are those who attack a well known player in the industry for no reason other than the quick burst of attention and controversy they’ll get. Bad idea. The blogsphere exists through friendships and trust, and if you are blacklisted, it’s near impossible to grow your blog’s influence. Another side of this is people who brag or gloat on their blogs. There is a level of confidence that’s required, but we don’t need to read a 10 page post about how your name was mentioned in Hicksville’s Newspaper last week. Readers are selfish and greedy… post about what information they came looking for and they’ll be much happier (and maybe even keep reading your blog). On the opposite side of this, one example of an attention whore who can get away with it is, of course, Shoemoney. From the famous picture of his Adsense check, to his latest MyBlogLog drama, it’s hard to deny Shoemoney loves attention… but with a blog as interesting and high quality as he has… he deserves it! :D

3. Personal Life Rambling

A blog is a public tool that is not supposed to be used as a diary. I couldn’t care less that your fish turned four years old today. Don’t constantly clutter my RSS reader with irrelevant posts, as there’s no quicker way for me to drop your feed. Obviously, an occasional post about a major landmark in your life is fine and interesting, but a large number of blogger have gotten their blog confused with a diary. They market it as an Internet SEO and SEM blog, but they make one post a month about SEO. There is about 50 blogs I read everyday (through Google Reader), and one of the quickest ways to get nicked from my subscribed list is to consistently post about unrelated material. A perfect example of this, however one who can hardly be criticized for it, is Google’s own Matt Cutts.

4. Not Updating

One of the biggest aspects in distinguishing a successful blog from a dud is a fairly large readerbase… and readers can’t read your blog if you never update. This is one we’ve always been guilty of at one point or another, especially when first getting started, but if you take up the responsibility of writing a blog, and you actually want it to be successful, you can’t neglect it. Depending on your niche, at least one or two updates a week should be the barebones minimum. There are a few blogs I consider exceptions to this however… who rarely post, but when they do, I make a point of reading every word of their posts our of pure respect for the authors. Among those are Boogy BonBon and Lee Dodd.

5. Posting Junk

Following the previous point, no one is going to subscribe and read your blog if there is few posts of real quality. Sure, posting quick jokes or interesting websites can be fun on occasion, but without good, solid content, what do readers get out of your blog? If they can spend the time to read your blog, you can at least spend a little time yourself and give them something worthwhile to read. One example, is the blog I setup to post whatever junk I don’t want to post here, Decomprehension. Separating the impulsive posts from the quality posts allows me to be get more out there, and maintain the integrity and quality of this blog.

6. Limiting RSS to Snippets

As the number of quality blogs online increase, it’s becoming more and more popular to keep up to date with your favorites via an RSS reader. One of the biggest things I can’t stand about blogs are people who are so scared of giving away free content, they truncate their RSS feeds to a quick blurb. My style of reading blogs is skimming the RSS, then if an article seems interesting, I will usually open that post’s page in a normal browser window and read the entire thing plus comments. However when an author limits it to three to four sentences of a three page post, it’s near impossible to tell if the article is worth reading or not. For those worried about duplicate content, Google is very good about snatching up new posts via RSS (or HTML, depending on how much Googlebot likes your site), and flagging you as the content originator. It is extremely rare for Googlebot to make a mistake in a cross-site duplicate content issue. If your reasoning behind limiting RSS feeds is because less people will see and click on your ads, reread item number one… it’s much better to get a loyal reader than to make a few extra cents. One example of a blog who does this, however is an exception to the rule, is Aaron Wall’s SEO Book. He drives me crazy with his handicap RSS feed, however I still make a point of reading his every post.

7. Not Being Unique

There are millions of blogs out there (55 million according to Technorati), and every one is fighting for readers and rankings. What sets you apart? If you just syndicate every popular story to hit Search Engine Watch or Slashdot, what sets you apart from the other 54 million doing the same thing? Of course, occasional story quoting (with sources cited and your own personal thoughts appended) is fine, but blogs that do nothing but this everyday will have a difficult time getting themselves known. Don’t misunderstand me, by all means reference other bloggers and engage the community, however I’m speaking of blogs that syndk8 99% of their content and show no original, provoking thought or creative effort. To truly shine in the blogsphere you need to consistently write high quality, unique posts. Instead of copying all the time, you should be the one aiming to be quoted and linked.

  • 07
  • Feb

I was trying to automate logging into MySpace with PHP and cURL, and I had some problems. For some reason, it kept kicking me back to the homepage rather than the logged in page… and finally I figured out why. I’ll post the code up here for anyone else who has a similar issue.

Basically, to automate the MySpace login system, you need these steps:

  • First setup your cURL session with a cookie file and a cookie jar. They’re obviously required. You will also NEED to specify a user agent… that’s what got me. MySpace checks your user-agent, and if it doesn’t match a known one, they abort your login process.
    // setup and configure
    $ch = curl_init();
    $randnum = rand(1,9999999);
    curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cookiejar-$randnum");
    curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookiejar-$randnum");
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1");
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 0);
  • Visit the myspace.com homepage, and scrape the security token, which is made into the URL where the login form submits (the form action):
    // get homepage for login page token
    curl_setopt($ch, CURLOPT_URL,"http://www.myspace.com");
    $page = curl_exec($ch);
    //
    // find it....
    //
    preg_match("/MyToken=([^"]+)"/",$page,$token);
    $token = $token[1];
  • Next actually post your information and submit the login form. You must forge the referer as myspace.com, and you must specify the content type in the HTTP header as “application/x-www-form-urlencoded”. Notice my last appending line on $poststring is a bunch of semi-encoded values… that is the rest of the form MySpace sends with your login. It’s a required line for their internals, don’t omit it.
    // do login
    curl_setopt($ch, CURLOPT_URL,"http://login.myspace.com/index.cfm?fuseaction=login.process&MyToken={$token}");
    curl_setopt($ch, CURLOPT_REFERER, "http://www.myspace.com");
    curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: application/x-www-form-urlencoded"));
    curl_setopt($ch, CURLOPT_POST, 1);
    $postfields = "email=" . urlencode($YOUR_EMAIL);
    $postfields .= "&password=" . urlencode($YOUR_PASSWORD);
    $postfields .= '&ctl00%24Main%24SplashDisplay%24login%24loginbutton.x=38&ctl00%24Main%24SplashDisplay%24login%24loginbutton.y=15';
    curl_setopt($ch, CURLOPT_POSTFIELDS,$postfields);
    $page = curl_exec($ch);
  • The next page you’ll hit is a 302 redirect to the internal login page. This might be handled automatically, but I’m going to scrape the redirect url and pass it manually, as a precaution.
    // find redirect url
    preg_match("/replace\("([^"]+)"/",$page,$redirpage);
    $redirpage = $redirpage[1];
    //
    // do the redirect
    //
    curl_setopt($ch, CURLOPT_REFERER,"http://login.myspace.com/index.cfm?fuseaction=login.process&MyToken={$token}");
    curl_setopt($ch, CURLOPT_URL,$redirpage);
    curl_setopt($ch, CURLOPT_POST, 0);
    $page = curl_exec($ch);
  • Now you should be at the logged in page. I run a quick check that it didn’t bounce us back to the login page for an invalid username or password before proceeding:
    // check login error
    if(strpos($page,"You Must Be Logged-In to do That!") !== false){
    // login error
    return 2;
    }

Congratulations, you’re now logged into MySpace. I fought with this for a while because I didn’t know they check the user-agent (most sites don’t care), and I was getting really strange results when trying to log in.

From this point, you can do whatever you want, such as send messages, post bulletins, modify your profile, etc. For requesting the modify-your-profile page, here’s the code:
// find edit profile link (with token attached)
preg_match("/ id="ctl00_Main_ctl00_Welcome1_EditMyProfileHyperLink" href="([^"]+)"/",$page,$redirpage);
$redirpage = $redirpage[1];
//
// go there (edit profile)
//
curl_setopt($ch, CURLOPT_URL, $redirpage);
$page = curl_exec($ch);

Simple!

And before you finish, don’t forget to clean up by closing curl and deleting the cookie file you made:
// clean up
curl_close($ch);
@unlink("/tmp/cookiejar-$randnum");

I’d recommend getting the Live HTTP Headers Firefox Add-on if you don’t have it already, as it makes debugging these processes much easier.

Here’s the entire source code uncut:
Read the rest of this entry …

  • 22
  • Jan

There are a number of things on the internet that suck- here’s my top 10:

10. Multi-color, rapid flashing banners congratulating me for being the millionth visitor. If I were really that lucky, I should start playing the lottery.

9. Popups piggy-backing on a link… I click the link to go somewhere, and while the page changes, an ad pops up in front of me. Site Point is an example sites that do of this. Actually, I think pop-ups in general describe number 9 best.

8. Chain emails. Email is not new anymore. Everyone uses it, and the novelty is wearing off. When will people learn that Bill Gates isn’t watching who they forward it to, and will not donate $1 to some armless, legless, kid with cancer living alone on the streets of Uganda by the name of Janji.

7. Trying to unsubscribe from an email advertising list you didn’t want to be on in the first place, and then have to send or confirm 30 additional emails during the removal process… later to find out you’re still getting the same spam, only now it’s coming from a different From address.

6. Having to sign up or register for every other website on the internet. When will they create one master login for everything? Google’s going in the right direction.

5. RIAA and MPAA. I’m tired of every other news article being about who they’re sueing, or how much money they’re losing now. Either get new techniques, or give up already. P2P will never die.

4. As a web developer myself, I can’t stand websites that break standards. If I view some site in Firefox on Ubuntu, it better look identical to IE on Windows (unless of course it’s IE that breaks the standards, ugh).

3. Broken links. Don’t you just hate it when you FINALLY find that perfect resource, and the links broken? Then on top of that, there’s no old cache of it? It’s just plain gone. Makes your heart sink, doesn’t it?

2. Slow loading websites. Like I mean sites that feel as if they were hosted on someone’s old 486, connected via their residential 56k dial-up. If you run a website, spend a few dollars and buy decent hosting.

1. Community-based websites that completely sell out. For example, MySpace has more advertisements crammed into every page than I would have previously thought possible.

  • 13
  • Jun

Heh, and unfortunately I’ve been hit by another wave of work, and I’ll be very busy for a while again too. :( I’ve been traveling all over the southeast on corporate server repair calls (usually Sun boxes), as well as doing heavy web development for a few companies. We’re also in talks with Comcast and Costal Computer Corporation about rolling out some joint-marketing ventures in the CRM industry. :)

I also called the printing company about the e30 tshirts today for United Bimmer, and I’m sending them the original image in a second, so hopefully we can finish the design work and begin printing in the next week or so. I’ll keep you posted on that.

And also, in my endless free time, I’ve formed a conglomerate network site for all my sites, to bring them all together. It’s called Eldium Interactive. http://www.eldiuminteractive.com and it’ll add a bar to the top of all our network sites like this: http://www.eldiuminteractive.com/showbar.php (example). That should connect all the related sites a bit better, and also help our search engine optimization greatly, since it’ll unite the entire network with a single website, rather than scattered links everywhere. Oh, and if anyone has any experience writing Press Releases, contact me. :)

Thanks guys, and hopefully things will clear up soon and I can resume more-frequent posting.

  • 06
  • Jun

The domain name is the absolute most important part of your website.  If you have the greatest website in the world, but a horrible domain name, your return visitors will be minimal.  Okay, to the point, here are a few simple tips that can help you choose a truly unique and successful domain:

- Keep it common with a .com, .net, or .org TLD… plain and simple.  Sure, you can find better names with a strange, or less common extension”¦ I even have a two letter domain in another country code, but it”™s useless.  If you want a site to be successful, stick to the main three.

- No dashes; that makes it more complicated to remember and easier to forget.  If you”™re going for repeat visitors, try to keep the margin of error as low as possible.

- Think of something that flows when spoken, like MySpace. Nothing with awkward vowels or multiple words with the same sound starting and ending, for example: pandas anniversary.com.  It doesn”™t have the same ease of flow like “œMySpace”.

- Don”™t choose a name that”™s too long. The longer the name is, the harder it is to remember”¦ and type in.  As a rule of thumb, keep it under two words.  thebestwallpapersiteontheinternet.com may be catchy, but isn’t practical.

- Choose a domain that cannot be confused for a plural tense… nothing that a plural version of one of the words would still make sense (grey area here). For example, there is an existing site called car-wallpapers.net, however, there is another, completely different wallpaper site at www.car-wallpaper.net.  Something as simple as a plural noun in the domain can be the difference your advertising and branding helping someone else”™s monetized website.  Try to choose a name that the plural wouldn”™t make sense, or is a completely different word (less common), such as Amazon”¦ very few people would confuse that and type amazons.com.

- I’m trying to think up a brandable name. Something like DieselStation.com (another car wallpaper site), which is catchy, but applies. A name like car-wallpapers.net is simply not brandable. It should be clean and simple, but catchy and apply directly toward your product in general.  Be unique, and creative.

- Sub-product branding.  The psychological side and branding is everything in a domain name.  The longer a visitor stays on your site, the more engraved your domain name should be in their mind.  For example, HostGator, a rapidly growing hosting company, names all their packages along their brand lines, such as Hatchling (small package), Baby Gator (medium) or Swamp Gator (large package).  This might sound cheesy, but it drills the name HostGator into the visitor”™s mind.

- Do your research.  Ensure there”™s no preexisting website out there that is similar to your name.  Even if it”™s a letter or two off, you want to ensure your domain brand is your own.  A perfect example of this is the car aftermarket lighting company I”™ve done web development for, Umnitza.  There is another, completely separate company called Umnitza-East, and whenever anyone tries to support Umnitza-East, the majority of the people end up going to umnitza.com and buying from the wrong vendor.  Granted this is completely their mistake, the same concept applies.  You don”™t want to tell someone to buy something from your store at miceparadice.com, and them accidentally buy from mouseparadice.com, your biggest competitor.

That”™s about all the tips I can come up with for now, however I do plan on expanding this in the future, and branching off a completely different article on website branding, so stay tuned.  :)   Feel free to leave comments with questions or suggestions.

  • 16
  • Apr

All right, car-wallpapers.net is doing incredible. It has only been online for a few weeks now, and already has about 1/5th the traffic of UB! However one thing that’s always bothered me is the brute simplicity of the name. It’s straight-forward, but horrible branding for a website. There are too many other websites with a similar name (just one typo away), and with a non .com TLD and a dash in the name, remembering the domain to type in later may be tricky. Also because of it’s success, I’d like to expand the site beyond car wallpapers and into new categories. I also run a few other websites unrelated to cars, such as sports fansites, and I’d like to offer wallpapers in a sidebar format similar to on UB. The car wallpapers section will become a subdomain of whatever the new website name is, such as cars.omgcooldesktop.com.  :)
That said, does anyone have any ideas for a non-industry specific wallpaper related website name, that’s catchy, brandable, and unique? Haha, any ideas are welcome!