Category Archives: Software Development

Same as it Ever Was: The History of HTML is a Conversation, Not a Spec

Developer Mark Pilgrim has posted a fascinating look at how the HTML img tag came into existence. The history Pilgrim digs up — mailing list conversations between the creators of the first web browsers like Marc Andreessen and the webs early pioneers like Tim Berners-Lee — show that far from being a carefully planned specification, the lingua franca of the web evolved a bit like the early universe — out of a murky chaos.

That from the chaos we got a workable — some would argue good — solution for creating the web is proof on some level that conversations and not abstracts, proposals and design by committee are the key to HTML’s success.

As Pilgrim writes:

HTML has always been a conversation between browser makers, authors, standards wonks, and other people who just showed up and liked to talk about angle brackets. Most of the successful versions of HTML have been “retro-specs,” catching up to the world while simultaneously trying to nudge it in the right direction.

You might be wondering, why did img succeed where other proposals, like an include or an icon tag failed? The answer is simple, because Marc Andreessen shipped code — Netscape Navigator — while those backing the other proposals, for most part, did not.

Of course that doesn’t mean that just shipping code is always good plan. Shipping code before a standard doesn’t necessarily produce the best solutions, as Pilgrim says. Or, put another way by a commentator on Pilgrim’s post, “shipping doesn’t mean you win, but not shipping means you lose.”

From those who shipped without the official blessing of a standard, we’ve come to have an img tag, the basis for AJAX, all of the HTML5 tools available in browsers today and much more.

Critics of HTML’s disorganized evolution will be quick to note that we’ve also come to have the blink tag, cross-browser rendering issues and other pains of web development.

Indeed we’re not suggesting that shipping features without at least engaging in the conversation is a good idea, but, when it comes to the future of HTML, if browser makers don’t ship HTML5 features before the standard is official we’ll be waiting until 2022 to use the new tools.

But while the future of HTML5 might be moving at a rather slow and convoluted pace. Pilgrim’s post is reminder that HTML has always progressed that way.

Perhaps the truly remarkable part is that, for all its flaws and convoluted evolution the core tech behind the web remains essentially the same now as it was then. “HTML is an unbroken line… a twisted, knotted, snarled line, to be sure… but still… Here we are, in 2009, and web pages from 1990 still render in modern browsers.”

Meet Go, Google’s New Programming Language

Google has released a brand-new programming language it hopes will solve some of the problems with existing languages such as Java and C++.

The language is called Go, and it was released under an open source license Tuesday. Google is no stranger to the open source world. The company has released the underlying code for several of its tools and services under open source licenses over the years. Just last week, Google released its Closure JavaScript tools for building Ajax web apps. And now Google has considerably upped its investment in free software with the release of Go, which is an entirely new programming language.

At first glance, Go looks a bit like C++, but borrows some elements, such as garbage collection, from scripting languages like Python and JavaScript. But Go’s real standout feature is its speed. A demo video shows the entire language — over 120K lines of code — compiling in under 10 seconds.

As a systems language, Go is intended to be used for developer applications like, for example, web servers. In fact, the golang.org website is being hosted by a Go program. But as Go developer Rob Pike says in recent Google Tech talk, “although Go is designed as a systems language, it has a much broader use than that.” Pike goes on to cite front-ends and other general purpose programming that Go can handle.

One of the most appealing parts of Go is its ability to handle multicore processors and, as Google’s FAQ explains, “provide fundamental support for concurrent execution and communication.”

Existing systems languages like C++ evolved long before today’s modern, and very fast, processors hit the market and make supporting multicore chips more difficult. While Google could have concentrated on writing libraries that can handle those tasks in C++, the developers behind Go say that “too many of the problems — lack of garbage collection, long dependency chains, nested include files, lack of concurrency awareness — are rooted in the design of the C and C++ languages themselves,” and decided it was time for something entirely new.

