22 November 2010

Switch to Office 2003 menus in Office 2007, 2010

This nifty program (free for personal use) enables Office 2003 menus in Office 2007 and 2010.

15 November 2010

Getting JW HTML5 Player to work on IE, Part II

In part 1, we talked about getting the player working on IE with the beta version of the JW HTML5 Player. Now that version 1.0 of the JW Player is out, let's revisit the issue of getting it working on various browsers, including IE.

First off, the full release has a different syntax for initialization of the player. This code demonstrates how to set up the player for all video tags on the page as well as for IE. Don't forget to include the jwplayer.js file on the page.

$(document).ready(function(){

$("video").each(function(){
if (jQuery.browser.msie){
var vidFile = "";
$(this).parent().find("source").each(function(){
if (jQuery(this).attr("src").indexOf("m4v") != -1 ||
jQuery(this).attr("src").indexOf("mp4") != -1){
vidFile = jQuery(this).attr("src"); //.substring(jQuery(this).attr("src").lastIndexOf("/")+1);
//alert("vidFile: " +vidFile);
}
$(this).remove();
});
$("[id="+$(this).attr("id")+"]").attr("src",vidFile);
}

jwplayer($(this).attr("id")).setup({
events: {
onPlay: function() {videoEventHandler(1)},
onComplete: function() {videoEventHandler(0)}
},
//debug: "console",
players:
[
{ type: "html5" },
{ type: "flash", src: "global/vid/player.swf" }
],
components: {
controlbar: {
position: 'bottom'
}
}
});
});


});

function videoEventHandler(type){
switch(type){
case 1:
stopSlider();
break;
case 0:
startSlider();
break;
default:
return;
}
}
You should try the above code without the if (jQuery.browser.msie){...} to see if it works for you on IE; it didn't for me so I've thrown that in. The code pulls the MP4/M4V video source and applies it to the main video tag as a src attribute. This took quite a bit of trial-and-error to discover.

Note that in the version I was using, there was a bug in Firefox: FF doesn't like the console object being called when without the Firebug window being open. IE has the console object available by default. So if you set debug: "console", you might get errors on Firefox.

In addition, when creating your video tags, ensure that the MP4 source tag comes before OGV: Chrome chokes if you have OGV first, perhaps because it can play both video types via its HTML5 implementation. Also note the event handlers attached to the video player; these are called for the AnythingSlider to stop and start.

13 October 2010

"NTLDR is missing" error on Windows 7

I was running a dual-boot XP Pro/Windows 7 box, with Windows 7 running on a second SATA drive. Finally decided to move the drive inside and surplus the XP drive. I hooked up the new drive internally and booted up, only to see it throw this error:
NTLDR is missing.

Press Ctrl+Alt+Del to restart.
No amount of rebooting helped. We tried using the Winternals boot disk to no avail. Finally did some research and found a forum thread that helped.

Two issues were going on: I had another external hard drive that was set to "Active" in Disk Management. The second issue had to do with the missing XP drive; apparently, the dual-boot menu was stored on that system. Following the instructions on the Microsoft article, I ran the Bootrec.exe utility with each of the switches, each time testing using the /ScanOs switch. It kept showing that there were 0 Windows installations.

But I crossed my fingers and rebooted anyway. Lo and behold -- it worked! One or more of the switches fixed it. I booted into Windows, logged in, and Windows automatically downloaded and installed the latest drivers for my system -- including dual displays.

08 October 2010

Java JDK installation on Windows

Installing Java on Windows for development can be one of the trickier things, especially if you're looking for Java 1.5 vs. 1.6: Java 1.5 is not readily available for download. However, some digging reveals this great site with a link to the download (which requires registration). From there, you can find the 32- and 64-bit versions of the Windows' installers.

09 September 2010

Watch out Java, here comes JavaScript

http://www.infoworld.com/d/developer-world/watch-out-java-here-comes-javascript-799
The benefits of JavaScript as a server-side language are clear and striking. It allows Web application developers to implement their entire code base using a single syntax, reducing the clutter and confusion of typical Web apps. JavaScript's performance is increasing at a breakneck pace, which has built-in benefits for developers. Its event-driven programming model makes building parallel applications easy and logical. And JavaScript itself has matured into a fine language, with features that support both the object-oriented and functional programming styles.

Windows 7 E-Learning Series

http://technet.microsoft.com/en-ca/itmanagement/ff742808.aspx

Migration From Windows XP to Windows 7






Get Microsoft Silverlight

08 September 2010

40 Free Vector Graphics for your Print Media Designs

http://www.tutoriallounge.com/2010/09/40-free-vector-graphics-for-your-print-media-designs/

Get Virtual PC to see your localhost on Windows 7

I use Virtual PC to test on IE7 and need it to see the host machine's localhost (IP address). This is disabled by default via the Win 7 firewall. You can re-enable it by following these steps:
  1. On the host machine, open the Control Panel and choose the Windows Firewall.
  2. In the firewall, go to "Allow a program or feature through Windows Firewall."
  3. In the "Allowed programs and features" list, scroll down to "World Wide Web Services (HTTP) and check the box under "Domain."
  4. Click OK
Now go to Start and type cmd into the search box. This will bring up the command window. Type ipconfig and hit enter to see your machine's IP address. Now, back in the Virtual PC's IE window, type the IP address, followed by the path to your app. For example, if you access the app via http://localhost/myapp/mypage.htm, you'd type this in the Virtual PC's IE address: http://000.000.000.000/myapp/mypage.htm (replace the 0's with your IP address).

Preparing for HTML5

Turn a Photoshop layout into a working web page faster than ever

31 August 2010

Joomla: Read custom article parameters from a module

In implementing a web site on Joomla, I came across a common issue: I needed to pass additional parameters with an article into a 3rd-party module. In this case, the module was the Joomla AnythingSlider, a very slick and flexible content slider/carousel.

The initial task of creating the custom parameters wasn't so bad; the first thread in this post covers that. You add the parameter to the advanced section of the file administrator/components/com_content/models/article.xml:

<param name="article_type" type="radio" default="default" 
label="Article Type" description="article type">
<option value="default">Default</option>
<option value="picture">Picture (rotator)</option>
<option value="video">Video (rotator)</option>
</param>
However, reading the values in a module is a different story. Here's the syntax to fetch all the parameters from article.xml:
$paramsdefs = JPATH_COMPONENT.DS.'models'.DS.'article.xml';
$myparams = new JParameter( $paramsdata, $paramsdefs );
And here's how a specific custom parameter is read (in this case, it's called article_type):
echo "Article type: ". $myparams->get('article_type');
This is thanks to another reply to the same post on the Joomla forums, but page 2.

UPDATE:
A good quested was raised about one of the variables used in the above code: $paramdata. Where was it defined? Well, it's not in the above code, but in the AnythingSlider Joomla extension, mod_anythingslider; you can download it from here.

The mod_anythingslider has a helper.php file, which defines the class ModSlideShow:
<?php
/**
* AnythingSlider Helper Classes
*
* @package Joomla 1.5.0
* @subpackage Modules
* @Copyright Copyright (c)2010 Dnote Software
* @license GNU/GPL, see http://www.gnu.org/copyleft/gpl.html
*
* mod_anythingslider is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* Parts of this software are based on AnythingSlider By Chris Coyier: http://css-tricks.com
**/

defined('_JEXEC') or die('Direct Access to this location is not allowed.');

class ModSlideShow
{
/**
* Returns a list of articles
*/
function getSlideshow(&$params, &$access)
{
global $mainframe;

$db =& JFactory::getDBO();
$user =& JFactory::getUser();
$aid = $user->get('aid', 0);

$catid = (int) $params->get('catid', 0);
$items = (int) $params->get('items', 0);

$contentConfig = &JComponentHelper::getParams( 'com_content' );
$noauth = !$contentConfig->get('show_noauth');
$date =& JFactory::getDate();
$now = $date->toMySQL();

$nullDate = $db->getNullDate();

// Ordering
switch ($params->get( 'ordering' ))
{
case 'o_asc':
$ordering = 'a.ordering';
break;
case 'o_dsc':
$ordering = 'a.ordering DESC';
break;
case 'm_dsc':
$ordering = 'a.modified DESC, a.created DESC';
break;
case 'c_dsc':
default:
$ordering = 'a.created DESC';
break;
}

// query to determine article count
$query = 'SELECT a.*,' .
' CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(":", a.id, a.alias) ELSE a.id END as slug,'.
' CASE WHEN CHAR_LENGTH(cc.alias) THEN CONCAT_WS(":", cc.id, cc.alias) ELSE cc.id END as catslug'.
' FROM #__content AS a' .
' INNER JOIN #__categories AS cc ON cc.id = a.catid' .
' INNER JOIN #__sections AS s ON s.id = a.sectionid' .
' WHERE a.state = 1 ' .
($noauth ? ' AND a.access <= ' .(int) $aid. ' AND cc.access <= ' .(int) $aid. ' AND s.access <= ' .(int) $aid : '').
' AND (a.publish_up = '.$db->Quote($nullDate).' OR a.publish_up <= '.$db->Quote($now).' ) ' .
' AND (a.publish_down = '.$db->Quote($nullDate).' OR a.publish_down >= '.$db->Quote($now).' )' .
' AND cc.id = '. (int) $catid .
' AND cc.section = s.id' .
' AND cc.published = 1' .
' AND s.published = 1' .
' ORDER BY '.$ordering ;
$db->setQuery($query, 0, $items);
$rows = $db->loadObjectList();

return $rows;
}

}
?>
Then in the mod_anythingslider.php, we define a few more variables:
$params->set('intro_only', 1);
$params->set('hide_author', 1);
$params->set('hide_createdate', 0);
$params->set('hide_modifydate', 1);

// Disable edit ability icon
$access = new stdClass();
$access->canEdit = 0;
$access->canEditOwn = 0;
$access->canPublish = 0;
// Other code here...
$slideShow = ModSlideShow::getSlideshow($params, $access);
Now we bring it all together in the default.php, which generates the HTML for the slider:
/* 
Variables used throughout the main foreach loop.
Don't define these in the loop b/c they'll get
created for each article in the carousel.
*/
$paramsdefs = JPATH_COMPONENT.DS.'models'.DS.'article.xml';
$limitstart = JRequest::getVar('limitstart', 0, '', 'int');
$dispatcher =& JDispatcher::getInstance();

/*
Main foreach loop of the carousel component. Runs
once for each article in the slideshow.
*/
foreach ($slideShow as $item){
echo "<li>";
$aparams =& $item->parameters;
$params->merge($aparams);

$item->text = $item->introtext;
$results = $dispatcher->trigger('onPrepareContent', array (& $item, & $params, $limitstart));

$paramsdata = $item->attribs;
$myparams = new JParameter( $paramsdata, $paramsdefs );
$article_type = $myparams->get('article_type');
// More processing inside the foreach...
}
Hope this helps those confused by the $paramdata variable.

Add Finger-Swipe Support to Webpages

http://padilicious.com/code/touchevents/

27 August 2010

Multiple $(document).ready()

A page can contain multiple jQuery calls to the $(document).ready() function. This comes in handy if you're generating code at run-time or mixing static JavaScript with code generated via PHP or other server-side language. In addition, you can abbreviate the call to:
$(function() {
// do something on document ready
});

How to find element based on a string

Say you're looking for a string in the HTML and wish to get the parent element(s) that contains it. This Stackoverflow.com thread covers the technique, using a wildcard ("*") for all page elements. You can narrow it down by using a specific element type ("div" for example) instead of the wildcard.

40 New JavaScript Tutorials with Helping Techniques

http://www.tutoriallounge.com/2010/08/40-new-javascript-tutorials-with-helping-techniques/

jQuery loading remote/external javascript files using getScript()

http://colourgray.wordpress.com/2008/09/22/jquery-loading-external-javascript-files-using-getscript/

20 Methods for Upping Your Current Web Design Skills

http://www.onextrapixel.com/2010/08/24/20-methods-for-upping-your-current-web-design-skills/

Slideshowify: Ken Burns Slideshow Effect as a jQuery Plugin

http://www.subchild.com/2010/06/10/ken-burns-effect-as-a-jquery-plugin-slideshowify/

Extensible Autocomplete

http://blog.jqueryui.com/2010/08/extensible-autocomplete/

Sortable, Resizable, Editable HTML Table With TableKit

http://www.greepit.com/2010/08/sortable-resizable-editable-html-table-with-tablekit/