Like many of Google’s open source projects, Go began life as a 20 percent time project (the time Google gives its engineers to experiment) and evolved into something more serious. Go has been in development for over two years now, but Google is hoping that, by releasing Go under a BSD-style license, a community will develop and build Go into a viable choice for software development.

At the moment, Go is still very young and experimental. Even Google isn’t currently using Go in “large-scale production” applications. While the site that’s hosting the code is running a server built with Go as a proof of concept, the primary purpose of this release is to attract developers and help build a community around Go.

Despite its fledgling status, Go already supports many of the standard tools you’d expect from a systems language and even includes support for other Google tools like Protocol Buffers.

Also, it’s worth noting that Google’s Go is not to be confused with an existing language entitled Go! (note explanation point). Google Blogoscoped reports that Go!’s developer Francis McCabe would like Google tochange the name of Go, but thus far Google has not responded to that request.

At the moment Go is only available for Linux and Mac OS. If you’d like to learn more, check out the video of Pike’s tech talk below (it’s long, but offers a pretty thorough overview of Go) or head to the new Go website.

Ajax for Beginners

JavaScript has had the XMLHttpRequest object for almost a decade now, but it really only started getting wide attention in 2004. All this attention was mostly due to some showoff web applications that made every developer who saw them think, “I want my site to do that!” But it also has to do with the spiffy, spiffy name given to it by the folks at AdaptivePath, who named this asynchronized application Ajax. Maybe you’ve heard of it?

A few high-profile Google applications in particular made a splash with Ajax: Maps and Gmail were first. It also powers some of the core functionality in the user interface of the ever-so-popular photo sharing siteFlickr. By now, Ajax has become integral to the fabric of the web, especially in the era of real-time applications like Twitter, Buzz and Wave (all of which use Ajax extensively in their webapp front ends, for the record). Ajax may also lay claim to being the first JavaScript object with its own fan website. Date.com doesn’t count, although I did have a scintillating chat with a lady there once about the getTimeZoneoffset method.

 

What is Ajax?

So what is this fancy object that everybody wants a piece of? In brief, it’s a solution to one of the big annoyances of web interfaces. Generally, the user inputs some data or makes a choice, and clicks a button that sends the data to the server. The server takes a look at the data and sends back a whole new web page, which is loaded into the browser. Reloading a page every time you want to do something is annoying, disjunctive and time-consuming for the user. XMLHttpRequest moves that browser-server interaction to behind the scenes, so the user can just keep on playing with the same page, even while elements on the page are talking to the server! Go take a look at Google Suggest if I’ve lost you — it’s a nice, eloquent example of this.

JavaScript has always been able to sneakily trigger a server-side script without anything happening in the browser by using a few classic tricks. This one, for example:onSubmit='runascript = new Image(); runascript.src="http://www.wired.com/images/archiveyscript.php?" + this.value'. That sort of chicanery is good, maybe, for caching form data to a file on the server, but it doesn’t return any information to the JavaScript that calls it, so its usefulness is limited. Ajax, on the other hand, can get a full parcel of data back from the script it calls. Hence the “XML” part of the name – which really is just there for looks, kind of like the “Java” part of JavaScript, because the returned data can be plain text or whatever you like, if XML is overkill or just not your cup of tea.

This opens up millions of exciting possibilities. Every form submission, every JavaScript event, and heaven knows what else, can now interact with server-side databases and processing power. Data retrieval, password authentication, image generation – you name it, Ajax can trigger it.

 

Making Your Own

The potential of Ajax-enhanced web apps is limited only by your imagination – and by browser support. Mozilla-based browsers can do it, and Safari, and newer versions of Explorer, and Opera 8 but not Opera 7. It’s best to incorporate a fallback way of doing things for users who aren’t as cutting edge as you’d like them to be. Also, Explorer does things somewhat differently (of course) from all the other browsers, so it’s necessary to fork the code to account for the irritating little 80-odd percent of the population who use IE.

Let’s build a simple application that accepts input from the user, passes it to some PHP on the server that checks it against a database, and returns the result to the browser. It comes in three parts. First, we need an HTML form. This you’ve seen before:

01 <html>
02
03  <head>
04
05  <title>Report</title>
06
07  <script type='text/javascript' src='xhr.js'></script> </head> <body> <form action="fallbackpage.php" method="post">
08
09
10
11  <p>Welcome, student. Please enter your essay here:<textarea name="essay"id="essay">
12
13  </textarea> <input type="submit" name="submit" value="Submit" onClick="return
14
15  grade(this.form.essay.value);">
16
17  </p>
18
19  </form>
20
21  </body>
22
23
24
25  </html>

Note that, for users without support for our script (named xhr.js), the form will just submit to the fallback page at fallbackpage.php.

Next comes the JavaScript. This is the exciting part, so we’ll take it slow.

1 function grade(essay) {

First, we initialize the object. We have to do it two ways, for different browsers.

01 // Mozilla version
02
03 if (window.XMLHttpRequest) {
04
05     xhr = new XMLHttpRequest();
06
07 }
08
09 // IE version
10
11 else if (window.ActiveXObject) {
12
13     xhr = new ActiveXObject("Microsoft.XMLHTTP");
14
15 }

Then, we escape the user input to make it URL-safe:

1 essay=encodeURIComponent(essay);

and use the open method of the object to open a connection to the PHP script:

1 xhr.open("POST","grade.php");

The method requires two arguments:first, the HTTP method (GET or POST); second, the URL of the script.

A quick HTTP header prepares the script for what it’s getting, and then the send method transmits the actual request:

1 xhr.setRequestHeader(
2
3      'Content-Type',
4
5      'application/x-www-form-urlencoded; charset=UTF-8'); xhr.send(essay);

This last step isn’t necessary for GET requests, wherein all the data can be contained in the query string of the URL.

 

Getting Results

Now we’re ready to see if the HTTP request worked. The readyState property counts up from zero during the request, and shows 4 when the server page has loaded successfully.

1 xhr.onreadystatechange=function() {
2
3      if (xhr.readyState==4) {

If the request worked, then we can get the output of the server-side script by querying the responseTextproperty, which contains a string. For more complex server script output, a responseXML property, which can hold a full document object of XML data, is also available.

1      grade = xhr.responseText;
2
3      alert ("Nice essay. Your grade is " + grade);
4
5    }
6
7    return false;
8
9 }

Want to see all that in a pastable block? Here it is in a separate file.

Finally, the third component is the PHP script, which lives on the server and waits patiently for the JavaScript to pass it some juicy data. This example uses PHP, but any language you like — Ruby, Perl, C, ASP — can do as well. The core of this example script is a natural-language function calledgrade_essay() that grades student essays from 1 to 100, but I will redact that part to conserve space.

01 <?php
02
03 function grade_essay($essay) {
04
05      return strlen($essay);
06
07 }
08
09 $essay = urldecode(implode(file('php://input')));
10
11 $grade = grade_essay($essay);
12
13 echo $grade;
14
15 ?>

The php://input grabs the POST data, which gets put into a string, decoded and passed to the ingenious grading algorithm. The algorithm returns a numeric grade. Lastly, we just output the grade with echo – ordinarily, this would display in the browser, but since the PHP script is running “behind the scenes,” the string output is simply returned to the JavaScript that called it. If you need structured data, an XML document would be output with an echo statement in just the same way, but the content-type of the output page must be set to text/xml.

What the user sees is this:She types her essay into the text area in the browser, clicks Submit, and within instants an alert box pops up giving her a final grade on the essay. Invisibly, the essay has been sent to the server, read and evaluated by a team of PHP gnomes, and returned with a grade, without ever reloading the page. The user can modify her essay and resubmit it endlessly.

And that’s the gist of the almost magical XMLHttpRequest object! The example is simple, but the uses of the object can be elaborately, multifariously clever. If you need further inspiration and edification, a burgeoning number of examples are dotted around the Web:

Slide and Push Menus

A set of fixed menus that will slide out from any of the edges of the page. The two menus that slide out from the left and right side can also be used in combination with the body moving to the left or right side, respectively, hence being “pushed”.

There are examples of how to trigger the opening and closing of the menus and some example media queries.

The HTML

<!-- body has the class "cbp-spmenu-push" -->
<nav class="cbp-spmenu cbp-spmenu-vertical cbp-spmenu-left" id="cbp-spmenu-s1">
	<h3>Menu</h3>
	<a href="#">Celery seakale</a>
	<a href="#">Dulse daikon</a>
	<a href="#">Zucchini garlic</a>
	<a href="#">Catsear azuki bean</a>
	<a href="#">Dandelion bunya</a>
	<a href="#">Rutabaga</a>
</nav>
<nav class="cbp-spmenu cbp-spmenu-vertical cbp-spmenu-right" id="cbp-spmenu-s2">
	<h3>Menu</h3>
	<a href="#">Celery seakale</a>
	<a href="#">Dulse daikon</a>
	<a href="#">Zucchini garlic</a>
	<a href="#">Catsear azuki bean</a>
	<a href="#">Dandelion bunya</a>
	<a href="#">Rutabaga</a>
</nav>
<nav class="cbp-spmenu cbp-spmenu-horizontal cbp-spmenu-top" id="cbp-spmenu-s3">
	<h3>Menu</h3>
	<a href="#">Celery seakale</a>
	<a href="#">Dulse daikon</a>
	<a href="#">Zucchini garlic</a>
	<a href="#">Catsear azuki bean</a>
	<a href="#">Dandelion bunya</a>
	<a href="#">Rutabaga</a>
	<a href="#">Celery seakale</a>
	<a href="#">Dulse daikon</a>
	<a href="#">Zucchini garlic</a>
	<a href="#">Catsear azuki bean</a>
	<a href="#">Dandelion bunya</a>
	<a href="#">Rutabaga</a>
</nav>
<nav class="cbp-spmenu cbp-spmenu-horizontal cbp-spmenu-bottom" id="cbp-spmenu-s4">
	<h3>Menu</h3>
	<a href="#">Celery seakale</a>
	<a href="#">Dulse daikon</a>
	<a href="#">Zucchini garlic</a>
	<a href="#">Catsear azuki bean</a>
	<a href="#">Dandelion bunya</a>
	<a href="#">Rutabaga</a>
	<a href="#">Celery seakale</a>
	<a href="#">Dulse daikon</a>
	<a href="#">Zucchini garlic</a>
	<a href="#">Catsear azuki bean</a>
	<a href="#">Dandelion bunya</a>
	<a href="#">Rutabaga</a>
</nav>
<div class="container">
	<div class="main">
		<section>
			<h2>Slide Menus</h2>
			<!-- Class "cbp-spmenu-open" gets applied to menu -->
			<button id="showLeft">Show/Hide Left Slide Menu</button>
			<button id="showRight">Show/Hide Right Slide Menu</button>
			<button id="showTop">Show/Hide Top Slide Menu</button>
			<button id="showBottom">Show/Hide Bottom Slide Menu</button>
		</section>
		<section class="buttonset">
			<h2>Push Menus</h2>
			<!-- Class "cbp-spmenu-open" gets applied to menu and "cbp-spmenu-push-toleft" or "cbp-spmenu-push-toright" to the body -->
			<button id="showLeftPush">Show/Hide Left Push Menu</button>
			<button id="showRightPush">Show/Hide Right Push Menu</button>
		</section>
	</div>
</div>

The CSS

/* General styles for all menus */

.cbp-spmenu {
	background: #47a3da;
	position: fixed;
}

.cbp-spmenu h3 {
	color: #afdefa;
	font-size: 1.9em;
	padding: 20px;
	margin: 0;
	font-weight: 300;
	background: #0d77b6;
}

.cbp-spmenu a {
	display: block;
	color: #fff;
	font-size: 1.1em;
	font-weight: 300;
}

.cbp-spmenu a:hover {
	background: #258ecd;
}

.cbp-spmenu a:active {
	background: #afdefa;
	color: #47a3da;
}

/* Orientation-dependent styles for the content of the menu */

.cbp-spmenu-vertical {
	width: 240px;
	height: 100%;
	top: 0;
	z-index: 1000;
}

.cbp-spmenu-vertical a {
	border-bottom: 1px solid #258ecd;
	padding: 1em;
}

.cbp-spmenu-horizontal {
	width: 100%;
	height: 150px;
	left: 0;
	z-index: 1000;
	overflow: hidden;
}

.cbp-spmenu-horizontal h3 {
	height: 100%;
	width: 20%;
	float: left;
}

.cbp-spmenu-horizontal a {
	float: left;
	width: 20%;
	padding: 0.8em;
	border-left: 1px solid #258ecd;
}

/* Vertical menu that slides from the left or right */

.cbp-spmenu-left {
	left: -240px;
}

.cbp-spmenu-right {
	right: -240px;
}

.cbp-spmenu-left.cbp-spmenu-open {
	left: 0px;
}

.cbp-spmenu-right.cbp-spmenu-open {
	right: 0px;
}

/* Horizontal menu that slides from the top or bottom */

.cbp-spmenu-top {
	top: -150px;
}

.cbp-spmenu-bottom {
	bottom: -150px;
}

.cbp-spmenu-top.cbp-spmenu-open {
	top: 0px;
}

.cbp-spmenu-bottom.cbp-spmenu-open {
	bottom: 0px;
}

/* Push classes applied to the body */

.cbp-spmenu-push {
	overflow-x: hidden;
	position: relative;
	left: 0;
}

.cbp-spmenu-push-toright {
	left: 240px;
}

.cbp-spmenu-push-toleft {
	left: -240px;
}

/* Transitions */

.cbp-spmenu,
.cbp-spmenu-push {
	-webkit-transition: all 0.3s ease;
	-moz-transition: all 0.3s ease;
	transition: all 0.3s ease;
}

/* Example media queries */

@media screen and (max-width: 55.1875em){

	.cbp-spmenu-horizontal {
		font-size: 75%;
		height: 110px;
	}

	.cbp-spmenu-top {
		top: -110px;
	}

	.cbp-spmenu-bottom {
		bottom: -110px;
	}

}

@media screen and (max-height: 26.375em){

	.cbp-spmenu-vertical {
		font-size: 90%;
		width: 190px;
	}

	.cbp-spmenu-left,
	.cbp-spmenu-push-toleft {
		left: -190px;
	}

	.cbp-spmenu-right {
		right: -190px;
	}

	.cbp-spmenu-push-toright {
		left: 190px;
	}
}

The JavaScript

var menuLeft = document.getElementById( 'cbp-spmenu-s1' ),
		menuRight = document.getElementById( 'cbp-spmenu-s2' ),
		menuTop = document.getElementById( 'cbp-spmenu-s3' ),
		menuBottom = document.getElementById( 'cbp-spmenu-s4' ),
		showLeft = document.getElementById( 'showLeft' ),
		showRight = document.getElementById( 'showRight' ),
		showTop = document.getElementById( 'showTop' ),
		showBottom = document.getElementById( 'showBottom' ),
		showLeftPush = document.getElementById( 'showLeftPush' ),
		showRightPush = document.getElementById( 'showRightPush' ),
		body = document.body;

showLeft.onclick = function() {
	classie.toggle( this, 'active' );
	classie.toggle( menuLeft, 'cbp-spmenu-open' );
	disableOther( 'showLeft' );
};
showRight.onclick = function() {
	classie.toggle( this, 'active' );
	classie.toggle( menuRight, 'cbp-spmenu-open' );
	disableOther( 'showRight' );
};
showTop.onclick = function() {
	classie.toggle( this, 'active' );
	classie.toggle( menuTop, 'cbp-spmenu-open' );
	disableOther( 'showTop' );
};
showBottom.onclick = function() {
	classie.toggle( this, 'active' );
	classie.toggle( menuBottom, 'cbp-spmenu-open' );
	disableOther( 'showBottom' );
};
showLeftPush.onclick = function() {
	classie.toggle( this, 'active' );
	classie.toggle( body, 'cbp-spmenu-push-toright' );
	classie.toggle( menuLeft, 'cbp-spmenu-open' );
	disableOther( 'showLeftPush' );
};
showRightPush.onclick = function() {
	classie.toggle( this, 'active' );
	classie.toggle( body, 'cbp-spmenu-push-toleft' );
	classie.toggle( menuRight, 'cbp-spmenu-open' );
	disableOther( 'showRightPush' );
};

function disableOther( button ) {
	if( button !== 'showLeft' ) {
		classie.toggle( showLeft, 'disabled' );
	}
	if( button !== 'showRight' ) {
		classie.toggle( showRight, 'disabled' );
	}
	if( button !== 'showTop' ) {
		classie.toggle( showTop, 'disabled' );
	}
	if( button !== 'showBottom' ) {
		classie.toggle( showBottom, 'disabled' );
	}
	if( button !== 'showLeftPush' ) {
		classie.toggle( showLeftPush, 'disabled' );
	}
	if( button !== 'showRightPush' ) {
		classie.toggle( showRightPush, 'disabled' );
	}
}

Solving PHP MySQL UTF-8 issues

Heres a list of actions you should do in order to get PHP + MySQL working with UTF-8:

1. Database:

CREATE DATABASE db_name
 CHARACTER SET utf8
 DEFAULT CHARACTER SET utf8
 COLLATE utf8_general_ci
 DEFAULT COLLATE utf8_general_ci
 ;

or if the database was already created:

ALTER DATABASE db_name
 CHARACTER SET utf8
 DEFAULT CHARACTER SET utf8
 COLLATE utf8_general_ci
 DEFAULT COLLATE utf8_general_ci
 ;

CREATE TABLE table_name(
 ...
 )
 DEFAULT CHARACTER SET utf8   
 COLLATE utf8_general_ci;

Or if the tables are already created:

ALTER TABLE tbl_name
 DEFAULT CHARACTER SET utf8
 COLLATE utf8_general_ci
 ;

2. Enable this line in php.ini:

extension=php_mbstring.dll

and configure the following in the same file:

mbstring.language = Neutral
mbstring.internal_encoding = UTF-8
mbstring.encoding_translation = On
mbstring.http_input = auto
mbstring.http_output = UTF-8
mbstring.detect_order = auto
mbstring.substitute_character = none
default_charset = UTF-8

3. Use the following php functions instead:

mail()                -> mb_send_mail()
strlen()              -> mb_strlen()   
strpos()              -> mb_strpos()
strrpos()             -> mb_strrpos()
substr()              -> mb_substr()
strtolower()          -> mb_strtolower()
strtoupper()          -> mb_strtoupper()
substr_count()        -> mb_substr_count()
ereg()                -> mb_ereg()
eregi()               -> mb_eregi()
ereg_replace()        -> mb_ereg_replace()
eregi_replace()       -> mb_eregi_replace()   
split()               -> mb_split()
htmlentities($var)    -> htmlentities($var, ENT_QUOTES, 'UTF-8')

4. Use headers and meta tags like:

header('Content-type: text/html; charset=UTF-8') ;

<meta http-equiv="Content-type" value="text/html; charset=UTF-8" />

5. Before any insert / update in the database you should perform the following:

mysql_query("SET NAMES 'utf8'");