26 August 2010

Add Quick Launch bar to Windows 7

The Quick Launch feature can be recreated in Windows 7, though why it's hidden is puzzling. This article provides step-by-step instructions on how to do this and even position it on the left, next to the start button.

22 August 2010

Learning RDFa

A great resource for learning RDFa.

20 August 2010

W3C cheatsheet

A nice cheatsheet from the good people at W3C on developing for mobile, accessibility, i18n, and typography.

19 August 2010

Quick Tip: An Introduction to Sammy.js

This tutorial introduces the Sammy.js, a useful jQuery library for writing RESTful evented JavaScript applications.

18 August 2010

SpriteMe: Automated CSS sprite creation

CSS sprites (sometimes referred to as "sliding doors") provide a nifty way to minimize the number of images site visitors have to download. However, creating them can be tricky. The powerful SpriteMe tool comes to the rescue.

Just save this link as a bookmark then go to a page and launch the bookmark. Easy, right?

17 August 2010

Top Free Script Fonts On The Web

http://webexpedition18.com/articles/top-free-script-fonts-on-the-web/

25 Fantastic jQuery Techniques and Effects For Creating Awesome Websites

http://artatm.com/2010/08/25-fantastic-jquery-techniques-and-effects-for-creating-awesome-websites/

Disappearing background image in the Web Developer plug-in for Firefox

One of the most powerful ways to view and edit the CSS of web sites on Firefox is the Web Developer extension. However, I recently noticed that when I selected Edit CSS from the extension's toolbar, the background images on the page disappeared.

Some research revealed a good thread on this issue. The problem had to do with the "../" notation in the stylesheet; changing these to be relative to the site root fixed the problem. For example, this:
background: transparent 
url(../img/bg.png) no-repeat 0 0;
becomes this:
background: transparent 
url(/cms_prd/global/img/bg.png) no-repeat 0 0;
This is assuming that the background image is here:
http://localhost/cms_prd/global/img/bg.png

30 Inspiring and Well Designed Website Footers

http://designtutorials4u.com/30-inspiring-and-well-designed-website-footers/

ASP.NET health monitoring

http://msdn.microsoft.com/en-us/library/bb398933.aspx

Adobe & Typekit team up on Web font delivery

http://blogs.adobe.com/jnack/2010/08/adobe-typekit-team-up-on-web-font-delivery.html

03 August 2010

How to install Joomla on Windows

For development purposes, I needed Joomla installed on my Windows XP system. However, Joomla has some infrastructure requirements often not found on Windows boxes. Here are some steps on how to successfully install Joomla on your PC:
  1. Download the XAMPP for Windows package. I downloaded the EXE and installed it at the root C: in the XAMPP folder.
  2. If you also have IIS running on your system, after the installation, change the default port used by Apache.
  3. The XAMPP installation will automatically ask you if you want to launch its control panel. If it's not already running, go to Start > XAMPP for Windows > XAMPP Control Panel.
  4. Click to start the Apache and MySql services (if they're not already running). When they successfully start, you'll see a green indicator saying "Running" next to each service. [Note: If the services take too long to start, it's more than likely because port 80 is being used by IIS; follow Step 2 above to change the Apache port to something else and try to start the services again.]

  5. Download the latest version of Joomla.
  6. Create a folder named joomla under C:\xampp\htdocs\
  7. Unzip the contents of the Joomla ZIP file into this new folder.
  8. Open your browser and navigate to http://localhost/ or, if you changed the Apache port, to http://localhost:xx/, where xx is the port number you assigned to Apache in Step 2.
  9. Click the phpMyAdmin link and go to "Privileges" on the MySQL database.
  10. Choose "Add a new User" and give it a name and password you can remember.
  11. Under "Global privileges" for this user, click "Check All" to grant all rights to this user.
  12. Click Go to create the user.
  13. Go to the Databases tab and create a database for Joomla (could be called joomla).
  14. Open your browser and navigate to http://localhost/joomla/ or, if you changed the Apache port, to http://localhost:xx/joomla/, where xx is the port number you assigned to Apache.
  15. Follow the wizard until you get to the database screen. Here, enter the information for the database and user you just created. For the host, use localhost. Important: Do not enter the port number after the host name, such as localhost:xx because this will not work and it won't generate an error; enter only the word localhost into the Host Name field.
  16. Upon successful completion, Joomla asks you to delete the installation folder. Go ahead and do that.
  17. To see the Joomla home page, reload http://localhost/joomla/ or, if you changed the Apache port, http://localhost:xx/joomla/, where xx is the port number you assigned to Apache.



Additional resources on installing Joomla with XAMPP on Windows and other platforms can be found on the Joomla docs site.

Scr.im: Email Address Shortener

http://scr.im/

30 July 2010

Favorite Google search tips

http://www.google.com/landing/searchtips/

29 July 2010

Firefox Environment Backup Extension

Back up Firefox profiles on Mac, Windows, and Linux with this handy plugin.

Joomla 1.6 Templates: What Designers Should Know

http://www.s-go.net/index.php/s-go-blog/261-joomla-16-templates-what-designers-should-know

Become the next Photoshop evangelist

http://www.nextphotoshopevangelist.com/

ASP.NET 4 and Visual Studio 2010 Web Forms

http://www.devsource.com/c/a/Languages/ASP-NET-4-Web-Forms-2134/

45 Great Examples of V-card Designs

http://inspirationfeed.com/2010/06/45-great-examples-of-v-card-designs/

45+ jQuery Based Wordpress Plugins and Tutorials

http://www.themeflash.com/45-jquery-based-wordpress-plugins-and-tutorials/

How to Create Glass Effect Text in Photoshop

http://www.designioustimes.com/tutorials/how-to-create-glass-effect-text-in-photoshop.html

Joomla 1.6 tutorial videos

What's new in Joomla 1.6 from Andrew Smith on Vimeo.


Joomla 1.6 — For Developers from Andrew Smith on Vimeo.

Tiny and Free Utility System Spec Reveals Your System's Secrets

http://www.pcworld.com/article/201302/tiny_and_free_utility_system_spec_reveals_your_systems_secrets.html

15 July 2010

20 Free Fonts Ideal For Logos And Headings

http://bluefaqs.com/2010/07/20-free-fonts-ideal-for-logos-and-headings/

28 Useful Front End Web Developer Cheat Sheets

http://smashinghub.com/useful-front-end-web-developer-cheat-sheets.htm

25 Wonderful PSD’s from 365psd.com (#2)

http://www.markedlines.com/25-wonderful-psd%e2%80%99s-from-365psd-com-2/

Achieving Visual Sharpness in Design and Art with Photoshop

http://design.creativefan.com/achieving-visual-sharpness-in-design-and-art-with-photoshop/

baseJS: A Mobile JavaScript Framework

http://paularmstrongdesigns.com/weblog/basejs-a-mobile-javascript-framework/

19 Impressive, Stunning and Simple Web Sites

http://www.designshard.com/inspiration/19-impressive-stunning-simple-web-sites/

35 Fresh Examples Of Creative Web Design

http://www.bestfreewebresources.com/2010/07/creative-web-design.html

CSS3 Features Support for Internet Explorer: PIE

http://www.greepit.com/2010/07/css3-features-support-for-internet-explorer-pie/

14 July 2010

Opera and the OGG video - source location matters

I've recently been working on implementing HTML5 video on a new web site. The challenge I ran into yesterday was to get the OGG video to display on Opera 10.54. Using the following error handler, I found out what the problem was, but couldn't get any closer to a solution:
 function failed(e) {
// video playback failed - show a message saying why
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
alert('You aborted the video playback.');
break;
case e.target.error.MEDIA_ERR_NETWORK:
alert('A network error caused the video download to fail part-way.');
break;
case e.target.error.MEDIA_ERR_DECODE:
alert('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.');
break;
case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
alert('The video could not be loaded, either because the server or network failed or because the format is not supported.');
break;
default:
alert('An unknown error occurred.');
break;
}
}
Here's the video tag:
<video  id="vid-2" width="372" height="209" 
poster="global/img/farmfresh.jpg" controls
onPlaying="stopSlider()" >
<source class="source" src="global/vid/farmfresh.ogg" type='application/ogg'
onError="failed(event)">
<source class="source" src="global/vid/farmfresh.mov">
<source class="source" src="global/vid/farmfresh.m4v" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
<img src="global/img/farmfresh2.jpg" title="North Carolina Farm Fresh: Monday, April 29 at 9:30 PM"/>
</video>
The problem was the location of the OGG source tag; for Opera, the OGG video has to be the first if you have multiple source elements. Now Opera is happy as well as the other browsers.

13 July 2010

30+ Very Useful HTML5 Tutorials, Techniques and Examples for Web Developers

http://www.tripwiremagazine.com/2010/07/30-very-useful-html5-tutorials-techniques-and-examples-for-web-developers.html

23 Essential HTML 5 Resources

http://carsonified.com/blog/dev/html-5-dev/23-essential-html-5-resources/

Summit: Mobile computing is education’s future

http://www.eschoolnews.com/2010/06/21/summit-mobile-computing-is-educations-future/
"Keynote speaker Peggy Johnson, executive vice president of Qualcomm Inc., pointed to a successful initiative in North Carolina, called Project K-Nect, that uses mobile phones to help teach algebra as an example of how mobile technology can empower learning.

"At-risk ninth graders taking part in the project have access to specially created mobile applications that help explain algebraic principles, and they also can watch videos of other students explaining these principles. In addition, they can text or IM their peers for advice when they get stuck.

"According to early studies of the program’s efficacy, students taking part in this Qualcomm-funded project outscored their peers who did not have access to the mobile phones and content by an average of 30 percent in algebra proficiency."

12 July 2010

Explaining JavaScript scope and closures

Closures are a critical part of JavaScript libraries; this tutorial explains scope and closures: http://robertnyman.com/2008/10/09/explaining-javascript-scope-and-closures/

Another great article on the same subject from the always impressive SmashingMagazine.com: http://www.smashingmagazine.com/2009/08/01/what-you-need-to-know-about-javascript-scope/

And more here: http://blog.morrisjohns.com/javascript_closures_for_dummies.html

How to use HTML5 on your website today

http://www.infoworld.com/d/applications/how-use-html5-your-website-today-220

Why SQL Server is better than any other RDBMS applications?

Pinal Dave has a question on his blog: "Why SQL Server is better than any other RDBMS applications?" Here's my two cents.

I learned RDBMS on SQL Server 2000 back in 2002; picked up a book and read it until the pages came out. It was an easy-to-use, developer-friendly relational database, which tied nicely to classic ASP. I wrote tons of stored procedures from the start, and avoided using ad hoc queries — and never had any security issues.

For a university’s online directory that needed quick response and tons of features, I wrote the entire search engine in a SQL Server stored procedure, with additional user-defined functions. At the time, the school’s data was in flat files stored on OpenVMS. I used a nightly DTS to pull the data and ran cleanup procedures to store it on SQL Server. All of this with great ease. And lets not forget: There’s not an equivalent of DTS/SSIS on Oracle. Going back to SQL Server 2000, this has been a powerful feature of the database, making developers’ lives easier.

For the same directory project, I needed to provide users with the option to leave multiple fields blank and allow searches on any combination of values they provided. The handy “coalesce” function made this a snap. I posted to SQL Server forums and got great help on how to accomplish this. The final SELECT statement looks beastly, but it’s quick and efficient. This was long before Oracle supported the “coalesce” function.

Also, I constantly used the IF EXISTS (SELECT *…) in my stored procedures and user-defined functions. Believe it or not, Oracle still doesn’t have a direct equivalent of this easy feature. If you wanted to insert a row but wanted to check that it didn’t already exist, you’d simply do an IF EXISTS. Easy and intuitive. This is much harder in Oracle.

In addition, the ease of using stored procedures with web apps makes SQL Server a web developer’s best friend. It took us over 2 weeks to get Oracle working with ASP.NET; SQL Server worked with it like a breeze. And the syntax was easy too. If you’ve connected Oracle stored procedures to ASP.NET apps, it’s not a trivial task. We had to install a 200Mb data provider to talk to Oracle. Not my idea of easy.

Moreover, SQL Server installs and runs smoothly with the Visual Studio development suite. SQL Server comes with the Management Studio tool built-in; you often buy extra utilities to get the same functionality out of other RDBMS.

With Oracle, you have to set up TNS files and ensure they have the correct settings on development and production. With SQL Server, you don’t have to worry about any of this.

Reporting tools? Built into SQL Server. As far back as 2002, you could purchase an inexpensive ($5, if I remember correctly) add-on from Microsoft to enable reporting capabilities. Today, the SSRS tool is robust, easy to use, and also developer-friendly. For years I was trying to convince my boss to go with SSRS; she finally went to a conference and saw how powerful it was and she was sold. Instead of a third-party tool that kept crashing daily, the university went with a product that users, admins, and developers love.

10 July 2010

Create your own online AR 3D storybooks

http://www.webkitchen.be/2010/07/07/create-your-own-online-ar-3d-storybooks/

Automate a Large Project with InDesign and Data Merge

http://www.creativebeacon.com/automate-a-large-project-with-indesign-and-data-merge/

The 9 best (and free) cross-browser testing tools

One common problem for web developers is how to test their sites with the different versions of browsers and platforms. Because IE is often the most troublesome, I start with those:
  • Internet Explorer Application Compatibility VPC Image: Virtual PC VHD files with the browser preinstalled. A Windows-centric solution, but provides the most comprehensive testing solution. To use, you'll need the free Virtual PC app; then create a new VMC and point it to one of the downloaded VHD files above.
  • MultipleIE: Another Windows-only tool, which provides a way for IE3 IE4.01 IE5 IE5.5 and IE6 to run on the same box. I've had some limited success with this; the browsers can be very temperamental (that is, they can crash without notice).
  • Spoon Browser Sandbox: Run different versions of browsers from the web without having to install them on your machine. Though I've not yet used Spoon, it holds great promise.
  • Adobe BrowserLab: Upload your pages securely to this Flex app and view snapshots of what they look like on different browsers. This tool is built into Dreamweaver CS5 and holds great potential for easing the testing process.
  • BrowserShots.org: Free and comprehensive alternative to BrowserCam, generates screenshots of your design in an incredible list of browsers and platforms. Because the tool is free, a lot of developers use it. For best results, limit your testing to just a few browsers; this speeds up the results.
  • IETester: Free browser for testing pages against IE 5.5 - 9. It's relatively new but holds promise.
  • NetRenderer: Choose IE version and enter a URL -- it's that simple.
  • iPhoney: Free tool for testing designs on the iPhone.
  • iPad Seek: Online tool to test your designs on the iPad in a similar fashion to iPhoney.

08 July 2010

Getting JW HTML5 Player to work on IE

In my continuing adventures with HTML5 video, I arrived at IE testing, and noticed that IE does not like the JW HTML5 Player (mainly because it's in beta right now). But I have to demo my site and can't wait until Version 1.0 of the player; so, I rolled up my sleeves for another non-trivial challenge.

The problem is that the current versions of IE can't display the HTML5 video tag; IE 9 will address this, but we'll be living with lower versions for some years. And the beta JW HTML5 Player doesn't remove the video tag completely from IE. The answer is to do some jQuery coding to find the video tags and replace them with swfobject elements. There are plenty of gotchas along the way as to file paths and filenames.

Here's the finished code:
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js">
</script>

<script type="text/javascript">
$(document).ready(function(){
// If this is IE...
if (jQuery.browser.msie){
var el = "";
var vidFileName = "";
var posterPath = "";
var videoTag = "";
var boxId = "";
var so = "";
var flashId = "";
var flashVars = "";
var params = "";
var attributes = "";
var anchorId = "";

// For each video element...
$("[id^='vid-']").each(function(){
// Clear out the variables.
el = "";
vidFileName = "";
posterPath = "";
videoTag = "";
flashId = "";
flashVars = "";
params = "";
attributes = "";
anchorId = "";

// Get a handle to the current object.
el = $(this);

// Set some variables we'll shortly.
boxId = this.id + "_flashBox";
flashId = this.id + "_flashPlayer";
anchorId = this.id + "_anchor";

/*
Set the ID of the first DIV element of the current
object's parent's parent. This will allow us to
reference that DIV later.
*/
el.parent().parent().find("div:first").attr("id",boxId);

/*
Loop over each 'source' tag inside the video; check
the 'source' tag's 'src' attribute. If it contains
'm4v' or 'mp4', then it's usable for the Flash
player in IE.
*/
el.parent().children("source").each(function(){
if ($(this).attr("src").indexOf("m4v") != -1 ||
$(this).attr("src").indexOf("mp4") != -1){
/*
We don't need the filename + path of the video,
only the filename. So we remove the path and
fetch only the filename.
*/
vidFileName = $(this).attr("src").substring($(this).attr("src").lastIndexOf("/")+1);
}
});

// Get the poster's filename and path.
posterPath = el.parent().find("img").attr("src");


// Get a reference to the video's containing DIV.
el = $("[id="+boxId+"]");

// Empty the DIV of all contents.
el.empty();

/*
Append an anchor tag with the anchor ID to the DIV.
We'll replace this anchor tag with the Flash player.
*/
el.append("<a id='" + anchorId + "'></a>");

// Set flashvars, params, and attributes.
flashvars =
{
file: vidFileName,
autostart: 'false',
image: posterPath
};

params =
{
allowfullscreen: 'true',
allowscriptaccess: 'always',
wmode: 'opaque'
};

attributes =
{
id: flashId,
name: flashId
};

/*
Embed the Flash player object using the swfobject.
The embedSWF() method replaces the anchorId element
with the Flash player. For more information on the
various arguments, please see the documentation here:
http://code.google.com/p/swfobject/wiki/documentation
*/
swfobject.embedSWF('global/vid/player.swf', anchorId, '372',
'209', '9.0.124', false, flashvars, params, attributes);
});
}
});
</script>
One gotcha with swfobject: You need to ensure the path of the 'file' that you wish to play is relative to the player.swf or you'll get an error saying 'Can't find file or access denied.' This thread talks about the issue.

In addition, you'll need to add the following to the page to prevent IE from throwing an error:
if (!jQuery.browser.msie){
$('video').jwplayer({
flashplayer:'global/js/jwplayer/player.swf',
skin:'global/js/jwplayer/five/five.xml'
});
}
This ensures that the JW HTML5 Player is fired off only on non-IE browsers. My previous post on HTML5 video and the JW Player has links to all my other posts on the subject.

UPDATE: Please see part 2 of this post for how to get the release version of the player working on IE and other browsers.

01 July 2010

Tracking the Real-Time Color Trends

http://www.colourlovers.com/trends

48 Best Creative, SEO, Marketing & Freelance Bookmarks – June 2010

http://joannaciolek.com/wordpress/best-creative-seo-marketing-freelance-bookmarks-june-2010

HTML5 Charting & Data Visualization Tool: HumbleFinance

http://www.greepit.com/2010/06/html5-charting-data-visualization-tool-humblefinance/

YouTube backs Adobe Flash over HTML5

http://www.infoworld.com/d/developer-world/youtube-backs-adobe-flash-over-html5-849
"While HTML5's video support enables us to bring most of the content and features of YouTube to computers and other devices that don't support Flash Player, it does not yet meet all of our needs," said YouTube software engineer John Harding in the post. "Today, Adobe Flash provides the best platform for YouTube's video distribution requirements."

Automatically put HTML5 videos in Fancybox

Here's a tricky one: Safari 5 and the iPad have issues with HTML5 video tags if those objects move. They show "black holes" on the screen, especially inside content rotators. Solution? Do a "popup" (via Lightbox, Fancybox, etc.) to handle the video, while leaving the video as is on the other browsers.

Adding to the complexity of the problem is the fact that Safari strips off the poster attribute from the video tag; not sure why. So I ended up using an img inside the video tag; we'll see the reason below. Here's the video tag as it appears in the HTML; the closing source tags are to prevent IE from throwing an error:
<video  id="vid-1" width="372" height="209"
poster="global/vid/historydetectives-poster.jpg" controls onPlaying="stopSlider()">
<source src="global/vid/historydetectives.mov"></source>
<source src="global/vid/historydetectives.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'></source>
<source src="global/vid/historydetectives2.ogg" type='application/ogg'></source>
<img src="global/vid/historydetectives-poster.jpg" />
</video>
To get Safari/iPad to pop these up in a Fancybox, we follow these steps:
  1. Loop over all the video tags on the page. In this case, their IDs all start with "vid-".
  2. Get each video's HTML; for this we have to get the parent element.
  3. Get the img tag's src attribute (Safari stripped out the poster attribute on the video tag).
  4. Generate some HTML for a linked image, with its src set to the img tag above.
  5. Ensure the link has a unique ID.
  6. Replace the video tag with the generated HTML.
  7. Instantiate a Fancybox for the video and set its content to the video's HTML.
Here's the code:
$(window).load(function () {
if (jQuery.browser.safari) {
var videoTag = "";
var posterPath = "";
var replacement = "";
var boxId = "";
var el = "";

/* Fetch all the video tags with ID
starting with 'vid-'.
*/
$("[id^='vid-']").each(function(){
// Extra precaution: reset variables.
videoTag = "";
posterPath = "";
replacement = "";
boxId = "";
el = "";

// Get a reference to this element.
el = $('[id='+this.id+']');

/*
To get the enclosing video tag,
fetch the parent's HTML.
*/
videoTag = el.parent().html();

/*
Get the path to the video's poster image.
Safari strips off the poster attribute, so
we use an image within the video tag to hold
the image path.
*/
posterPath = el.parent().find("img").attr("src");

/*
We're manually instantiating and setting
properties on a Fancybox, so we add "_manual"
to the ID.
*/
boxId = this.id + "_manual";

/*
Concatenate some HTML: We'll create an image tag
with its source set to the image tag inside the video.
Wrap it in an anchor tag and set its ID to what we
created above so we can attach it to the Fancybox.
*/
replacement = "<a title='' id='" + boxId +
"' href='javascript:;'><img src='" +
posterPath + "' style='float:left; padding-left:5px; '/></a>";

/*
Replace the video element with the concatenated HTML
we just created.
*/
el.parent().replaceWith(replacement);

/*
Instantiate a Fancybox and attach it to the
linked image. Set its 'content' to the video
tag's HTML.
*/
$("[id="+boxId+"]").fancybox(
{
'content' : videoTag,
'autoDimensions' :true,
'padding' : 9,
'showCloseButton' : true,
'enableEscapeButton': true
}
); // end click function
}); // end each function
} // end if
else {
/*
This next line is needed only if we use an HTML5 video
player library (such as JW HTML5 Player from LongTail
Video). These libraries often include their own controls
and if we don't remove the 'controls' attribute from
the video tag, the other HTML5-ready browsers produce
"double" controls. We're including the 'controls'
attribute on the video tag for the iPad to be happy;
without that attribute, the video pops up with a black
screen on Fancybox. So we strip it from the video tag.
*/
$("[id^='vid-']").each(function(){
$('[id='+this.id+']').removeAttr("controls");
});
} // end else
} // end load function
One other caveat: We can't call the following in the each function:
$("[id="+boxId+"]").click(function()
{
$.fancybox( ....
The reason? We need to instantiate a Fancybox for each of the videos.

I've documented additional adventures and solutions with the content rotator and HTML5 video in these posts:

25 June 2010

A GPU-Powered HTML5 Flickr Photo Viewer

http://blogs.msdn.com/b/ie/archive/2010/06/03/a-gpu-powered-html5-flickr-photo-viewer.aspx
Flickr Explorer is written using standard HTML, CSS and JavaScript. It uses AJAX to asynchronously search Flickr based on your search terms and display image results through an interactive and visually compelling experience. You can zoom in, pan around, and open each photo’s Flickr page with by control+clicking.

WebGL - OpenGL ES 2.0 for the Web

http://www.khronos.org/webgl/
WebGL is a cross-platform, royalty-free web standard for a low-level 3D graphics API based on OpenGL ES 2.0, exposed through the HTML5 Canvas element as Document Object Model interfaces.

What's New in C# and .NET 4

http://www.devsource.com/c/a/Using-VS/ASPNet-4-Enhances-With-New-CLR-and-More-123145/

Text To Speech in C# (with Talking Browser!)

http://www.devsource.com/c/a/Languages/Text-To-Speech-in-C-with-Talking-Browser/

22 June 2010

OpenLayers: Free Maps for the Web

http://openlayers.org/

.NET: String.IsNullOrWhiteSpace Method

http://msdn.microsoft.com/en-us/library/system.string.isnullorwhitespace%28VS.100%29.aspx
Indicates whether a specified string is Nothing, empty, or consists only of white-space characters.
Handy little static method added in .NET 4.0, used in this way:
using System;

public class Example
{
public static void Main()
{
string[] values = { null, String.Empty, "ABCDE",
new String(' ', 20), " \t ",
new String('\u2000', 10) };
foreach (string value in values)
Console.WriteLine(String.IsNullOrWhiteSpace(value));
}
}
// The example displays the following output:
// True
// True
// False
// True
// True
// True

JavaScript: === vs ==

http://msmvps.com/blogs/luisabreu/archive/2009/08/25/vs.aspx

clickoutside jQuery plugin

http://www.stoimen.com/blog/2010/02/17/clickoutside-jquery-plugin/

Change the Viewport, be Ready for the iPhone!

http://www.stoimen.com/blog/2010/03/10/change-the-viewport-be-ready-for-the-iphone/

CSS Priority: The Difference Between a.my-class and .my-class

http://www.stoimen.com/blog/2010/03/11/css-priority-the-difference-between-a-my-class-and-my-class/

Open Source JavaScript Slider Component

A very cool slider component that is mobile-aware: http://www.webappers.com/2010/06/15/open-source-javascript-slider-component/

Latest Web Design Trends — Afresh Inspiration From the Print

http://www.webappers.com/2010/06/22/latest-web-design-trends-%e2%80%94-afresh-inspiration-from-the-print/

Solution for AnythingSlider and duplicate IDs

If you ever use the JW Player inside the AnythingSlider, and you place a video in the last panel of your UL list, you'll run into a pesky and non-trivial headache: The AnythingSlider automatically duplicates the last "panel" -- so it duplicates the video tag. This code fixes it by looking for the duplicate ID of my video tag (all my video tags start with "vid-") and renaming the ID to something random:
$(window).load(function () {
$('[id]').each(function(){
var ids = $('[id='+this.id+']');
if(ids.length>1 && ids[0]==this){
if (this.id.indexOf("vid-") != -1){
this.id = this.id + "_" + Math.floor(Math.random()*11);
console.warn('Multiple ID #'+this.id);
}
}
});
});
All the browsers that will need to use the Flash fallback player will now work correctly. Of course, you'd need to change the "vid-" to the start of whatever ID you've given your video tag. This issue may also manifest itself in other situations where duplicate IDs are not desirable.

HTML5 Canvas tag JavaScript library

http://processingjs.org/
Processing.js is an open programming language for people who want to program images, animation, and interactions for the web without using Flash or Java applets. Processing.js uses Javascript to draw shapes and manipulate images on the HTML5 Canvas element. The code is light-weight, simple to learn and makes an ideal tool for visualizing data, creating user-interfaces and developing web-based games.

jQuery.Preload

http://flesler.blogspot.com/2008/01/jquerypreload.html

15 Amazing jQuery Image Gallery/Slideshow Plugins and Tutorials

http://speckyboy.com/2009/06/03/15-amazing-jquery-image-galleryslideshow-plugins-and-tutorials/

jScrollPane - cool block-level scroller

http://www.kelvinluck.com/assets/jquery/jScrollPane/jScrollPane.html

The Top: 12 Best jQuery Image Galleries

http://www.devlounge.net/design/the-top-12-best-jquery-image-galleries

AJAX Image Gallery powered by Slideflow (like Cover Flow)

http://mediaeventservices.com/blog/2007/11/15/ajax-image-gallery-powered-by-slideflow-like-cover-flow/

Convert text to ASCII

http://getyourwebsitehere.com/jswb/text_to_ascii.html

Free Download: 70 Excellent Notepapers and Sticky notes

http://www.psdrockstar.com/collections/free-download-70-excellent-notepapers-and-sticky-notes/

Great and free stock photos

http://www.sxc.hu/

Sticker Edge Peel

http://pshero.com/photoshop-tutorials/graphic-design/sticker-edge-peel

21 June 2010

How to stop AnythingSlider from code

I covered this as part of a post on HTML5 video, but wanted to give it its own article here because a lot of folks have run into the issue: How do you stop the AnythingSlider by using JavaScript? The answer isn't as intuitive as it should be.

A somewhat related question on StackOverflow.com provided a part of the answer:
$("div.anythingSlider a#start-stop").trigger("click");
However, that solution toggles the current state of the "start-stop" by triggering the click action. Here's a complete solution. Assuming that the startText has been set to "Go", this function will stop the AnythingSlider:
function stopSlider(){
// This is a way to "cache" the element and not have
// to fetch it again and again.
var el = $("div.anythingSlider a#start-stop");
// Loop while triggering the click action on the element.
while (1 == 1){
el.trigger("click");
// If the HTML of the element contains "Go", then
// it's stopped and we can break out of the loop.
if (el.html().indexOf("Go") != -1) break;
}
}
The code triggers the "click" on the "start-stop" element, checking after each click to see if the HTML of the element contains the word "Go"; if it does, it break out of the loop. Of course, you'll have to modify it if you're using text other than "Go" on the "start-stop" anchor tag.

18 June 2010

Online JavaScript compressor

http://javascriptcompressor.com/

Event handler for HTML5 video

I'm using the HTML5 video tag inside the AnythingSlider. An interesting problem arose: How do you stop the AnythingSlider when the user starts playing the video? You don't want the slider to keep going in this situation.

Well, here's a solution. The HTML5 video events are described in the "4.8.9.12 Event summary" section of the W3C document. At first, you'd guess that you'd use the onPlay event handler. Nope. That only works when you play the video the first time; on the second play, it won't call the function. The event handler to use is onPlaying.

But how do you stop the AnythingSlider programmatically? The good folks on StackOverflow.com provided the answer.

So here's the video tag:
<video controls preload onPlaying="stopSlider()">
....
</video>
And here's the function to stop the AnythingSlider:
function stopSlider(){
while (1 == 1){
$("div.anythingSlider a#start-stop").trigger("click");
if ($("div.anythingSlider a#start-stop").html().indexOf("Go") != -1)
break;
}
}
Note what appears to be an infinite while loop: Actually, the code is designed to stop the AnythingSlider. It triggers the "click" on the "start-stop" element, checking after each click to see if the HTML of the element contains the word "Go"; if it does, it break out of the loop. Of course, you'll have to modify it if you're using text other than "Go" on the "start-stop" anchor tag.

15 June 2010

OGV/OGG and the HTML5 player in Firefox

I tried playing an OGV video on Firefox using the new HTML5 video tag; the video played fine in the latest versions of Opera, Chrome, and Safari. But Firefox 3.6.3 would only show a big "X" -- no errors, nothing.

Some research revealed the answer: The video is being served as application/octet-stream. The other browsers can detect the type from the extension; Firefox, following good standards, is checking the mime type. The same issue existed on my localhost, with IIS running.

Solution is to add the OGV/OGG mime type to the server; different servers have different ways of doing this. For IIS, it's pretty simple. Follow the linked article, and simply replace the "Extension" with .ogg and the "MIME type" with application/ogg and restart IIS. Additional information on Firefox and mime type configuration can be found here. I recommend the OGG file extension and application/ogg mime type because they're included on Apache servers by default -- so no need to update configuration files and restart your production server.

But there's more to it. The type attribute on the source has to be shorter (this is a known Firefox bug). In addition, the OGG file has to be encoded correctly for it to work in all the browsers supporting the HTML5 video tag. The best encoding tool I've found thus far is FireFogg. It created the OGV that works like a charm on all the appropriate browsers (I just renamed the extension to OGG).

One last gotcha: IE doesn't like the source tag not being closed and will throw JavaScript errors; the other browsers don't care. So simply add a closing tag to the source tag and IE is happy. Now, why use a video tag in IE, when IE doesn't support that yet? Simple: The html5media library automatically replaces the video tag in unsupported browsers, such as IE, with the Flowplayer Flash player.

The final result is this; note the closing source tags; also, the MP4 source has to come first for it to work correctly on the iPhone/iPad:
<video id="vid" width="372" height="209" poster="global/vid/historydetectives-poster.jpg" controls preload>
<source src="global/vid/historydetectives.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'></source>
<source src="global/vid/historydetectives.ogg" type='application/ogg'> </source>
</video>

12 June 2010

Useful Design Tips For Your iPad App

http://www.smashingmagazine.com/2010/04/16/design-tips-for-your-ipad-app/

Seven JavaScript Things I Wish I Knew Much Earlier In My Career

http://www.smashingmagazine.com/2010/04/20/seven-javascript-things-i-wish-i-knew-much-earlier-in-my-career/

Designing For A Hierarchy Of Needs

http://www.smashingmagazine.com/2010/04/26/designing-for-a-hierarchy-of-needs/

40 Useful jQuery Techniques and Plugins

http://www.smashingmagazine.com/2010/04/27/45-useful-jquery-techniques-and-plugins/

Resurrecting User Interface Prototypes (Without Creating Zombies)

http://www.smashingmagazine.com/2010/05/17/resurrecting-user-interface-prototypes-without-creating-zombies/

CSS 2.1 and CSS 3 Help Cheat Sheets (PDF)

http://www.smashingmagazine.com/2010/05/13/css-2-1-and-css-3-help-cheat-sheets-pdf/

Web Design Trends 2010: Real-Life Metaphors and CSS3 Adaptation

http://www.smashingmagazine.com/2010/05/20/web-design-trends-2010-real-life-metaphors-and-css3-adaptation/

Free Designer’s Portfolio Icon Set (12 High Quality Icons)

http://www.smashingmagazine.com/2010/05/24/free-designer-s-portfolio-icon-set-12-high-quality-icons/

Web Development For The iPhone And iPad: Getting Started

http://www.smashingmagazine.com/2010/05/28/web-development-for-the-iphone-and-ipad-getting-started/

Cross-Browser Testing: A Detailed Review Of Tools And Services

http://www.smashingmagazine.com/2010/06/04/cross-browser-testing-a-detailed-review-of-tools-and-services/

GPS Data panel now available for CS5

http://blogs.adobe.com/jnack/2010/06/gps_data_panel_now_available_for_cs5.html

22 Excellent JQuery and CSS Tutorials

http://skyje.com/2010/06/jquery-and-css/

CS5 enterprise deployment tool now available

http://blogs.adobe.com/jnack/2010/06/cs5_enterprise_deployment_tool_now_available.html

The Principles Of Cross-Browser CSS Coding

http://www.smashingmagazine.com/2010/06/07/the-principles-of-cross-browser-css-coding/

10+ Free HTML5-CSS3 Website Templates (To Start Designing For Tomorrow)

http://www.webresourcesdepot.com/10-free-html5-css3-website-templates-to-start-designing-for-tomorrow/

Best HTML5 Media Player Implementations

http://blog.insicdesigns.com/2010/06/best-html5-media-player-implementations/

Best Open Source Free FLV Players

http://www.greepit.com/2009/02/best-open-source-free-flv-players/

Themeable HTML5 Video Player – FlareVideo

http://www.greepit.com/2010/06/themeable-html5-video-player-flarevideo/

30 Inspiring and Well Designed Website Footers

http://designtutorials4u.com/30-inspiring-and-well-designed-website-footers/

04 June 2010

Unobtrusive Inline Javascript Notification

http://www.notifier.addons.32teeth.org/

AJAX Image Gallery powered by Slideflow (like Cover Flow)

http://mediaeventservices.com/blog/2007/11/15/ajax-image-gallery-powered-by-slideflow-like-cover-flow/

57+ Free Image Gallery, Slideshow And Lightbox Solutions

http://www.1stwebdesigner.com/resources/57-free-image-gallery-slideshow-and-lightbox-solutions/

Multifaceted Lightbox

http://www.gregphoto.net/lightbox/

30 Scripts For Galleries, Slideshows and Lightboxes

http://www.smashingmagazine.com/2007/05/18/30-best-solutions-for-image-galleries-slideshows-lightboxes/

Weekly Web Design Inspiration #51

http://d-lists.co.uk/2010/05/02/weekly-web-design-inspiration-51/

Weekly Smashing Web Design Inspiration – #14

http://www.smashingshare.com/2010/04/09/weekly-smashing-web-design-inspiration-14/

35 (Really) Incredible Free Icon Sets

http://www.smashingmagazine.com/2008/03/06/35-really-incredible-free-icon-sets/

Navigation Menus: Trends and Examples

http://www.smashingmagazine.com/2008/02/26/navigation-menus-trends-and-examples/