<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:base="http://www.timbenniks.nl" xml:lang="en">
	<generator uri="http://zotonic.com/">Zotonic - Atom Feed Module</generator>
	<updated>2011-06-14T09:15:17+02:00</updated>
	<logo />
	
	<id>http://www.timbenniks.nl/feed/blog</id>
	<title>Tim Benniks, Front-end Engineer - Blogpost</title>

    
	
		
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/timbenniks_blog" /><feedburner:info uri="timbenniks_blog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/1700</id>
			<updated>2011-02-02T19:18:21+01:00</updated>
			<published>2011-01-31T21:55:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/1700/a-mobile-development-strategy" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2011/1/31/phones.jpeg%28400x400%29%28DAD1141E22A78BF1A70DE02280B5DDA7%29.jpg" />
			

			<title>A mobile development strategy</title>
			
				<summary>Nowadays more and more interactive projects have a mobile component. This article lays out a strategy that I think would work for a mobile website. As there as so many different devices and screen resolutions on that market, one has to be very flexible and pragmatic to be able to develop something that works like it should. In this article I’ll try to explain how to make this happen with a couple of simple techniques. I will not go into the details of any of them just yet, this is merely an explanation of the strategy. Later articles will be much more concrete and will show hand’s on examples.</summary>
				<content type="html">&lt;h2&gt;Things to keep in mind when developing for mobile&lt;/h2&gt;&lt;p&gt;If you build a mobile website, you could re-use the templates that are used for the regular website and just change the CSS. So, downscale images, downscale the grid, hide certain assets, and maybe put the menu on the top of the page.&lt;/p&gt;&lt;p&gt;I used the tricks above on my own website and wrote about them &lt;a href="http://www.timbenniks.nl/blog/1421/my-new-fluffy-css3-layout" target="_self"&gt;here&lt;/a&gt;. I used media queries and a fluid grid to make my website accessible to all the devices I liked. Developing in this particular way is fine for websites that do not have a specific mobile concept. It just makes them easier to navigate on an iPad or HTC phone. But you should not do this for a project that has it’s main focus on mobile.&lt;/p&gt;&lt;p&gt;If you are developing a specific website or app for a mobile device, there are some considerations to keep in mind. Remember that you usually have a strict policy on Internet use and that you only have a 3G or GPRS connection. Even if you hide the slide show or the background images, the browser will still download them. The same goes for resizing images with CSS. You uploaded a big image for your desktop users, but you scale it down for mobile users. It turns out that the mobile browser actually downloads the big image and then scales it down.&lt;/p&gt;&lt;p&gt;For me this is a total “no-go”. Why load stuff you can’t even see or scale down? It just slows down the experience and drives up your Internet costs.&lt;/p&gt;&lt;p&gt;Some companies advertise that they allow flash to work on their device. That sounds promising, but I have not seen any workable and performing sites yet. The flash drivers on those devices are not optimized for a mobile and slow down or crash the browser. A definite “no-go” again.&lt;/p&gt;&lt;h2&gt;Context baby!&lt;/h2&gt;&lt;p&gt;When you develop for mobile, in what context users view your site is very important. On a mobile you are usually more hands-on and more goal-focused. Imagine running for the train and you forgot from what lane your train is departing. You grab your mobile, squeeze your bagel somewhere and browse to the train company website to check the departures. How frustrated would you be if you had to browse through 5 pages and scroll along media players that show the company’s history and such? You just want to get to these departure lanes...&lt;/p&gt;&lt;p&gt;I propose a set of simple templates that already know that the website is being viewed on some sort of mobile / touch device. In this template you can leave out all the fancy slide shows and high-res images. Instead, just focus on the most important information.&lt;/p&gt;&lt;p&gt;I personally think that if you design a website, you should start with the mobile version. It let’s you and your client focus on the most important piece of information on the entire website. After that, scale up and design the fancy stuff. If you organize your process this way, hopefully all your team members get a sort of group conscience that you are working on a design that has to be very adaptable to the users context. Everything should be flexible and fast. It’s the wobbly web people, not a magazine... Nothing is fixed anymore, not even pixels (check the iPhone 4 screen).&lt;/p&gt;&lt;h2&gt;Device classes&lt;/h2&gt;&lt;p&gt;Because you can never develop for all devices in the world, it’s handy to classify the most used resolutions and devices into some groups. You can target your design and development to each of these groups.&lt;/p&gt;&lt;p&gt;Each of these device classes has a unique:&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;context (chill mode on the couch, desk use, running);&lt;/li&gt;&lt;li&gt;input method (touch events, mouse etc);&lt;/li&gt;&lt;li&gt;average display size.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.lukew.com/" target="_blank"&gt;Luke Wroblowski&lt;/a&gt; wrote a &lt;a href="http://www.lukew.com/ff/entry.asp?1258" target="_blank"&gt;great piece&lt;/a&gt; about this.&lt;/p&gt;&lt;h2&gt;Responsive design and fluid stuff&lt;/h2&gt;&lt;p&gt;Responsive design is a relatively new term, but actually it’s as old as the Internet. Remember all these old school websites that would fill your whole screen? These designs where percentage based and would scale down if you had a smaller screen.&lt;/p&gt;&lt;p&gt;Responsive design means that you design something that is able to respond to change. The design is adaptive to the context it’s used in. For example: resolution, landscape or portrait, JavaScript support, CSS3 support, touch or mouse oriented. So it’s not just a fluid grid.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.alistapart.com/articles/responsive-web-design" target="_blank"&gt;Read more about responsive design.&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Stuff you can use when developing a responsive design&lt;/h2&gt;&lt;h3&gt;Progressive enhancement&lt;/h3&gt;&lt;p&gt;This is a much discussed topic for years. Any respectable web developer should know about this by now. It is even more important to use it for mobile development. There are loads of devices with many different browsers and versions. Feature detecting is a key element in responsive design. &lt;a href="http://www.alistapart.com/articles/understandingprogressiveenhancement/" target="_blank"&gt;This&lt;/a&gt; is a nice article about progressive enhancement.&lt;/p&gt;&lt;h3&gt;Fluid “em-based” or “%-based” grids&lt;/h3&gt;&lt;p&gt;Using a fluid grid can help you a lot in mobile development. As there are a lot of different screen resolutions it’s not manageable to design a fixed grid for every device. Just design for an average screen that has been classified in the device classes mentioned above.&lt;/p&gt;&lt;p&gt;If your design is fluid you can still pull of resolutions that fit in the classification but are a little different then the one you initially designed for.&lt;/p&gt;&lt;h3&gt;Fluid images and client side adaptive image replacement&lt;/h3&gt;&lt;p&gt;Fluid images is a very sexy technique which Ethan Marcotte helped make famous. It basically means that even your images scale according to the resolution of the device.&lt;/p&gt;&lt;p&gt;There is a drawback to this technique. To be able to scale the images you need to use the biggest one possible to match all your design stages. A stretched image on a website is horrible. A nice solution is “client side adaptive image replacement”. &lt;a href="http://filamentgroup.com/lab/responsive_images_experimenting_with_context_aware_image_sizing/" target="_blank"&gt;Read more about about it here.&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Media queries&lt;/h3&gt;&lt;p&gt;Media queries are hot! The spec is not entirely finished but they are very usable nowadays. Media queries let you add CSS rules according to a query that you specify. For example “orientation: landscape”, or “screen”, or “max-device-width: 768px”. Picture the strength of these when you build one interface for let’s say two devices classes. When you get below a screen width of 320px, move the menu to the top and when you hit 240px remove that new column and make the typography a little bigger. Try resizing this website, look at the Media query magic!&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;If you put all of this together, mobile development is in desperate need of “adaptive” design and development. It’s hard to predict how many devices are yet to come, and what their capabilities and resolutions will be. If your design is adaptive and feature detecting you can be almost sure it will service old and new devices. This is a pretty bold statement so let’s hope browsers keep implementing web standards the correct way.&lt;/p&gt;&lt;p&gt;If we developers and (especially designers) keep it about web-standards, we can show our team-leads and project managers that they do not have to buy insanely expensive packages like net biscuits. It would be awesome if designs become a little more web-oriented so that developers and designers can work together more closely. This not only prevents extra overhead in your project, but also helps creating a great standards-based web app that works on a large range of mobile devices.&lt;/p&gt;&lt;h3&gt;Sources:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.lukew.com" target="_blank"&gt;http://www.lukew.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.alistapart.com" target="_blank"&gt;http://www.alistapart.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.quirksmode.org" target="_blank"&gt;http://www.quirksmode.org&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.w3.org" target="_blank"&gt;http://www.w3.org&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/1562</id>
			<updated>2011-01-10T20:49:42+01:00</updated>
			<published>2010-12-14T20:34:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/1562/non-blocking-javascript-roundup" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/12/14/tx65coupe_albums_1965_ford_mustang_picture16748_100_0538.jpeg%28400x400%29%288DFD38B5AF62B705624EA38407DAD1A8%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/12/14/schiphol-1.jpeg%28400x400%29%28E8D7E0DD61394238269A30D8DA824C26%29.jpg" />
			

			<title>Non-blocking JavaScript roundup</title>
			
				<summary>Non-blocking JavaScript has been a hot topic for a while now. I am going to try to explain why JavaScript blocks the browser while rendering a page and how you can solve this issue. This article is a roundup of the most commonly used techniques out there. Credits for these best practises go to the developers at Yahoo!.</summary>
				<content type="html">&lt;h2&gt;About blocking&lt;/h2&gt;&lt;p&gt;In my opinion JavaScript plays an important role in the perceived speed of a website. While JavaScript is executed, nothing can happen on your page. Most browsers have only one thread for the UI and the JavaScript and because of this they can only do one thing at a time. The longer the JavaScript takes to load and parse, the longer it takes the browser to be able to do something with user input. The very existence of a script tag in your page is enough to make the page wait.&lt;/p&gt;&lt;p&gt;In this article I will outline some techniques to handle this issue in a pragmatic way. The blocking issue is important because speed and responsiveness is vital for a website. The faster a user perceives your website, the sweeter the experience is to them. &lt;a href="http://developer.yahoo.com/performance"&gt;The Yahoo! developer blog&lt;/a&gt; has a lot of data on this.&lt;/p&gt;&lt;h2&gt;A reason why&lt;/h2&gt;&lt;p&gt;There is a reason why browsers block page loading when they encounter a script tag. Blocking is a necessary part of the page life cycle because the script may make changes to the page while executing. An example is document.write which is often used by banners. The browser can never know what that document.write does with the current DOM. So it stops rendering and lets the script execute. Once that is done, the browser resumes building your page. This also goes for external scripts. Keep in mind that page rendering and user interaction can not happen during the execution of javascript.&lt;/p&gt;&lt;h2&gt;Position&lt;/h2&gt;&lt;p&gt;Back in the day when separation of structure, logic and styling became a best practise, it was advised to put all the external stuff in the head of the page. This would be an ideal example of that:&lt;/p&gt;&lt;pre&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;title&amp;gt;2003&amp;lt;/title&amp;gt;
	&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;prototype.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	
	&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;effects.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
	&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;common.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;

	&amp;lt;link type=&amp;quot;text/css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;style.css&amp;quot; /&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;h1&amp;gt;Meh.&amp;lt;/h1&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;p&gt;In this &amp;#39;once&amp;#39; excellent code we can see a major performance issue. Because there are three script tags in the header the browser has to parse them first before she starts to render the rest of the page. Let&amp;#39;s say each file is big and takes about 100ms to download and parse. The perceived performance will suffer horribly because you have to wait about 300ms of blank page before you see something. A nice example is http://www.schiphol.nl. They have a stunning 28 JavaScript files loaded in the head of their homepage. Try to load this website with an empty cache and see the nasty stuff happen. For fun try the same from Italy. The experience is very slow and I would not like to come back to check the departure times again.&lt;/p&gt;&lt;p&gt;&lt;!-- z-media 1563 {"align": "left", "size": "middle", "crop": "", "link": ""} --&gt;&lt;/p&gt;&lt;p&gt;A simple solution for this would be to put the script tags just above the body end tag. Now the browser will render all the sweet stuff first and then blocks near the end to download and parse the JavaScript. If it blocks the UI in the end, it&amp;#39;s a lot less harmful.&lt;/p&gt;&lt;h2&gt;Combining&lt;/h2&gt;&lt;p&gt;Now that your script tags are placed at the bottom, you still have multiple HTTP requests. An HTTP request generates overhead and is therefore harmful for the responsiveness en perceived speed of your website. A general rule of thumb that we have learned from Yahoo! is to combine your scripts. Three requests of 20kb take much longer than one request of 60kb.&lt;/p&gt;&lt;p&gt;Combining can be an automated process, so you don&amp;#39;t have to bother putting all those files together yourself. The cool thing is that because of this automation you can still have separate files when developing. When the website is on a production server all JavaScript files get combined so there are as little requests as possible.&lt;/p&gt;&lt;p&gt;There is another great benefit from automating the combination of files. The combined file can also be compressed! This way you loose white space, comments and variable names get shortened. The smaller your file, the faster the download, the sweeter the experience becomes for you users.&lt;/p&gt;&lt;h2&gt;Nonblocking&lt;/h2&gt;&lt;p&gt;Nowadays it&amp;#39;s a best practise to practise the techniques mentioned above. Next to this it is advisable to keep the amount of code small. Less code means a faster site because there is not much to download and parse. But, if we look at this best practise with realistic eyes, it&amp;#39;s not going to work out. Our applications are bigger and fancier then ever before.&lt;/p&gt;&lt;p&gt;If you combine all files and put that file at the bottom, you still end up with one big file that holds off the document.ready event when downloading and parsing. The trick is to load the JavaScript after the page is finished loading. So after the window.load event.&lt;/p&gt;&lt;h3&gt;Defer&lt;/h3&gt;&lt;p&gt;There are a couple of techniques you can use to accomplish this. There is the defer attribute that you can place in your script tag. The fact that you pace the defer attribute on the script tag means that you tell the browser that the script will not change the DOM and it is safe to load the script after the page has been rendered. The downfall to this technique is that it is only supported by Internet Explorer and Firefox 3.5+.&lt;/p&gt;&lt;h3&gt;Dynamic script elements&lt;/h3&gt;&lt;p&gt;The DOM allows you to dynamically add and remove elements to it. Things like a link tag and a script tag are also DOM elements. You can change, add or remove them in any way you like with some basic DOM manipulation functions profited by JavaScript.&lt;/p&gt;&lt;pre&gt;var scriptTag = document.createElement(&amp;quot;script&amp;quot;);
scriptTag.src = &amp;quot;file.js&amp;quot;;
document.getElementsByTagName(&amp;quot;head&amp;quot;)[0].appendChild(scriptTag);
&lt;/pre&gt;&lt;p&gt;The newly generated script tag wil load file.js. The fancy thing about this technique is that the JavaScript file is loaded and executed without blocking the page while loading. It does not even matter where the script tag is placed.&lt;/p&gt;&lt;p&gt;When a file is downloaded this way it is automatically executed. This could potentially lead to some trouble with script dependencies. You have to find a way to know when the script is loaded, and ready to be executed. Most browsers fire a &amp;quot;load&amp;quot; event when the script source has been downloaded. You can add this to your function:&lt;/p&gt;&lt;pre&gt;scriptTag.onLoad = function() {
	alert(&amp;quot;I am loaded&amp;quot;);
}
&lt;/pre&gt;&lt;p&gt;Of course Internet Explorer has a different implementation. They have implemented 5 ready states. The most important are &amp;quot;loaded&amp;quot; and &amp;quot;complete&amp;quot;. Internet Explorer uses them inconsistently so it is wise to check for both ready states.&lt;/p&gt;&lt;pre&gt;scriptTag.onreadystatechange = function() {
	if(scriptTag.onreadystatechange == &amp;quot;loaded&amp;quot; 
	|| scriptTag.onreadystatechange == &amp;quot;complete&amp;quot;) {
		scriptTag.onreadystatechange = null;
		alert(&amp;quot;I am loaded&amp;quot;);
	}
}
&lt;/pre&gt;&lt;p&gt;If you combine everything you could write something like this:&lt;/p&gt;&lt;pre&gt;function loadScript(url, callback) {
	var scriptTag = document.createElement(&amp;quot;script&amp;quot;);

	// check for IE
	if(scriptTag.readyState) {
		scriptTag.onreadystatechange = function() {
			if(scriptTag.readyState == &amp;quot;loaded&amp;quot; 
			|| scriptTag.readyState == &amp;quot;complete&amp;quot;) {
				scriptTag.onreadystatechange = null;
				callback();
			}
		}	
	} else {
		scriptTag.onLoad = function() {
			callback();
		}
	}
	
	scriptTag.src = url;
	document.getElementsByTagName(&amp;quot;head&amp;quot;)[0].appendChild(scriptTag);	
}
&lt;/pre&gt;&lt;p&gt;With this fancy piece of code you can load script asynchronously across browsers. And with the callback attribute you can make sure that your scripts are loaded in the correct order:&lt;/p&gt;&lt;pre&gt;loadScript(&amp;quot;jquery.js&amp;quot;, function() {
	loadScript(&amp;quot;validate.js&amp;quot;, function() {
		loadScript(&amp;quot;common.js&amp;quot;, function() {
			yourApplicationNameSpace.init();
		});
	});
});
&lt;/pre&gt;&lt;p&gt;For the most optimal speed, just inline this function just before the body ends. For the fastest possible load time, use a tool like YUI compressor to make the script as small as possible.&lt;/p&gt;&lt;p&gt;That wraps it up, I hope it helps! Let&amp;#39;s make sure we all use these kind of techniques so we can enjoy a faster web!&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/1434</id>
			<updated>2010-12-02T09:37:18+01:00</updated>
			<published>2010-12-01T13:00:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/1434/progressive-enhancement-you-have-to-do-it-together-to-make-it-work" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/11/15/big_deal2.jpeg%28400x400%29%28C7ACEB7EEB809711EA163E4367286AC6%29.jpg" />
			

			<title>Progressive enhancement: you have to do it together to make it work</title>
			
				<summary>This is an article about how we can deal with progressive enhancement when used with real-life projects, by real-life projects I mean the big projects with demanding clients that we are all familiar with. These types of clients are mainly focused on the impact of their branding experience for all the visitors of their website. To them it does not matter in what context or where the site is viewed from as long as the brand is represented. If you combine this vision with the way that visual designers work, it usually results in the fact that the website should look the same (and give the same experience) on all browsers, connections and devices.</summary>
				<content type="html">&lt;p&gt;A project like this is usually filled with red tape and politics about specs and money. Front-end developers have to negotiate these hazards and advise their clients (and team) about using proper techniques. These techniques are critical for a fast, accessible and responsive website. A site that has little need for support and rework is cheap and without countless rework issues for IE6 we have more time on our hands to develop for the future.&lt;/p&gt;&lt;p&gt;By now we all know that the answer to these problems is &amp;#39;Progressive Enhancement&amp;#39;. But, lets face reality, most of the time progressive enhancement is a bit of a utopian ideal. Let&amp;#39;s say your client has 95% IE7 users but still wants to show off with shadows, gradients and transitions. Obviously there are ways to still use our beloved techniques, but it gets a lot harder when you have to explain to the client that the project will be expensive and time consuming.&lt;/p&gt;&lt;h3&gt;Crossroads&lt;/h3&gt;&lt;p&gt;In these projects we often get to a crossroad where we have to make a decision. Are we going to develop for the future or are we optimizing for the fading past of 2001? Both ways are valid as long as the choice is made wisely. Most of the time this choice is not made by (or known to) the whole team. Then the trouble starts. Who is responsible for the design decisions when it is unclear who knows what techniques are used while developing? What will happen to your credibility if you present the final templates to an unhappy client that expected gradients in IE? At that moment it&amp;#39;s probably not so cool to tell them that -ms-filters suck right?&lt;/p&gt;&lt;p&gt;Tickets start to appear in the issue-tracker because the client&amp;#39;s tester (who has the visual designs as a baseline) spots loads of bugs in IE6. I could go on and on with more situations like these. I guess at one point in time we have all been in them. You are in big fat trouble if the vision on front-end development was not chosen on time. It is vital for the project that all stakeholders are involved when this vision is spread out.&lt;/p&gt;&lt;p&gt;I&amp;#39;ve noticed (and I&amp;#39;ve also heard this from other developers) that many visual designers have a bit of trouble with progressively enhancing their design. In their eyes it looks more like tearing down the design to make it work in less capable browsers. Their work has obviously been done with vision and according to them, it should look the same everywhere.&lt;/p&gt;&lt;h3&gt;Lets work together&lt;/h3&gt;&lt;p&gt;It is our responsibility as web developers to teach everybody around us about the browser differences and the solutions that progressive enhancement can offer us to make projects ready for the future.&lt;/p&gt;&lt;p&gt;I think we can solve some of the issues I mentioned above by working together as a tight team. Obviously the whole team needs to be committed to their jobs and it also helps if everybody in the team knows a little bit about what their teammates do. A front-end developer for example needs to know his typography, but to be able to build templates he also needs to understand the back-end technology.&lt;/p&gt;&lt;p&gt;The same goes for visual design. They are &amp;#39;web&amp;#39; designers right? So, try to understand what browsers do and why some stuff is hard and most stuff is easy. Try to crawl into the mind of a developer and look at the abstract methods that are used to build a website. Use a design tool that is component based so you can generate five pages with different content blocks on the fly. In my opinion Photoshop is for pixel nerds and generates loads of overhead when prototyping.&lt;/p&gt;&lt;p&gt;Think more like a web developer and work together. The front-end developer could use the designed components to recreate them in the browser. To go even further, the developer could use these components as includes in his development environment. As long as you use the correct naming conventions everything is synced up nicely.&lt;/p&gt;&lt;p&gt;When you know a bit more about what your teammates do, it becomes a much easier to communicate. The faster the communication is, the more time you have to document and keep everybody up to date. It is vital that you create a group consciousness that you are working on a web project. On the web everything is dynamic, the web has loads of users that browse on different devices, browsers and connections.&lt;/p&gt;&lt;p&gt;Think in responsive design, nothing is fixed anymore. Maybe the interface that you are building appears on someones fridge door in 2014? I&amp;#39;m not saying that we have to &amp;#39;over&amp;#39; design and think of every aspect possible. It&amp;#39;s just about being agile in your thinking process.&lt;/p&gt;&lt;p&gt;All team members know different things. Where one is really into making fast websites, the other might be into accessibility. The best thing to do is combine these skills and get the correct group of people together before you start a project. It is also very important to incorporate your client into the project team, make sure you work with your client and not for them. This way the project becomes nice and agile and the client will understand the choices that are made in the process.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;As I have said before, it is vital for your project to work together closely. I think the &amp;#39;scrum&amp;#39; method suits this nicely. Knowing a bit more about your teammates and getting the client involved are also important parts.&lt;/p&gt;&lt;p&gt;Next to this is the vision on front-end development. As this is such an important part of the project, this vision needs to be shared with all stakeholders. The vision needs to be written down and understood by everybody and could even be part of a pitch. To write this down, you need to know a lot about what the goals of your client are. For example; What is the target audience for this project and what are the goals of these people? In what context are they looking at the site? On a mobile in the train, or on the toilet with an iPad? Maybe they check the website on the 15&amp;quot; CRT in the nurses station (yes, hospitals are shabby when it comes to this :-)).&lt;/p&gt;&lt;p&gt;This article reflects my idea on how to handle projects. Please share your opinions because this is an ever changing subject and we could all use some fresh ideas.&lt;/p&gt;&lt;p&gt;In my next article I am going to try to explain something about progressive enhancement and it&amp;#39;s background. For now read the masterpiece &lt;a href="http://hardboiledwebdesign.com/" target="_blank"&gt;&amp;#39;Hardboiled webdesign&amp;#39; by Andy Clark&lt;/a&gt; to get more information about the general use of progressive enhancement. Andy also writes a bunch about the mindset that you need to be a hardboiled web developer and use progressive enhancement in real-life projects.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/1421</id>
			<updated>2010-11-10T23:20:02+01:00</updated>
			<published>2010-11-09T21:32:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/1421/my-new-fluffy-css3-layout" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/11/9/fluffy.png%28400x400%29%281D65C33984DC53C9E4403DB86C4D259B%29.jpg" />
			

			<title>My new fluffy CSS3 layout</title>
			
				<summary>I decided to tear down the heavy javascripting I have been doing lately and dove into CSS3 and HMTL5 again. This website is the result of that research.</summary>
				<content type="html">&lt;p&gt;I attended a great presentation by &lt;a href="http://nerd.vasilis.nl" target="_blank"&gt;Vasilis van Gemert&lt;/a&gt; that inspired me to use the new layout techniques offered by CSS3. Vasilis talked about the transition of fixed websites into scalable (fluffy) websites that are very flexible and work on multiple devices and resolutions.&lt;/p&gt;&lt;p&gt;I realized that there is great power in using @media-queries and a percentage based layout. Try resizing your browser window right now, and see what happens. Note that IE6/7/8 cannot handle this nifty stuff so switch browsers if you have to.&lt;/p&gt;&lt;p&gt;When you buy a new (desktop) computer nowadays, you usually get a nice big screen. So, next to making this website work on small screens, I also wanted to give people a full-window experience. The bigger your screen, the more wide and fancy the website.&lt;/p&gt;&lt;p&gt;For now the maximum width is 1900px. I used HTML5 markup for the layout and outline. The columns are styled using &amp;quot;inline-block&amp;quot;. This was a sweet find because I didn&amp;#39;t have to worry about float and clearfix problems anymore! In this case it&amp;#39;s just bad luck for old IE users. This is my personal site and I want to be able to experiment with innovative technologies.&lt;/p&gt;&lt;h3&gt;Is this the perfect solution?&lt;/h3&gt;&lt;p&gt;You hear loads of people that say that @media-queries solve &amp;#39;all&amp;#39; our problems. With this new magic niftiness we can build &amp;#39;one&amp;#39; website that works on all screen sizes and devices.&lt;/p&gt;&lt;p&gt;But what happens when we use this technology is that we actually add more code in order to optimize for small, mobile devices. That&amp;#39;s a little weird don&amp;#39;t you think? Especially when we all know that speed matters a lot on mobiles.&lt;/p&gt;&lt;p&gt;I read a great article on fluid images by the &lt;a href="http://unstoppablerobotninja.com/entry/fluid-images" target="_blank"&gt;Ethan Marcotte&lt;/a&gt;. In this website I used a small bit of the techniques described by the Ethan. Every image scales when you resize the browser. This very fancy stuff on one side. But on the other side it&amp;#39;s a bad practice. Why load big images that get scaled down when you visit the website on an iPad or HTC device?&lt;/p&gt;&lt;h3&gt;Why did I use fluid images?&lt;/h3&gt;&lt;p&gt;Because I did not design a dedicated mobile site. I made a site that looks good on most screen resolutions. This way my visitors do not have to zoom in. I actually use &amp;#39;display:none&amp;#39; for images when you visit this site on a mobile device with a screen-width of 280px.&lt;/p&gt;&lt;p&gt;If you think about that, it really is against the &amp;#39;speed matters&amp;#39; rule for mobile websites. Luckily this is a very simple layout with hardly any images and it&amp;#39;s backend system is the fastest I&amp;#39;ve ever seen (&lt;a href="http://zotonic.com" target="_blank"&gt;Zotonic&lt;/a&gt;). So, no problems in the speed- and data usage departments.&lt;/p&gt;&lt;h3&gt;A final tought&lt;/h3&gt;&lt;p&gt;I have one final thought on just using @media-queries to transform your site into a mobile website. This is also mentioned in several articles on the wobbly web and by developers around me.&lt;/p&gt;&lt;p&gt;You should show different content on a mobile device then on a desktop screen. The mobile context is way more hands-on and goal focused. For example when you want to check the train times when you are running towards the station with a coffee in you hand. At that moment you do not want the corporate history of the train company in a slideshow on the homepage. You need those frakking departure times!&lt;/p&gt;&lt;p&gt;@media-queries are a great aspect of the responsive design movement out there. I love the fact that we design for multiple devices and think about the future. I hope to see more examples of experiments like mine and would love to see some best practices on responsive design of websites.&lt;/p&gt;&lt;p&gt;The future of web development is a bright one and I love to being a part of it!&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/1354</id>
			<updated>2010-10-05T13:20:24+02:00</updated>
			<published>2010-10-05T10:55:00+02:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/1354/mediafonds-updated" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/10/5/340.jpeg%28400x400%29%28AA858D7B475F0F04B3B97AFC90830B40%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/10/5/mf5_658x508.png%28400x400%29%28EF87B92874D85EB277EAB217A5461909%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/10/5/mf3_658x604.png%28400x400%29%28824A58812D1CC3C98D27A6902A82AF64%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/10/5/mf4_658x604.png%28400x400%29%285E1DA1EE405E7A702CD273A3337456F6%29.jpg" />
			

			<title>Mediafonds updated</title>
			
				<summary>The Mediafonds website was recently relaunched after finishing the second phase of the project.</summary>
				<content type="html">&lt;p&gt;To simplify the design &lt;a href="http://www.mannschaft.org" target="_blank"&gt;Mannschaft&lt;/a&gt; redesigned the navigation and made sure that new content is easier to find. This is why they added the &amp;quot;Acitiviteiten&amp;quot; link. The Etalage is still the main area of the site. It shows the ever growing productions that Mediafonds funds.&lt;/p&gt;&lt;p&gt;Other things that have been renewed are: the calendar overview, the &amp;quot;activiteiten&amp;quot; pages and there is a possibility to add a slideshow to a page.&lt;/p&gt;&lt;p&gt;See the new site here: &lt;a href="http://www.mediafonds.nl" target="_blank"&gt;http://www.mediafonds.nl&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;!-- z-media 1357 {"align": "block", "size": "middle", "crop": "crop", "link": ""} --&gt;&lt;/p&gt;&lt;p&gt;&lt;!-- z-media 1358 {"align": "block", "size": "middle", "crop": "crop", "link": ""} --&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/964</id>
			<updated>2010-10-09T01:08:55+02:00</updated>
			<published>2010-05-19T00:10:00+02:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/964/jquery-notice-featured-on-papermashup-com" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/5/19/ashley.png%28400x400%29%2822DC566C430A460D4B4B0FE62C9650BF%29.jpg" />
			

			<title>jQuery notice featured on papermashup.com</title>
			
				<summary>My jQuery "Growl-like" notification plugin has been featured on papermashup.com! Cool stuff! Thanks Ashley!</summary>
				<content type="html">&lt;h3&gt;The intro of the original article&lt;/h3&gt;&lt;p&gt;Last week I signed up Gravity a new site setup by a few guys that used to work at MySpace. As I was using the site I noticed these great little notifications popping up in my browser, Mac users will be familiar with this as they work in the same way as Growl notifications. I thought it was interesting that this technique of displaying live information to users could be presented in this way, so I went on the hunt for a similar jQuery plugin and found a number of results however the one that caught my eye was the &lt;a href="http://www.timbenniks.nl/blog/566/jquery-growl-like-notification-plugin"&gt;jQuery Notice plugin&lt;/a&gt; by &lt;a href="http://www.timbenniks.nl"&gt;Tim Benniks&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;See &lt;a href="http://papermashup.com/jquery-growl-notification-plugin/"&gt;Ashley&amp;#39;s post&lt;/a&gt; or my own &lt;a href="http://www.timbenniks.nl/blog/566/jquery-growl-like-notification-plugin" target="_self"&gt;project page about the &amp;quot;Growl-like&amp;quot;notification Plugin&lt;/a&gt;.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/954</id>
			<updated>2010-12-14T20:35:06+01:00</updated>
			<published>2010-05-18T09:53:00+02:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/954/about-jquery-and-performance" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/5/18/tumblr-ky63k668gx1qz4ts6o1-500.jpeg%28400x400%29%28389F5781630EF9EBB0BA9BC0A9385C64%29.jpg" />
			

			<title>About jQuery and performance</title>
			
				<summary>Once upon a time, all we needed to worry about was reducing Bytes and Requests and playing around with load order to make things faster. Nowadays, we are increasingly impacting one more major component in performance — CPU utilization. Using jQuery and other frameworks that make selecting nodes and DOM manipulation easy can have adverse affects if you’re not careful and follow some simple practices for reducing the work the browser has to do.</summary>
				<content type="html">&lt;p&gt;&lt;a href="http://www.artzstudio.com/2009/04/jquery-performance-rules/" target="_blank"&gt;Read the rest of this great article on Artzstudio.com.&lt;/a&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/829</id>
			<updated>2010-04-17T13:16:08+02:00</updated>
			<published>2010-04-15T13:10:00+02:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/829/how-to-make-a-simple-contact-form-in-zotonic" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/4/15/pen-and-paper.jpeg%28400x400%29%28F7955775B091E96488D83BDABCCFB83A%29.jpg" />
			

			<title>How to make a simple contact form in Zotonic</title>
			
				<summary>This tutorial teaches you to create a form, validate it, submit it over Ajax and e-mail the results back to you. </summary>
				<content type="html">&lt;p&gt;This article originally comes from &lt;a href="http://zotonic.com/documentation/807/implementing-a-simple-contact-form"&gt;zotonic.com&lt;/a&gt; and is written by &lt;a href="http://scherpenisse.net"&gt;Arjan Scherpenisse&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Making a simple contact form might seem difficult, but with the smart application of different Zotonic techniques you&amp;#39;ll see that it&amp;#39;s actually very easy.﻿&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;Create the contact page URL dispatcher and template&lt;/li&gt;&lt;li&gt;Create the contact form&lt;/li&gt;&lt;li&gt;Create the contact-form handler Erlang file.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-size: 18px; font-weight: bold;"&gt;Create the contact page URL dispatcher and template&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The URL dispatcher is placed in &lt;strong&gt;priv/sites/default/dispatch/dispatch&lt;/strong&gt;. Add this line:&lt;/p&gt;&lt;pre&gt;{contact_url, [&amp;quot;contact&amp;quot;], resource_template, [ {template, &amp;quot;contact.tpl&amp;quot;} ]},
&lt;/pre&gt;&lt;p&gt;This says that the page at &lt;strong&gt;&amp;quot;/contact&amp;quot;&lt;/strong&gt; will use the &lt;strong&gt;&amp;quot;contact.tpl&amp;quot;&lt;/strong&gt; template. Let&amp;#39;s create this template, at &lt;strong&gt;priv/sites/default/templates/contact.tpl&lt;/strong&gt;:&lt;/p&gt;&lt;pre&gt;{% extends &amp;quot;base.tpl&amp;quot; %}

{% block content %}
&amp;lt;h1&amp;gt;Contact page&amp;lt;/h1&amp;gt;
{% endblock %}
&lt;/pre&gt;&lt;p&gt;Now we have this, let&amp;#39;s try to see if it loads. Flush the Zotonic cache (to refresh the URL dispatchers) by going to &lt;em&gt;&amp;quot;modules&amp;quot;&lt;/em&gt; -&amp;gt; &lt;em&gt;&amp;quot;rescan modules&amp;quot;&lt;/em&gt; in the admin. Now, point your browser to &lt;a href="http://127.0.0.1/contact"&gt;http://127.0.0.1/contact&lt;/a&gt;. This should show the contact page with the template you just made.&lt;/p&gt;&lt;h2&gt;Create the contact form&lt;/h2&gt;&lt;p&gt;Now you should write the acual contact form. You should decide what fields you want in the form, so for now, just put a name, e-mail and comment field:&lt;/p&gt;&lt;pre&gt;{% wire id=&amp;quot;contact-form&amp;quot; type=&amp;quot;submit&amp;quot; postback={contact} delegate=&amp;quot;resource_default_contact&amp;quot; %}
&amp;lt;form id=&amp;quot;contact-form&amp;quot; method=&amp;quot;post&amp;quot; action=&amp;quot;postback&amp;quot;&amp;gt;

 &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name&amp;lt;/label&amp;gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;name&amp;quot; id=&amp;quot;name&amp;quot; /&amp;gt;

 &amp;lt;label for=&amp;quot;email&amp;quot;&amp;gt;E-mail&amp;lt;/label&amp;gt;
 &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;mail&amp;quot; id=&amp;quot;mail&amp;quot; /&amp;gt;
 {% validate id=&amp;quot;mail&amp;quot; type={presence} type={email} %}

 &amp;lt;label for=&amp;quot;message&amp;quot;&amp;gt;Message&amp;lt;/label&amp;gt;
 &amp;lt;textarea name=&amp;quot;message&amp;quot; id=&amp;quot;message&amp;quot; cols=&amp;quot;60&amp;quot; rows=&amp;quot;8&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
 {% validate id=&amp;quot;message&amp;quot; type={presence} %}

 &amp;lt;input type=&amp;quot;submit&amp;quot; value=&amp;quot;Send&amp;quot; /&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;p&gt;This template has 3 fields, of which the message and the e-mail are required, and the e-mail input has to contain a valid e-mail address. The name field is optional.&lt;/p&gt;&lt;h2&gt;Create the contact-form handler Erlang file.&lt;/h2&gt;&lt;p&gt;As you see in the &lt;a href="http://zotonic.com/scomp-wire"&gt;&lt;strong&gt;wire&lt;/strong&gt;&lt;/a&gt; statement in the contact form, the delegate argument is set to resource_default_contact, which is the name of an erlang module which we still have to create. When the form submits, this module&amp;#39;s &lt;strong&gt;event/2 &lt;/strong&gt;function gets called.Create a file &lt;strong&gt;priv/sites/default/resources/resource_default_contact.erl&lt;/strong&gt; with the following contents:&lt;/p&gt;&lt;pre&gt;-module(resource_default_contact).
-export([event/2]).

-include_lib(&amp;quot;zotonic.hrl&amp;quot;).

event({submit, {contact, []}, _TriggerId, _TargetId}, Context) -&amp;gt;
  ?DEBUG(z_context:get_q_all(Context)),
  Context.
&lt;/pre&gt;&lt;p&gt;This is the most simple version of a Zotonic form-handling function: it just dumps all form input it gets to the Zotonic console (using the &lt;strong&gt;?DEBUG &lt;/strong&gt;macro). To compile this Erlang module, enter the following on the zotonic console:&lt;/p&gt;&lt;pre&gt;z:m().
&lt;/pre&gt;&lt;p&gt;You&amp;#39;ll see a notice that the file is recompiled, which should end with a &amp;quot;ok&amp;quot; message to indicate the success. This compiling is actually very important: &lt;em&gt;Whenever you change the .erl file, you&amp;#39;ll need to recompile it using this command.&lt;/em&gt;&lt;/p&gt;&lt;h2&gt;Using mod_emailer to e-mail the contents of the contact form to somebody&lt;/h2&gt;&lt;p&gt;Using Zotonic&amp;#39;s mod_emailer modules, you can very easily send somebody an e-mail. Let&amp;#39;s  create a simple template to send the contents of the form to the site administrator.&lt;/p&gt;&lt;p&gt;Create the file priv/sites/default/templates/_email_contact.tpl:&lt;/p&gt;&lt;pre&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Contact form&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;p&amp;gt;Hello, the contact form of the site has been submitted.&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;Name: {{ name|escape }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;E-mail: {{ mail|escape }}&amp;lt;/p&amp;gt;
    &amp;lt;p&amp;gt;The contents of the message was this:&amp;lt;/p&amp;gt;
    &amp;lt;pre&amp;gt;{{ message|escape }}&amp;lt;/pre&amp;gt;
    &amp;lt;p&amp;gt;Regards, your website.&amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;p&gt;This template will function as the message body that will be sent. Note: this template gets scanned for the &amp;lt;title&amp;gt; tag, which will double as the e-mail&amp;#39;s subject, so be sure to include it!&lt;/p&gt;&lt;p&gt;Now we have to change our &lt;strong&gt;event/2&lt;/strong&gt; function to render this template and e-mail it using &lt;a href="http://zotonic.com/documentation/808/mod-emailer"&gt;&lt;em&gt;mod_emailer&lt;/em&gt;&lt;/a&gt;. Change the event function to the following:&lt;/p&gt;&lt;pre&gt;event({submit, {contact, []}, _TriggerId, _TargetId}, Context) -&amp;gt;
  Vars = [{mail, z_context:get_q(&amp;quot;mail&amp;quot;, Context)},
          {name, z_context:get_q(&amp;quot;name&amp;quot;, Context)},
          {message, z_context:get_q(&amp;quot;message&amp;quot;, Context)}],
  z_email:send_render(z_email:get_admin_email(Context), &amp;quot;_email_contact.tpl&amp;quot;, Vars, Context),
  z_render:update(&amp;quot;contact-form&amp;quot;, &amp;quot;&amp;lt;p&amp;gt;The form has been submitted! Thank you, we&amp;#39;ll get in touch soon.&amp;lt;/p&amp;gt;&amp;quot;, Context).
&lt;/pre&gt;&lt;p&gt;This loads the relevant values from the form, puts them in the Vars variable, and then calls the z_email module to mail the given template to the e-mail address of the site admin (which is defined in your site&amp;#39;s config file). For more information on sending mails from Zotonic, please see the&lt;a href="http://zotonic.com/documentation/808/mod-emailer"&gt; mod_emailer  documentation&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Finally, this contact-form handler replaces the contact form with a &amp;lt;p&amp;gt; tag with a success message, using the z_render:update function.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/727</id>
			<updated>2010-10-03T01:37:49+02:00</updated>
			<published>2010-03-24T11:31:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/727/zotonic-s-speed-a-benchmark-by-floris-benniks" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/24/speed.png%28400x400%29%28E1E4D152A179B5D9A16BCEB4DB49B520%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/24/benchmark-png-450x-a3dde32b4b6c9a8cf1fed27e310d6520.jpeg%28400x400%29%28F1530207019DA9C7FCF8B04501D2D3A8%29.jpg" />
			

			<title>Zotonic's speed, A benchmark by Floris Benniks</title>
			
				<summary>Dutch web developer Floris Benniks tried Zotonic in a work session we had the other day. After this session he had rebuild his site in Zotonic. Both his old php site and the new Zotonic site where running next to each other on his machine. Benchmark time baby!</summary>
				<content type="html">&lt;p&gt;Zotonic&amp;#39;s &lt;a title="Zotonic&amp;#39;s team" href="http://zotonic.com/zotonic-team" target="_blank"&gt;crew&lt;/a&gt; claims their framework is faster then the competition (Django, RoR, Wordpress, Drupal, Jooma!, etc). Any reasonably able developer does not just buy that. A simple benchmark could show a bit more of Zotonic&amp;#39;s potential. As &lt;a href="http://www.florisbenniks.nl" target="_blank"&gt;Floris&lt;/a&gt; had both his php site and his Zotonic site running on the same machine, it was the perfect environment for a comparison.&lt;/p&gt;&lt;p&gt;For the benchmark the &amp;quot;&lt;a href="http://www.florisbenniks.nl/about" target="_blank"&gt;about&lt;/a&gt;&amp;quot; page of his site was used. The &lt;a href="http://httpd.apache.org/docs/2.0/programs/ab.html" target="_blank"&gt;apache benchmark&lt;/a&gt; tool has been used for all testing.&lt;/p&gt;&lt;pre&gt;ab -n 1000 -c 100 http://127.0.0.1:8000/about/&lt;/pre&gt;&lt;p&gt;This command sends 1000 requests with 100 requests at the same time.&lt;/p&gt;&lt;h3&gt;Specs&lt;/h3&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;&lt;span style="font-weight: normal; font-size: 12px;"&gt;Zotonic uses postgreSQL 8.4 and Erlang R1304B. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;The php site uses PHP 5.2.1 and MySQL 5.1.3.&lt;/li&gt;&lt;li&gt;The test computer is a Q6600 @3.1ghz (quadcode), 8gb ram, Vertex ssd&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Requests per second&lt;/h3&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;PHP: 167.62 [#/sec]&lt;/li&gt;&lt;li&gt;Zotonic: 1795.91 [#/sec]&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Zotonic is 10.71x faster then the PHP site.&lt;/p&gt;&lt;h3&gt;Transfer rate&lt;/h3&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;PHP: 1023.23 [kb/sec]&lt;/li&gt;&lt;li&gt;Zotonic: 8130.70 [kb/sec]&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Zotonic is 7.94x faster then the PHP site.&lt;/p&gt;&lt;p&gt;&lt;!-- z-media 728 {"align": "block", "size": "large", "crop": "", "link": ""} --&gt;&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;As It turns out, Zotonic is indeed faster then his PHP website. Of course there are many ways of testing and this is just one of them. Let&amp;#39;s not see these numbers as final yet.&lt;/p&gt;&lt;p&gt;At least my mission has been accomplished. Floris is going to build all his websites in Zotonic from now on.&lt;/p&gt;&lt;p&gt;Check out the &lt;a href="http://florisbenniks.nl/blog/hoe-snel-is-zotonic-/" target="_blank"&gt;original&lt;/a&gt; Dutch article on &lt;a href="http://florisbenniks.nl" target="_blank"&gt;florisbenniks.nl&lt;/a&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/712</id>
			<updated>2010-05-19T20:56:22+02:00</updated>
			<published>2010-03-21T10:35:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/712/step-by-step-guide-to-install-zotonic-on-osx" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/21/dummies.png%28400x400%29%2831B3DC06110BE3BD5E8A8581EFA76DE5%29.jpg" />
			

			<title>Step by step guide to install Zotonic on OSX</title>
			
				<summary>In this post I will explain how to install Zotonic on OSX. If you are not really acquainted with Terminal.app, you will be after this!</summary>
				<content type="html">&lt;h2&gt;First things first&lt;/h2&gt;&lt;p&gt;You guys and gals need to download some software bundles to be able to start using Zotonic. You will need:&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;&lt;a title="Download Xcode here" href="http://developer.apple.com/technologies/tools/xcode.html" target="_blank"&gt;Xcode&lt;/a&gt; (OSX development bundle)&lt;/li&gt;&lt;li&gt;ImageMagick&lt;/li&gt;&lt;li&gt;&lt;a title="Download Erlang here" href="http://erlang.org/download/otp_src_R13B04.tar.gz" target="_blank"&gt;Erlang&lt;/a&gt; (preferably R13B04)&lt;/li&gt;&lt;li&gt;&lt;a title="Download PostgresSQL here" href="http://www.enterprisedb.com/getfile.jsp?fileid=879" target="_blank"&gt;PostgreSQL&lt;/a&gt; (preferably 8.4 or higher)&lt;/li&gt;&lt;li&gt;The Zotonic &lt;a title="Download the Zotonic source" href="http://code.google.com/p/zotonic/" target="_blank"&gt;source&lt;/a&gt; code&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;ImageMagick&lt;/h3&gt;&lt;p&gt;ImageMagick has loads of dependencies and extra bundles. Because of that, it&amp;#39;s a pain to install. But luckily &lt;a title="Download MacPorts here" href="http://distfiles.macports.org/MacPorts/MacPorts-1.8.2-10.6-SnowLeopard.dmg" target="_blank"&gt;MacPorts&lt;/a&gt; comes to the rescue. The MacPorts Project is an open-source community initiative to design an easy-to-use system for compiling, installing, and upgrading command-line stuff on OSX.&lt;/p&gt;&lt;p&gt;MacPorts will do all the dependency checks and installs them. Great stuff! First download &lt;a title="Download MacPorts here" href="http://distfiles.macports.org/MacPorts/MacPorts-1.8.2-10.6-SnowLeopard.dmg" target="_blank"&gt;MacPorts&lt;/a&gt; and install (don&amp;#39;t worry, it&amp;#39;s just a .pkg file).&lt;/p&gt;&lt;p&gt;After that type:&lt;/p&gt;&lt;pre&gt;sudo port install ImageMagick&lt;/pre&gt;&lt;h3&gt;Erlang&lt;/h3&gt;&lt;p&gt;To install Erlang you could use MacPorts again. To be honest I wouldn&amp;#39;t do that. It takes ages to check al the dependencies and it does not install the latest version. &lt;a title="Download erlnag" href="http://erlang.org/download/otp_src_R13B04.tar.gz" target="_blank"&gt;Just download this one&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Let the fun stuff begin and become a real command-line wizard! After you&amp;#39;ve downloaded Erlang, just unpack it. Open terminal, type cd and drag Erlang&amp;#39;s folder into the terminal. You will see something like this appear:&lt;/p&gt;&lt;pre&gt;cd /Users/tim/Downloads/otp_src_R13B04/&lt;/pre&gt;&lt;p&gt;Hit enter. Now that you are in, type the following commands to configure, compile and install Erlang. Note that each of them takes some time. Don&amp;#39;t put them in the same time, just one after another. Have some coffee / beer. This takes a while :-)&lt;/p&gt;&lt;pre&gt;./configure
make
sudo make install&lt;/pre&gt;&lt;h3&gt;PostgreSQL&lt;/h3&gt;&lt;p&gt;PostgreSQL has an excellent &lt;a title="Download PostgresSQL" href="http://www.enterprisedb.com/products/pgdownload.do#osx" target="_blank"&gt;installer&lt;/a&gt;. Just install the package. It could be that there are some issues with the memory management your Mac has and that PostgreSQL requires. If that is the case, just pm me on @&lt;a title="Twiytter account for Tim Benniks" href="http://twitter.com/timbenniks" target="_blank"&gt;timbenniks&lt;/a&gt;. If this starts to happen to more people, I will write up the solution here.&lt;/p&gt;&lt;h3&gt;The Zotonic source code&lt;/h3&gt;&lt;p&gt;You can just download the package from: http://code.google.com/p/zotonic/. If you are using Mercurial you can get Zotonic&amp;#39;s tip like this:&lt;/p&gt;&lt;pre&gt;hg clone https://zotonic.googlecode.com/hg/ zotonic&lt;/pre&gt;&lt;h2&gt;Now the good stuff!&lt;/h2&gt;&lt;p&gt;After all this downloading and compiling, we need to get to business with Zotonic. Here&amp;#39;s a list of what we need to do to make all of this happen.&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;Database crap&lt;/li&gt;&lt;li&gt;&amp;quot;Make&amp;quot; zotonic&lt;/li&gt;&lt;li&gt;Zotonic&amp;#39;s configuration&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Database crap&lt;/h3&gt;&lt;p&gt;Open pgadmin. Just do cmd+space and type pgadmin, your Mac will find it for you.&lt;/p&gt;&lt;p&gt;In the sidebar you will see a tree structure with just &amp;quot;Servers(1)&amp;quot; and then a PostgreSQL item under it. It should have a red cross. Double click that and type in the root password that you gave while installing PostgreSQL.&lt;/p&gt;&lt;p&gt;Afte this, click on the Databases item in the sidebar. The Postgres database will appear in the tree structure. Click on it and then click on the SQL button in the top bar.&lt;/p&gt;&lt;p&gt;Now a new window opens and we can query away! &lt;em&gt;Note: remove the default text that is in the window. &lt;/em&gt;We need to make a new user, a new database and grant the new user access to the new database. Please do these queries one at the time. Just paste in and press the little green play button in the top bar.&lt;/p&gt;&lt;pre&gt;CREATE USER zotonic WITH PASSWORD &amp;#39;yourdbpassword&amp;#39;;
CREATE DATABASE zotonic WITH OWNER = zotonic ENCODING = &amp;#39;UTF8&amp;#39;;
GRANT ALL ON DATABASE zotonic TO zotonic;
\c zotonic
CREATE LANGUAGE &amp;quot;plpgsql&amp;quot;;&lt;/pre&gt;&lt;h3&gt;Make Zotonic&lt;/h3&gt;&lt;p&gt;I would suggest that you put the Zotonic folder in the &amp;quot;Sites&amp;quot; directory that lives in your home folder. Please note that the root folder of Zotonic needs to be named &lt;strong&gt;zotonic&lt;/strong&gt; at all times. Sorry for this, we are working on it :-P&lt;/p&gt;&lt;p&gt;No open terminal and &amp;quot;cd&amp;quot; into this folder. Obviously my name should be swapped with your username.&lt;/p&gt;&lt;pre&gt;cd /Users/tim/Sites/zotonic
make&lt;/pre&gt;&lt;h3&gt;Zotonic&amp;#39;s configuration&lt;/h3&gt;&lt;p&gt;If you open the Zotonic folder you find a &amp;quot;priv&amp;quot; folder. Your projects will live in there. For now we will use Zotonic&amp;#39;s default site. We need to rename the config for it to be read by Zotonic.&lt;/p&gt;&lt;pre&gt;cp priv/sites/default/config.in priv/sites/default/config&lt;/pre&gt;&lt;p&gt;Then, edit that file and change the values of dbpassword, sign_key_simple and sign_key:&lt;/p&gt;&lt;pre&gt;% Configuration of the default site.
[
% This site is enabled or not.
{enabled, true},
 
% Atomic hostname, MUST be equal to the directory name of this site.
{host, default},
 
% Hostname for virtual host support
{hostname, &amp;quot;127.0.0.1:8000&amp;quot;},
{hostalias, &amp;quot;localhost:8000&amp;quot;},
% PostgreSQL database connection
{dbhost, &amp;quot;127.0.0.1&amp;quot;},
{dbport, 5432},
{dbuser, &amp;quot;zotonic&amp;quot;},
{dbpassword, &amp;quot;yourdbpassword&amp;quot;},
{dbdatabase, &amp;quot;zotonic&amp;quot;},

% Admin password, used during installation. You can change it later
{adminpassword, &amp;quot;admin&amp;quot;},

% Key used for signing image urls with image manipulations (crop, rotate, resize, etc.)
% A new key will force regenerating images, which takes cpu time and will fill your hard disk.
{sign_key_simple, &amp;lt;&amp;lt;&amp;quot;--change-me--&amp;quot;&amp;gt;&amp;gt;},

% Key used for signing postbacks - this _must_ be a hard to guess key, otherwise your system is insecure.
% When not defined, then zotonic will generate a new key on every restart.
% When a new key is generated then all postbacks from old html pages will fail.
{sign_key, &amp;lt;&amp;lt;&amp;quot;--change-me--&amp;quot;&amp;gt;&amp;gt;}
].&lt;/pre&gt;&lt;p&gt;Make sure that the directory &amp;quot;priv/sites/default/files&amp;quot; and all its subdirectories are readable and writeable for the current user (Which is the user zotonic will run under).&lt;/p&gt;&lt;pre&gt;chmod -R +rw /Users/tim/Sites/zotonic/priv/sites/default/files&lt;/pre&gt;&lt;p&gt;Now start up Zotonic! Go to Zotonic root folder and type:&lt;/p&gt;&lt;pre&gt;./start.sh&lt;/pre&gt;&lt;p&gt;You see zotonic starting up, lots of messages pass by, and zotonic will install the initial database. When something goes wrong here, then it is almost always a problem with the database connection. Check your database configuration in the config file.&lt;/p&gt;&lt;p&gt;Point your browser to http://localhost:8000/ or logon as admin (the default password is &amp;#39;admin&amp;#39;) at: http://localhost:8000/admin/&lt;/p&gt;&lt;p&gt;When all done, then you can stop the Erlang shell with:&lt;/p&gt;&lt;pre&gt;q().&lt;/pre&gt;&lt;p&gt;That&amp;#39;s all folks. Good luck messing around with Zotonic. The next post will be about setting up a new project and about the basics of dispatch rules and templates.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/693</id>
			<updated>2010-05-21T11:22:38+02:00</updated>
			<published>2010-03-18T11:04:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/693/the-myth-of-the-page-fold" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/18/xentex-dual-screen-folding-laptop-1.jpeg%28400x400%29%280C9F04B03926AEF363568E2806C949CD%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/18/longpages.png%28400x400%29%28FA4ACECC0AE6EF2D238B959B0B55BAE7%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/18/brisair.png%28400x400%29%28DBD20D9372B7BC0AB625CAB51AD64A0C%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/18/fcold.png%28400x400%29%28F7AB18A77946FBDC0324565F175B26ED%29.jpg" />
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/18/fcnew1.jpeg%28400x400%29%28649E0E4E89C21EFD7ACF4270224C6A19%29.jpg" />
			

			<title>The myth of the page fold</title>
			
				<summary>As web professionals, we all know that the concept of the page fold being an impenetrable barrier for users is a myth. Over the last 6 years cxpartners have watched over 800 user testing sessions and only 3 on occasions they have seen the page fold as a barrier to users getting to the content they want.</summary>
				<content type="html">&lt;p&gt;&lt;a href="http://www.cxpartners.co.uk/thoughts/the_myth_of_the_page_fold_evidence_from_user_testing.htm" target="_blank"&gt;Read the rest of this article at cxpartners.co.uk&lt;/a&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/669</id>
			<updated>2010-03-13T20:30:32+01:00</updated>
			<published>2010-03-13T20:10:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/669/timbenniks-nl-featured-at-1webdesigner-com" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/13/1stwebdesigner.png%28400x400%29%286115ED25A02B8A3F9CFC86862B0908F7%29.jpg" />
			

			<title>timbenniks.nl featured at 1stwebdesigner.com</title>
			
				<summary>My website has been featured at 1stwebdesigner.com by Andy Walpole in a post about hmtl5 and the future of the web. </summary>
				<content type="html">&lt;p&gt;Thanks &lt;a href="http://www.1stwebdesigner.com/author/andy-walpole/"&gt;Andy&lt;/a&gt;, for including me into your sweet blogpost!&lt;/p&gt;&lt;p&gt;Read it here: &lt;a href="http://www.1stwebdesigner.com/inspiration/ultra-modern-websites-html5/"&gt;http://www.1stwebdesigner.com/inspiration/ultra-modern-websites-html5/&lt;/a&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/667</id>
			<updated>2010-05-21T12:21:08+02:00</updated>
			<published>2010-03-10T23:49:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/667/cross-browser-at-font-face-support" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/11/font-face.png%28400x400%29%283D2E2BA3EF38928D12E58C7D9410A6C4%29.jpg" />
			

			<title>Cross-browser @font-face support</title>
			
				<summary>At the moment, web fonts are all the buzz. After reading this post, you designer will love you! It describes how the usage @font-face works cross-browser.</summary>
				<content type="html">&lt;p&gt;Read the rest of this great post on &lt;a href="http://blog.themeforest.net/tutorials/how-to-achieve-cross-browser-font-face-support/" target="_blank"&gt;themeforest.com&lt;/a&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/664</id>
			<updated>2010-03-09T21:45:26+01:00</updated>
			<published>2010-03-09T21:33:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/664/zotonic-destroys-wordpress-and-rethinks-the-cms-with-erlang" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/3/9/screen-shot-2010-03-09-at-9-40-33-pm.png%28400x400%29%28BB1ED7D42673D23C25DA02389AE402CA%29.jpg" />
			

			<title>Zotonic destroys WordPress and rethinks the CMS with Erlang </title>
			
				<summary>Chad DePue from Erlanginside.com did an Interview with Marc Worrell, who is one of the principal developers of Zotonic.</summary>
				<content type="html">&lt;p&gt;Chad DePue took a minute from getting ready for his talk at Erlang Factory (and working on the day job) to talk with &lt;a href="http://zotonic.com/zotonic-team"&gt;Marc Worrell&lt;/a&gt;, Lead Architect of &lt;a href="http://zotonic.com"&gt;Zotonic&lt;/a&gt; – a new Content Management System written entirely in Erlang. This is a brief overview of the system focused on the ‘why’ – the technical details are well covered on their site, but he wanted to understand the motivations behind a company taking on a project like this.&lt;/p&gt;&lt;p&gt;Read the interview here: &lt;a href="http://erlanginside.com/zotonic-destroys-wordpress-and-rethinks-the-cms-with-erlang-149"&gt;http://erlanginside.com/zotonic-destroys-wordpress-and-rethinks-the-cms-with-erlang-149&lt;/a&gt;&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/568</id>
			<updated>2010-03-08T16:26:59+01:00</updated>
			<published>2010-02-23T14:41:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/568/how-to-effectively-communicate-with-developers" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload835-320-320.jpeg%28400x400%29%2878A7A9E204A99D93B353F4B025B753EE%29.jpg" />
			

			<title>How to effectively communicate with developers.</title>
			
				<summary>If you have ever worked with a developer or a development team, this article will probably strike close to home. As designers, we work with dozens of developers across the globe each year. Some of us are fortunate enough to find a gem; a developer that just gets it. A developer that you feel is on your same wavelength in terms of what needs to be accomplished with the user interface, and what it needs to happen. Most often, however, we find developers that we generally don’t see eye to eye with.</summary>
				<content type="html">&lt;p&gt;Read this the rest of this amazingly cool article &lt;a href="http://www.smashingmagazine.com/2009/08/14/how-to-effectively-communicate-with-developers/" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/566</id>
			<updated>2010-05-05T22:26:46+02:00</updated>
			<published>2010-02-23T14:37:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/566/jquery-growl-like-notification-plugin" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload4172-320-320.jpeg%28400x400%29%28B1844E10ABCEEFB1942256C6273460E8%29.jpg" />
			

			<title>jQuery “growl–like” notification plugin.</title>
			
				<summary>This is project is a simple jQuery plugin called jQuery Notice. As the names says, you can give notification to the users of your side.</summary>
				<content type="html">&lt;h3&gt;What! Another one?&lt;/h3&gt;&lt;p&gt;There are more growl-like notification plugins out there, and I hear you thinking: why yet another one!?  Well. The other plugins out there are not written in a style that I like.  I needed my notifications more flexible and lightweight. The project is hosted on the &lt;a title="jQuery notice at the jQuery pluings area" href="http://plugins.jquery.com/project/jquery-notice"&gt;jQuery plugins repository&lt;/a&gt; and on &lt;a title="jQuery notice on google code" href="http://code.google.com/p/jquery-notice/"&gt;google code&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;How it works&lt;/h3&gt;&lt;p&gt;This plugin extends jQuery. That means that you can call it like this: &lt;strong&gt;jQuery.noticeAdd()&lt;/strong&gt; or &lt;strong&gt;jQuery.noticeRemove()&lt;/strong&gt;. The fact that it is not bound to an html object makes this plugin very easy to use. It is callable or removable from any function. For example: it could be initiated as callback from a function or on a success or failure after an Ajax request. More info &lt;a href="http://timbenniks.nl/sandbox/900/jquery-growl-like-notification-plugin"&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/564</id>
			<updated>2010-05-05T22:00:28+02:00</updated>
			<published>2010-02-23T14:32:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/564/about-the-atatonic-css-framework" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload6009-320-320.jpeg%28400x400%29%2881762A1A22D0B021035D50AB04A845F5%29.jpg" />
			

			<title>About the Atatonic CSS Framework.</title>
			
				<summary>This is the project page for the CSS Framework Atatonic to make my life as a web developer easier. It is created out of my experience as a front end engineer and because some new big projects are coming up this year. I do not want to be spending my time in rebuilding CSS I have already build some other time.</summary>
				<content type="html">&lt;h3&gt;What! Another one?&lt;/h3&gt;&lt;p&gt;Lately there are more and more CSS frameworks popping out of ground. My issue with most of them is that they mainly focus on the grid. All the other options are added in later. This framework has its main focus on typography. Vertical rhythm is one of the most important things in design, so why not start your perspective from that angle?&lt;/p&gt;&lt;p&gt;To make my life easier as a developer I added grid support in the Atatonic CSS Framework. Its works like any other grid system, but with only about 10 lines of css.&lt;/p&gt;&lt;p&gt;The main goal of this project is to provide a solid base to start with every project. I do not want to bloat this framework with features. That is what you do in the project specific styles. The combined file is only 5kb. Deflate of gzip it and you are down to 3kb.&lt;/p&gt;&lt;h3&gt;Incremental development&lt;/h3&gt;&lt;p&gt;The Atatonic CSS Framework is still very young. It is a basic set-up of typography and grid tools. Changes will be made and things will be added in the process. I aim to keep the core small and voerviewable. So extra features will be added as plugins. Like a stylesheet for forms or something that adds extra typographical features.&lt;/p&gt;&lt;p&gt;&lt;a title="Atatonic CSS Framework" href="http://atatonic.timbenniks.nl"&gt;Check&lt;/a&gt; it out.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/559</id>
			<updated>2010-12-14T20:34:40+01:00</updated>
			<published>2010-02-23T14:28:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/559/hands-on-rules-for-a-fast-website" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload2348-320-320.jpeg%28400x400%29%28FC5B626D1AACAA5658AAEEC2DE200463%29.jpg" />
			

			<title>Hands on rules for a fast website.</title>
			
				<summary>It is no secret that users prefer faster web sites. But what happens during the time a user waits for a page to load? The key insight is the realization that only 10-20% of the total end-user response time is spent 
getting the HTML document to the browser. You need to focus on the other 80--90% if you want to make your pages noticeably faster. </summary>
				<content type="html">&lt;p&gt;Yahoo! did some great research on this subject and came up with 14 rules.  In a series of posts I will talk about the rules that I think are the most important. I will give some background information and explain how to implement them by examples of my own code.&lt;/p&gt;&lt;h3&gt;The 80/20 performance rule&lt;/h3&gt;&lt;p&gt;This rule is commonly referred to as the Pareto principle (also known as the 80-20 rule),  which states for any phenomenon, 80% of the consequences come from 20% of the causes.&lt;/p&gt;&lt;p&gt;We see this phenomenon in software engineering or designing where 80% of the time is spent in  only 20% of the code or details in the design.  When we optimize our applications, we know to focus on that 20% of the code.  This same technique should also be applied when optimizing web pages.&lt;/p&gt;&lt;p&gt;Most performance optimization today are made on the parts that generate the HTML document (apache, databases, template engines, etc.),  but those parts only contribute to about 10-20% of the user’s response time.  It is better to focus on optimizing the parts that contribute to the other 80-90%.&lt;/p&gt;&lt;h3&gt;Reduce your http requests!&lt;/h3&gt;&lt;p&gt;Every external file you include has to be processed and loaded after the html has been loaded.  The more you include, the more http request the browser has to handle. The impact of having many components in the page is exacerbated by the fact that browsers download only two or sometimes four components  in parallel per hostname, depending on the HTTP version of the response and the user&amp;#39;s browser.  Yahoo!&amp;#39;s research shows that reducing the number of HTTP requests has the biggest impact on reducing response time and  is often the easiest performance improvement to make.&lt;/p&gt;&lt;p&gt;When you cache these external files in the user&amp;#39;s browser, you can have remarkable speed improvements. More on that in the next post.&lt;/p&gt;&lt;h3&gt;Ways of reducing http requests&lt;/h3&gt;&lt;p&gt;One way to reduce the number of components in the page is to simplify the page&amp;#39;s design.  But is there a way to build pages with richer content while also achieving fast response times?  Here are some techniques for reducing the number of HTTP requests, while still supporting rich page designs.&lt;/p&gt;&lt;h3&gt;Combine files&lt;/h3&gt;&lt;p&gt;This way you reduce the number of HTTP requests by combining all scripts into a single script and combining all CSS into a single stylesheet.  Combining files is more challenging when the scripts and stylesheets vary from page to page,  but making this part of your release process improves response times.&lt;/p&gt;&lt;p&gt;This is a simplified example of my library.php code.  In future posts I will use this code and add caching, gzip and different ways of compressing to it.&lt;/p&gt;&lt;pre&gt;/**
 * library.php
 * Controller to fetch css or js script files.
 *
 * @package     timbenniks.com    
 * @author      Tim Benniks - tim@timbenniks.com
 * @copyright   2009 timbenniks.com
 * @version     $Id: library.php 63 2009-01-16 09:24:18Z timbenniks $
 */

// create variables from $_GET[&amp;#39;files&amp;#39;]
$string 	 = explode(&amp;#39;.&amp;#39;, $_GET[&amp;#39;files&amp;#39;]);
$files	 	 = $string[0];
$extention 	 = $string[1];
$all_files	 = explode(&amp;#39;,&amp;#39;, $files);

$cached_file = &amp;#39;./cache/&amp;#39;.urlencode($files).&amp;#39;.&amp;#39;.$extention;

// set the right content type
if($extention == &amp;#39;css&amp;#39;)
{
	header(&amp;#39;Content-type: text/css&amp;#39;);
}
elseif($extention == &amp;#39;js&amp;#39;)
{
	header(&amp;#39;Content-type: text/javascript&amp;#39;);
}

// If the file is not cached, create it. 
if(!file_exists($cached_file))
{	
	for($i = 0; $i &amp;lt; count($all_files); $i++)
	{
		if(is_file($extention.&amp;#39;/&amp;#39;.$all_files[$i].&amp;#39;.&amp;#39;.$extention))
		{
			$put_contents = true;
			$join_files   = file($extention.&amp;#39;/&amp;#39;.$all_files[$i].&amp;#39;.&amp;#39;.$extention);
			$all_in_one   = join(&amp;#39;&amp;#39;, $join_files);
		}
		else
		{
			$put_contents = false;
			header(&amp;quot;HTTP/1.0 404 Not Found&amp;quot;);
		}	
	}

	if($put_contents)
	{
		file_put_contents($cached_file, $all_in_one);
		echo $all_in_one;
	}
}
else
{
	echo file_get_contents($cached_file);
}&lt;/pre&gt;&lt;h3&gt;CSS Sprites&lt;/h3&gt;&lt;p&gt;This is the preferred method for reducing the number of image requests. Only one! For multiple images. Combine your background images into a single image and use the CSS background-image and background-position properties  to display the desired image segment.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;Reducing the number of HTTP requests in your page is the place to start.  This is the most important guideline for improving performance for first time visitors. Most of the time 40-60% of daily visitors to your site come in with an empty cache.  Making your page fast for these first time visitors is key to a better user experience.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/557</id>
			<updated>2010-05-21T12:24:03+02:00</updated>
			<published>2010-02-23T14:26:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/557/composing-with-web-typography" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload1323-320-320.jpeg%28400x400%29%28CFFD85BD219D150965E32008E50AD957%29.jpg" />
			

			<title>Composing with web typography.</title>
			
				<summary>Space in typography is like time in music. It is infinitely divisible, but a few proportional intervals can be much more useful than a limitless choice of arbitrary quantities. — Robert Bringhurst. This post will be explaining the techniques used to achieve these neat proportional intervals.</summary>
				<content type="html">&lt;p&gt;This article has quotations from &lt;a href="http://24ways.org" target="_blank"&gt;24ways&lt;/a&gt; and &lt;a href="http://alistapart.com" target="_blank"&gt;A List apart&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Just as regular use of time provides rhythm in music, regular use of space provides rhythm in typography.  Without rhythm the listener or the reader becomes disorientated, lost or totally bored.&lt;/p&gt;&lt;p&gt;On the Web, vertical rhythm (the spacing and arrangement of text as the reader descends the page)  is contributed to by three factors: font size, line height and margin.  All of these factors must calculated with care in order that the rhythm is maintained.&lt;/p&gt;&lt;p&gt;The basic unit of vertical space is line height. Establishing a suitable line height that can be applied to all text on the page is the key to a solid dependable vertical rhythm which will engage and guide the reader down the page.&lt;/p&gt;&lt;h3&gt;Establishing a suitable line height&lt;/h3&gt;&lt;p&gt;Before we start you have to know that the default setting of a browser (yep, all of them!) is 96dpi with a basic font size of 16px. So 1em would be 16px. The easiest place to begin determining a basic line height unit is with the font size of the body.&lt;/p&gt;&lt;p&gt;I almost always go for 12px. That is because the table of 12 is divisible by 1, 2, 3, 4 and 6. So it is easy to switch to 24, 36 or even 18. To ensure readability the body text will almost certainly need some leading, that is to say spacing between the lines. A line-height of 1.5 times 12 would give 6px spacing between the lines of the body text.  This will create a total line height of 18px, which becomes our basic unit.&lt;/p&gt;&lt;p&gt;Here’s the CSS to get us to this point:&lt;/p&gt;&lt;pre&gt;body {
	font-size: 75%; 
}

html&amp;gt;body {
	font-size: 12px;
	line-height: 18px;
}
&lt;/pre&gt;&lt;p&gt;There are many ways to size text in CSS and the above approach provides and accessible method of achieving the pixel-precision  solid typography requires. The first font-size in the example reduces  the body text from the 16px default down to the 12px we require.&lt;/p&gt;&lt;p&gt;This rule is primarily there for Internet Explorer 6 and below on Windows: the percentage value means that the text will scale  predictably should a user bump the text size up or down. The second font-size sets the text size specifically and is ignored by IE6,  but used by Firefox, Safari, IE7, Opera and other modern browsers which allow users to resize text sized in pixels.&lt;/p&gt;&lt;p&gt;As you can see I have used pixels as measurement here. Further down below I explain why.&lt;/p&gt;&lt;h3&gt;Spacing between paragraphs&lt;/h3&gt;&lt;p&gt;With our rhythmic unit set at 18px we need to ensure that it is maintained throughout the body.  A common place to lose the rhythm is the gaps set between margins.  The default treatment by web browsers of paragraphs is to insert a bottom-margin of 1em.  In our case this would give a spacing between the paragraphs of 12px and hence throw the text out of rhythm.&lt;/p&gt;&lt;p&gt;If the rhythm of the page is to be maintained, the spacing of paragraphs should be related to the basic line height unit.  This is achieved simply by setting bottom-margins equal to the line height.&lt;/p&gt;&lt;pre&gt;p {
	font-size: 12px;
	line-height: 18px;
	margin: 0 0 18px 0;
}
&lt;/pre&gt;&lt;h3&gt;Don&amp;#39;t fear the pixel!&lt;/h3&gt;&lt;p&gt;As you can see I code in pixels. Let me explain this before you guys hit me! At Mediamatic Lab we mainly build websites that are designed around and by typography. After many attempts we came to the conclusion that building a website that is based on typography gets easier using pixels. When designing a practical system like this, it’s important that it’s relatively easy (for yourself and others) to use and maintain.&lt;/p&gt;&lt;p&gt;With pixels, I can set one base line height for the entire document and I don’t have to recalculate it whenever I use a smaller or bigger font size.  If you wanted to make your font a bit bigger, just up it one pixel and leave your line height the same.&lt;/p&gt;&lt;p&gt;An easy example to show the difference between relative sizes and pixels:&lt;/p&gt;&lt;pre&gt;p {
	font-size: 14px;
	line-height: 18px;
	margin: 0 0 18px 0;
}

p {
	font-size: 1.1667em;
	line-height: 1.286;
	margin: 0 0 1.286em 0;
}	
&lt;/pre&gt;&lt;p&gt;You can use relative sizes, but it quickly becomes a lot more difficult to maintain as the math becomes more complicated.  As you can see in the example, the line height had to be recalculated to make sure it would still be 18px with a font of 14px.  If I would have kept it 1.5 like you would want, it becomes 1.5 times 14 which becomes: 21 instead of 18. If you have a big page with a lot of elements and you make a small miscalculation,  your whole rhythm could be gone and predicting how browsers are going to round your values makes it hard to be exact.&lt;/p&gt;&lt;h3&gt;In the end, it&amp;#39;s a tradeoff&lt;/h3&gt;&lt;p&gt;Most browsers will scale pixel-based line-heights proportionally along with the text.  Of course, the margins don&amp;#39;t scale, and neither do the images.  But is it worth making the system more complicated just to make the margins scale if the images don&amp;#39;t?&lt;/p&gt;&lt;p&gt;Consider the amount of people that use ie6 is becoming less and less.  And for that percentage of the ie6 users, how many scale websites? If they really need bigger fonts, they need that on their whole computer and they have probably set their screen to 120dpi.&lt;/p&gt;&lt;p&gt;There you have two other reasons then technique to just use pixels.&lt;/p&gt;&lt;p&gt;At some point as designers we have to strike a balance between creating pixel-perfect layouts and infinitely flexible ones. When you get down to it, resizable text is primarily an accessibility feature, not a design feature. Ideally it’s something that should be provided by the browser, no matter how the page is built, and in modern browsers it is. As long as all your content is readable and accessible at all sizes, it’s not necessarily true that the design must maintain integrity as you scale.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/555</id>
			<updated>2010-05-19T09:44:12+02:00</updated>
			<published>2010-02-23T14:23:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/555/the-basics-of-web-typography" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload619-320-320.jpeg%28400x400%29%287CB4DEFF4BB381DBD520EA0A2BA7304C%29.jpg" />
			

			<title>The basics of web typography.</title>
			
				<summary>This post is about web typography and it's recipe of four fundamental ingredients. Typography is cool, hip and artful. Therefore it's a shame that it's basic requirements are almost never met by web designers.</summary>
				<content type="html">&lt;p&gt;If you ever made a nice risotto, you know that this recipe takes a lot of care and effort to make it taste just right. Put to much water to quickly and it becomes blobby, put to little to late and it turns out dry and tastes like cardboard. The same go&amp;#39;s for typography. Apart from content, typography can make or break your website.&lt;/p&gt;&lt;p&gt;Typography for the web has come a long way since web 0.1.  In these old days typography for the web was not an important thing.  Today things are different.  Not only do we have modern browsers that support images (yeah!),  but we have the opportunity to make our pages come to life through great typography.&lt;/p&gt;&lt;h3&gt;Contrast&lt;/h3&gt;&lt;p&gt;Pale pink text on a pale blue background, is very cool for an old school t-shirt, but it doesn’t read well.  Text is there to be read. Make sure that it contrasts enough with the background to achieve that.  If you’re ever unsure about contrast, then take a screen dump of your page, open up your image editing software and reduce the image to grey-scale.  You’ll soon see if you have enough contrast.  &lt;a title="Robert Bringhurst" href="http://en.wikipedia.org/wiki/Robert_Bringhurst"&gt;Robert Bringhurst&lt;/a&gt;, a very cool typographer writes: &amp;quot;...typography exists to honor content&amp;quot;.  Are we honoring the content if we design our pages in such a way that the content is difficult to read?&lt;/p&gt;&lt;p&gt;Personally I dislike to read long stretches of reversed out text (e.g. white text on a dark or black background).  It may well be appropriate for shorter stretches of text on-screen, but I find it very tiring to read for any length of time.&lt;/p&gt;&lt;h3&gt;Size&lt;/h3&gt;&lt;p&gt;This one is easy. Don’t set body text below 11px and, if possible, make it bigger.  Remember, what’s legible on your 65&amp;quot; High Definition Plasma monitor, might not be so on a 15&amp;quot; MacBook. If in doubt, make it bigger!&lt;/p&gt;&lt;h3&gt;Hierarchy&lt;/h3&gt;&lt;p&gt;Varying type size is one of the best ways to differentiate content.  Colors and pretty boxes might help, but different sizes of type throughout your pages  will show your readers the importance of your pages.  If you have readers that are in a hurry, they can quickly pick out the important bits and might stay longer and read on.&lt;/p&gt;&lt;p&gt;Hierarchy can be achieved in other ways too.  I&amp;#39;ve just mentioned using different sizes of type to achieve it, but you can also use different styles. For example all-caps or using italic for sub-headings.  Serif and sans serif faces can also be mixed to good effect.&lt;/p&gt;&lt;h3&gt;Space&lt;/h3&gt;&lt;p&gt;Let your type breathe. Don&amp;#39;t be afraid to leave blank spaces in your pages.  This white space will help focus attention on the text.  Next, remember &lt;strong&gt;line-height&lt;/strong&gt;. A good rule of thumb is line-spacing that’s at least 150% of your text size. (e.d. 12px font-size and 18px line-heigt). Good type designers put a whole lot of effort into the micro white space that sits inside type.  They spend countless hours attempting to achieve a balance (vertical rhythm) between the lines of text. Likewise, we should take time to consider the macro white space, the &amp;#39;voids&amp;#39; that shape our blocks of text.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;Remember, these are not rules, but rather guidelines.  However, follow them and your site will have that thing that makes user like you website very much instead of just a nice one.&lt;/p&gt;&lt;p&gt;The next post will be about the research I did on what CSS technique to use. It will show some different approaches with their pro&amp;#39;s and con&amp;#39;s.&lt;/p&gt;&lt;p&gt;This post is inspired by a great blogpost on the website &lt;a href="http://www.iLoveTypography.com"&gt;iLoveTypography&lt;/a&gt;.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/552</id>
			<updated>2011-01-31T14:39:05+01:00</updated>
			<published>2010-02-23T14:19:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/552/cross-browser-rounded-corners" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload9562-320-320.jpeg%28400x400%29%28B3A37F8DD4DCB77144867EFBC4C585B3%29.jpg" />
			

			<title>Cross-browser rounded corners.</title>
			
				<summary>Round corners. Something that should be easy, right? Not so much. It seems they were left out of the CSS 2.1 specification. No matter, there are a couple of ways to hack them out and make them look good. This post contains several solutions with their pro‚s and con‚s. All mentioned solutions have support for modern browsers and anti-aliasing. </summary>
				<content type="html">&lt;p&gt;Every element in HTML is square. You can apply a background image to an element to make it look round, but the element itself is still square.&lt;/p&gt;&lt;p&gt;CSS3 comes with a heaven-sent solution: border-radius. It allows you to apply a rounded corner or border to an element without the use of extra markup or Javascript. Unfortunately, only Gecko (Firefox&amp;#39;s rendering engine) and Webkit (Safari, Chrome) support it, with prefixed equivalents -webkit-border-radius and -moz-border-radius, because their support is still experimental.&lt;/p&gt;&lt;p&gt;Webkit and Gecko have a market share of 20% and 7%. What to do with the other 73%, mainly Internet Explorer 6 and 7? We don&amp;#39;t want to serve the majority square corners, while only a minority sees the beautiful round corners, right?&lt;/p&gt;&lt;p&gt;And what about Opera? Wasn&amp;#39;t that browser pretty modern? Well, Opera supported -o-border-radius in 2006 in version 9 of their browser, but they removed the support in 9.1 for unknown reasons. So we need a cross-browser solution. Fortunately, there are a few:&lt;/p&gt;&lt;h3&gt;Adding markup&lt;/h3&gt;&lt;p&gt;The most straight-forward solution to create rounded corners on a box is by adding extra markup (html) to the box to apply corner backgrounds to. With a fixed width and height, you only need one element to show four rounded corners. With a fixed width and dynamic height, you need at least two elements. With a dynamic width and dynamic height, you need four.&lt;/p&gt;&lt;p&gt;In most cases, you won&amp;#39;t need extra elements for types 1 and 2. For example, when you have markup that already looks like this:&lt;/p&gt;&lt;pre&gt;&lt;div&gt;&lt;h3&gt;Title&lt;/h3&gt;&lt;p&gt;Text&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;If only the height is dynamic, the complete top (with the top-left and top-right rounded corners) can be applied to the h3, which overlaps the div. The div itself has a very tall background image positioned from the bottom, with the bottom-left and bottom-right corners and the filling for the middle.&lt;/p&gt;&lt;p&gt;With a dynamic height and dynamic width and using the same markup, you don&amp;#39;t have enough elements to apply a corner to. The div can contain the top-left corner and the filling, the h3 can have the top-right corner, but then we&amp;#39;re still two elements short, so we&amp;#39;ll need to add two more elements to show the bottom corners. Our new markup:&lt;/p&gt;&lt;pre&gt;&lt;div&gt;&lt;h3&gt;Title&lt;/h3&gt;&lt;p&gt;Text&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;Now we can add the bottom background images to the spans, but our beautiful clean html is cluttered.&lt;/p&gt;&lt;h3&gt;Making it dynamic&lt;/h3&gt;&lt;p&gt;To keep our markup clean, we could add a little Javascript. Let&amp;#39;s take our first markup snippet again, and add a class to it:&lt;/p&gt;&lt;pre&gt;&lt;div class="rounded"&gt;&lt;h3&gt;Title&lt;/h3&gt;&lt;p&gt;Text&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;We could now tell Javascript to add four span&amp;#39;s to all elements with the class &amp;quot;rounded&amp;quot;. We want to get this result:&lt;/p&gt;&lt;pre&gt;&lt;div class="rounded"&gt;&lt;h3&gt;Title&lt;/h3&gt;&lt;p&gt;Text&lt;/p&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;This transformation only takes a few simple lines of code, especially when using jQuery. With our Javascript-generated corner spans, we have enough elements to apply corners to, and we could generate general styles using the classes which are the same for every rounded box. A small note: if the background below the div has a pattern or gradient, you need even more elements so they aren&amp;#39;t overlapping eachother. Also, use caution using this method with existing sites. If you have any scripts that don&amp;#39;t expect your site&amp;#39;s markup to be modified by another script, it may break stuff.&lt;/p&gt;&lt;h3&gt;Making it super-dynamic&lt;/h3&gt;&lt;p&gt;Until now, our solutions were depending on using a background image. So for every combination of border-radius, foreground color and background color, you&amp;#39;ll need a seperate image. It would be a lot easier if this was done completely automagic. You could write a back-end script, creating the images dynamically, but that would cost a lot of time.&lt;/p&gt;&lt;p&gt;Fortunately, there are cross-browser solutions that don&amp;#39;t need any images to work. In this area we find two free Javascript libraries: CurvyCorners and ShadedBorder. They work by dynamically creating hundreds of tiny divs in each corner. Together, these divs form an anti-aliased rounded corner.&lt;/p&gt;&lt;p&gt;The effect is super, and both CurvyCorners and ShadedBorder are easy to setup and configure. There&amp;#39;s a major cause for concern, however. If you want a box to have four rounded corners with a border-radius of 20 pixels and a border of 3 pixels, CurvyCorners creates 424 extra div&amp;#39;s, each with their own position, background-color and transparency. With 5 rounded boxes, that&amp;#39;s 2120 extra div&amp;#39;s. That could cause serious performance issues with page buildup, scripts and scrollspeed, especially in older browsers.&lt;/p&gt;&lt;h3&gt;The solution&lt;/h3&gt;&lt;pre&gt;$.fn.rounded_corners = function()
{
	return this.each(function()
	{
		$(this).css({position: &amp;#39;relative&amp;#39;});

		$(&amp;#39;&amp;#39;)
			.css({ // this will only accept numeric border widths
				marginTop:   &amp;#39;-&amp;#39; + (parseInt($(this).css(&amp;#39;border-top-width))   || 0),
				marginRight: &amp;#39;-&amp;#39; + (parseInt($(this).css(&amp;#39;border-right-width&amp;#39;)) || 0),
				marginBottom:&amp;#39;-&amp;#39; + (parseInt($(this).css(&amp;#39;border-bottom-width&amp;#39;))|| 0),
				marginLeft:  &amp;#39;-&amp;#39; + (parseInt($(this).css(&amp;#39;border-left-width&amp;#39;))  || 0)
			})
			.appendTo(this);

			if($.browser.msie &amp;amp;&amp;amp; $.browser.version &amp;lt; 7)
			{
				$(this).each(function()
				{   
					
				var h = $(this).height();
				var w = $(this).width();
	
				if(h%2)
				{ 
					$(&amp;#39;.cnr_sw&amp;#39;, this).css({bottom: &amp;#39;-1px&amp;#39;});
					$(&amp;#39;.cnr_se&amp;#39;, this).css({bottom: &amp;#39;-1px&amp;#39;}); 
				}
	
				if(w%2)
				{	 
					$(&amp;#39;.cnr_ne&amp;#39;, this).css({right: &amp;#39;-1px&amp;#39;});
					$(&amp;#39;.cnr_se&amp;#39;, this).css({right: &amp;#39;-1px&amp;#39;}); 
				}
			});
		}
	});
}    

if($.browser.msie)
{
	$(&amp;#39;.selector1, .selector2, #selector3&amp;#39;).rounded_corners();            
}&lt;/pre&gt;&lt;pre&gt;.cnrs {
	background: transparent url(/image/corners_white.png) no-repeat;
	border: none !important;
	overflow: hidden;
	position: absolute;
	height: 6px;
	width: 6px;
	font-size: 1px !important;
	z-index: 9999;
	right: 0;
	top: 0;
}

.cnr_ne {
	background-position: right top;
}

.cnr_nw {
	background-position: left top;
}

.cnr_sw {
	background-position: left bottom;
}

.cnr_se {
	background-position: right bottom;
}&lt;/pre&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/548</id>
			<updated>2010-05-05T22:00:26+02:00</updated>
			<published>2010-02-23T14:16:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/548/how-to-enhance-your-websites-seo" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload2985-320-320.jpeg%28400x400%29%28E76FFE680EBBE221E8AC35D3693AE9BF%29.jpg" />
			

			<title>How to enhance your websites SEO</title>
			
				<summary>There are a lot of simple things that can be done when building a website for a client that will help increase the likelihood of the website having good search engine results. In this post I will explain a couple of basic things that I think every webmaster or web developer should now about. I focus mostly on Google here because they are unique in the variety of tools that they offer to help optimize a website for their search engines, a lot of which I have personally used for some of my clients.</summary>
				<content type="html">&lt;h2&gt;Tools you can use&lt;/h2&gt;&lt;h3&gt;Create a sitemap.xml file&lt;/h3&gt;&lt;p&gt;A sitemap.xml file is a listing of the pages on your website in a format that is friendly to the search engines.  You might be more familiar with a site map that is intended for humans to use. It&amp;#39;s the same concept, but the XML format is in the language that the search engine crawlers read.&lt;/p&gt;&lt;p&gt;There are a variety of tools out there to generate site maps for your website:&lt;/p&gt;&lt;p&gt;If you have a website that is static HTML pages, then you can use the free sitemap generator at &lt;a href="http://www.xml-sitemaps.com/"&gt;XML-Sitemaps.com&lt;/a&gt; to generate one. 	If you use something like Wordpress I recommend using a great plug-in that I found called &lt;a href="http://www.arnebrachhold.de/projects/wordpress-plugins/google-xml-sitemaps-generator/"&gt;Google (XML) Sitemaps Generator for WordPress&lt;/a&gt;.  	It will generate and update a sitemap automatically for you.&lt;/p&gt;&lt;h3&gt;Create a robots.txt file&lt;/h3&gt;&lt;p&gt;A robots.txt file is a set of instructions that tells the visiting search engine crawlers what they can and can&amp;#39;t index on your website.&lt;/p&gt;&lt;p&gt;For example, you can give instructions to tell certain search engines not to crawl your website,  	or that all engines shouldn&amp;#39;t crawl a particular directory on your website.  	The most basic instructions tell all search engines that they can crawl all directories on your website.&lt;/p&gt;&lt;p&gt;When you subscribe to &lt;a href="https://www.google.com/webmasters/tools/dashboard"&gt;Google&amp;#39;s free Webmaster Tools&lt;/a&gt;,  	there is a tool that will create a robots.txt file for you. Once you create it, make sure that it goes in the root directory of your website.&lt;/p&gt;&lt;h3&gt;Submit your URL&lt;/h3&gt;&lt;p&gt;This one should be obvious, but it&amp;#39;s worth mentioning anyways.  	Submitting your URL to the search engines helps them find your website quicker - although sometimes it will still take some time after you submit it before the engines crawl your website.&lt;/p&gt;&lt;p&gt;At the bare minimum, you should submit your URL to the three major search engines.  	You can do that at these spots: &lt;a href="http://www.google.com/addurl/?continue=/addurl"&gt;submit a URL to Google&lt;/a&gt;, &lt;a href="https://siteexplorer.search.yahoo.com/mysites"&gt;to Yahoo&lt;/a&gt; or &lt;a href="http://search.live.com/docs/submit.aspx"&gt;to MSN&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;Submit your sitemap&lt;/h3&gt;&lt;p&gt;The same benefit as telling the search engines what your URL is applies to your sitemap as well it will just help them find your website and content easier.  	From personal experience, Google makes it very easy to do. There is a tool within their &lt;a href="https://www.google.com/webmasters/tools/dashboard"&gt;webmaster tools&lt;/a&gt; that lets you do that.&lt;/p&gt;&lt;h2&gt;Tips for Page SEO&lt;/h2&gt;&lt;h3&gt;Title tags&lt;/h3&gt;&lt;p&gt;A page&amp;#39;s title tag is the first thing search engines look at when determining what a particular page is about.  	Title tags are also what potential visitors see and read when they&amp;#39;re looking at a search results page.&lt;/p&gt;&lt;p&gt;Most websites include the company name in the title tag, although there is still a good deal of debate about whether the name should be at the beginning or end of the title tag.&lt;/p&gt;&lt;p&gt;The most important thing to do with your title tags is make them relevant to what the page is about. It&amp;#39;s important to include one or two keywords in it as well, but don&amp;#39;t stuff your title tag full of keywords - that will just make your website look bad, and there are limits for the number of characters that can appear.&lt;/p&gt;&lt;h3&gt;Header tags&lt;/h3&gt;&lt;p&gt;From the standpoints of usability, accessibility, and SEO, there are arguably fewer things that are more important than using your header tags properly. Not only do they visually break up your content on the page, but they also give users who are glancing through the page an idea of what is being written about.&lt;/p&gt;&lt;h3&gt;How you use header tags&lt;/h3&gt;&lt;p&gt;H1 tags are used for your main page title, to show what the page is about and H2, H3, H4, H5, H6 tags are used to break up your page copy, but also to show the search engines what the topics are on a page so that it can index your website properly.&lt;/p&gt;&lt;h3&gt;ALT and TITLE attributes&lt;/h3&gt;&lt;p&gt;These two attributes don&amp;#39;t usually play a prominent role in the average user&amp;#39;s experience with a website, but they&amp;#39;re still important and shouldn&amp;#39;t be overlooked. There are also some small SEO benefits that can be gained from using them.&lt;/p&gt;&lt;p&gt;The ALT attribute is used when coding an image onto a page; think of it as some alternate text that appears should an image not load on a page. This attribute is important from an accessibility perspective because the screen readers used by blind people won&amp;#39;t show them what the image is, but if there is some descriptive text in the ALT attribute, they will pick up on that.&lt;/p&gt;&lt;p&gt;From an SEO perspective, the ALT attribute is another opportunity to get some code onto your page that the search engines will be able to read. Making it as relevant as possible to what the page is about can help contribute to stronger search engine rankings.&lt;/p&gt;&lt;p&gt;The TITLE attribute is usually used on links, and is often one of the small touches that a great website has. You&amp;#39;ve all seen the TITLE attribute in action even if you don&amp;#39;t realize what it is; if you hover over a link and a little tool tip appears, that&amp;#39;s the TITLE attribute in action.&lt;/p&gt;&lt;p&gt;From an SEO perspective, it&amp;#39;s again all about relevance, so be sure that what you&amp;#39;re putting in the TITLE attribute relates to where the link takes someone. Doing so will also help from a usability standpoint, which is just another added bonus.&lt;/p&gt;&lt;h3&gt;Use META tags&lt;/h3&gt;&lt;p&gt;Contained within the header of every page&amp;#39;s source code are what are called META tags. They are invisible to a website&amp;#39;s visitors, but are there because search engine spiders read them.&lt;/p&gt;&lt;p&gt;The two META tags that you need to concern yourself with the most when it comes to SEO are the description and keyword tags.&lt;/p&gt;&lt;p&gt;The description tag is especially important because it is listed in your search result. It&amp;#39;s what users read when a link comes up and what makes them decide whether to click on the link or not. A well-written description should read like a sentence and should be a succinct summary of the page and what someone can find when on it. You don&amp;#39;t want to include as many keywords as possible, but be sure to write the description with a focus on the keywords that are relevant to that page.&lt;/p&gt;&lt;p&gt;The keyword tag is still worth focusing some attention on, so be sure that you include at least a few relevant keywords in there - but again, don&amp;#39;t go overboard. Back in the early days of search, people used to stuff the keyword tags with anything and everything to improve their search engine results, and as a result, many search engines now just disregard the keyword tag.&lt;/p&gt;&lt;h3&gt;Content is king!&lt;/h3&gt;&lt;p&gt;Want to know the most important aspect of SEO on a website? It&amp;#39;s the content. It always has been, and it always will be. You could use all of the tips mentioned above, but unless they are all relevant to the content on the page, then you&amp;#39;re just wasting time.&lt;/p&gt;&lt;p&gt;Yes, it&amp;#39;s true that most people will not read your content - but that doesn&amp;#39;t mean you should ignore it, because the search engine crawlers do read it and weigh it highly in their algorithms. The tricky part is that you also can&amp;#39;t write content that is entirely for the search engines, because real people need to read it and make a connection to it. There needs to be a balance between the two.&lt;/p&gt;&lt;p&gt;Here are some tips to help you write SEO-friendly content:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Focus the content around a few keywords only -- don&amp;#39;t try to include as many as possible&lt;/li&gt;&lt;li&gt;Make sure that it reads well and makes sense from a human point of view&lt;/li&gt;&lt;li&gt;Just write naturally and explain the information in terms most people will understand&lt;/li&gt;&lt;li&gt;Keep it relevant to what people would expect to read on that page&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;SEO-practitioners often forget that the search engines are not the end unto themselves - they are only a tool that real people use to help them find what they&amp;#39;re looking for. So even if they can get the search engines to think that a page is great, it&amp;#39;s only as great as its ability to either keep people on the website, or to get them to make a purchase or complete a transaction of some sorts.&lt;/p&gt;&lt;p&gt;And in an interesting twist, yet another thing that the search engines factor into their algorithms is how quickly someone leaves your website from the search engine results that brought them there. This is just further proof that SEO can be summed up in one word, which I&amp;#39;ve already used repeatedly: relevance.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/546</id>
			<updated>2010-05-21T12:35:43+02:00</updated>
			<published>2010-02-23T14:13:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/546/almost-never-add-a-reset-button-to-a-form" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/image-crop-userupload8381-320-320.jpeg%28400x400%29%28797575BF1C31279E7448BD9D37A99A20%29.jpg" />
			

			<title>(Almost) never add a reset button to a form.</title>
			
				<summary>There was a time when many, many, forms on the web had a reset button. Thankfully, reset buttons are not quite as common these days, but there are enough of them out there to cause users lots of frustration.</summary>
				<content type="html">&lt;p&gt;Read this article by Roger Johansson &lt;a href="http://www.456bereastreet.com/archive/200909/almost_never_add_a_reset_button_to_a_form/" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/544</id>
			<updated>2010-05-21T12:31:10+02:00</updated>
			<published>2010-02-23T13:58:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/544/zotonic-a-pragmatic-and-modern-cms" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2010/2/23/moderncms-1.png%28400x400%29%2802A0BB478509B124B9EA245AFA0BC1EF%29.jpg" />
			

			<title>Zotonic—A pragmatic and modern CMS.</title>
			
				<summary>We built a new content management system which will be released as open source. The CMS is loosely based on Semantic Web principles and builds upon our experience building web sites, content management systems and programming in general. We call it Zotonic.</summary>
				<content type="html">&lt;p&gt;This post is a copy from &lt;a href="http://www.whatwebwhat.com" target="_blank"&gt;Marc Worrell&lt;/a&gt;&amp;#39;s post on &lt;a href="http://whatwebwhat.com/2009/06/16/zotonic-erlang-powered-cms/" target="_blank"&gt;whatwebwhat.com&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Zotonic enables hosting very popular sites on simple hardware.&lt;/p&gt;&lt;p&gt;I will write a couple of articles highlighting aspects of Zotonic. Today I focus on the reason we built a new CMS and on performance aspects. In other articles I will highlight the general design of Zotonic, the template system, modules, screen components, form handling, and adding logic (actions) to the templates.&lt;/p&gt;&lt;h3&gt;Why?&lt;/h3&gt;&lt;p&gt;Yet another CMS?  Why?  Because the current crop of open source content management systems don’t do what we want them to do. What do we want to do?  We have a simple list of requirements:&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;Flexible and easy to learn template system;&lt;/li&gt;&lt;li&gt;Separation of logic, viewer and data store (MVC);&lt;/li&gt;&lt;li&gt;Rich data model, easy to add knowledge to the data;&lt;/li&gt;&lt;li&gt;Easy to make highly interactive web sites;&lt;/li&gt;&lt;li&gt;High performance from a single machine for simple hosting;&lt;/li&gt;&lt;li&gt;Future proof, easy to integrate with XMPP and other services;&lt;/li&gt;&lt;li&gt;Easily extensible with modules;&lt;/li&gt;&lt;li&gt;Able to handle push notifications with Comet;&lt;/li&gt;&lt;li&gt;Easy and fun to program the back end.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;The Open Source building blocks of Zotonic&lt;/h3&gt;&lt;p&gt;Zotonic would not be possible without the contributions of many open source projects:&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;Django like template engine (an adapted version of &lt;a href="http://code.google.com/p/erlydtl/"&gt;ErlyDTL&lt;/a&gt;);&lt;/li&gt;&lt;li&gt;HTTP protocol handler and abstraction with &lt;a href="http://bitbucket.org/justin/webmachine/wiki/Home"&gt;Webmachine&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;Event driven user interface based on &lt;a href="http://www.nitrogenproject.com/"&gt;Nitrogen&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;The best scalable open source database around: &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;A sweet and small CSS framework: &lt;a href="http://atatonic.timbenniks.nl/"&gt;Atatonic&lt;/a&gt;;&lt;/li&gt;&lt;li&gt;&lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; for the user interface.&lt;/li&gt;&lt;li&gt;&lt;a href="http://glozer.net/src/epgsql/"&gt;epgsql&lt;/a&gt; For connecting to the database; and&lt;/li&gt;&lt;li&gt;&lt;a href="http://github.com/archaelus/esmtp/tree/master"&gt;esmtp&lt;/a&gt; For sending e-mail.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Zotonic is written in the programming language &lt;a href="http://erlang.org"&gt;Erlang&lt;/a&gt;.  In the next section I explain why we use this programming language.&lt;/p&gt;&lt;h3&gt;What is a web site anyway?  Or why we choose Erlang&lt;/h3&gt;&lt;p&gt;Once upon a time a website was a collection of manually edited HTML pages and some images.  All was fine.&lt;/p&gt;&lt;p&gt;Then search was added to the site, necessitating extra programs running on the server on behalf of a web site visitor.&lt;/p&gt;&lt;p&gt;Then those pages started to be filled with content from a database, nothing changed much except that editing and searching got a lot easier.&lt;/p&gt;&lt;p&gt;And then we started to let the visitor react, interact and upload information to the server.  Not only the visitor was allowed to interact, also machines got their own interface to talk to the server.  Web 2.0 with APIs and user generated content took off.&lt;/p&gt;&lt;p&gt;Nowadays a web site is talking in many different ways to humans and machines.  It is collecting information from multiple sources and actively submitting new articles to other sites or machines.  The web server gives the visitor more and more ways to access the stored information. People are using RSS readers, widgets, desktop applications, other web sites and so on.&lt;/p&gt;&lt;p&gt;The web server evolved from a simple machine serving some pages to a complex switchboard connected to many different servers and services.  The web server constantly sifts through information and storing it on behalf of its users.  It constantly generates different representations of its own stored information, let is be as HTML pages, RDF documents, Atom entries, XMPP messages or API result sets.&lt;/p&gt;&lt;p&gt;This new web server is an &lt;em&gt;always on&lt;/em&gt; machine.  Not a simple server reacting to requests from a web browser.&lt;/p&gt;&lt;p&gt;This new web server is way more dynamic than yesterdays database based HTML generator.  It needs to stay connected with other servers, it needs to have all those connections open and active at all times.  It even needs to &lt;em&gt;push&lt;/em&gt; information to the web browsers of visitors.&lt;/p&gt;&lt;p&gt;This new web server needs a different approach and programming model which becomes more and more like a information switchboard with thousands of open connections to other machines and web browsers.&lt;/p&gt;&lt;p&gt;Erlang was created to program telephone switches.  Its programming model and features are a natural match to this new kind of web/information server.  Besides its natural match to the problem domain it was also created to make very robust systems that are &lt;em&gt;always on&lt;/em&gt;.  No need to reboot an Erlang system for a program update.&lt;/p&gt;&lt;p&gt;That is why we choose Erlang.  To create a robust web server that can be like a spider in the web of information.  And one that is still easy to program and extend.&lt;/p&gt;&lt;h3&gt;Performance: Scale up?  Scale out?  Scale in!&lt;/h3&gt;&lt;p&gt;The current generation of computers are so fast that we can play multi user video games on a single machine, whilst surfing the web, checking our mail and what not.  Why should we be happy with generating a couple of web pages per second from a machine that is so capable?  How green is that?&lt;/p&gt;&lt;p&gt;We have quite a lot of experience building content management systems and web sites in general.  What did we learn?  For one thing: when you want high performance &lt;em&gt;and&lt;/em&gt; flexibility &lt;em&gt;and&lt;/em&gt; less machines, then you are in a lot of trouble.&lt;/p&gt;&lt;h4&gt;Usage scenario&lt;/h4&gt;&lt;p&gt;Our usage scenario is:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A fairly popular web site experiencing periodic surges of visitors;&lt;/li&gt;&lt;li&gt;The web site uses modern technologies like Ajax and Comet; and &lt;/li&gt;&lt;li&gt;Multiple web sites on a single server.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So we are &lt;em&gt;not&lt;/em&gt; targeting the new Flickr or similar sites.  They need custom built software, not an off the shelf CMS.  We &lt;em&gt;are&lt;/em&gt; targeting the other 99 or so percent of the web sites.&lt;/p&gt;&lt;h4&gt;PHP&lt;/h4&gt;&lt;p&gt;PHP is the most popular language for building web sites.&lt;/p&gt;&lt;p&gt;For every request PHP wakes up and starts finding out where he is, where the code is, what the code is, where the database is, etc. etc.  It does this again, and again, and again.  Even when nothing is changed.  This &lt;em&gt;share nothing&lt;/em&gt; approach is nice when handling a single request, or when scaling out (adding more machines).  It is not nice when you want to handle lots of requests from a single machine.&lt;/p&gt;&lt;h4&gt;Ruby on Rails and Django&lt;/h4&gt;&lt;p&gt;Other scaling problems arise with Python (Django) and Ruby (on Rails).  Typically they are single threaded, that is they use only one thread of those 32 or more hardware threads that are available on modern hardware. That is solved by having more independent processes, each handling requests one by one.  Those processes need to communicate with each other, adding more processes and complexity for caching systems etc.&lt;/p&gt;&lt;h4&gt;Zotonic&lt;/h4&gt;&lt;p&gt;Thanks to Erlang, Zotonic is completely multi threaded and scales linearly when adding more cores.  All information about the web site is kept in memory and easily shared between requests.  When two requests need the same html fragment then that fragment can be only rendered once.  Note that this is not caching, which Zotonic handles as well, but a simple prevention for doing the same thing twice at the same time.&lt;/p&gt;&lt;p&gt;Zotonic typically serves 100 to 500 dynamic pages per second on normal of the shelf hardware.  Which is enough for the fast majority of web sites.&lt;/p&gt;&lt;p&gt;Zotonic can serve a complete page before a Joomla/Drupal/WordPress site has even loaded its PHP code.  With a Zotonic server you can serve either many more sites, or many more visitors per site.&lt;/p&gt;&lt;p&gt;Later more about the architecture of Zotonic and how to use Zotonic.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
		
	
		<entry xmlns:gd="http://schemas.google.com/g/2005" xml:lang="en">
			<id>http://www.timbenniks.nl/id/524</id>
			<updated>2010-09-02T16:15:22+02:00</updated>
			<published>2009-11-19T08:42:00+01:00</published>
			<author>
				
				<name>Tim Benniks</name>
				<uri>http://www.timbenniks.nl/id/523</uri>
				
			</author>
			
			<link rel="alternate" type="text/html" href="http://www.timbenniks.nl/blog/524/zotonic-a-quick-overview" />
			
			
			
			
				<link rel="enclosure" type="image/jpeg" href="http://www.timbenniks.nl/image/2009/11/25/image-crop-userupload6591-320-320.jpg%28400x400%29%281F779501715AA0380D4AA39613E33C12%29.jpg" />
			

			<title>Zotonic, a quick overview.</title>
			
				<summary>In an earlier post I wrote about the reasons why we started building the content management system Zotonic using the programming language Erlang. In this installment I will give a quick overview of the data model and the basic building blocks of Zotonic.</summary>
				<content type="html">&lt;p&gt;This post is a copy from &lt;a href="http://www.whatwebwhat.com" target="_blank"&gt;Marc Worrell&lt;/a&gt;&amp;#39;s post on &lt;a href="http://whatwebwhat.com/2009/07/01/zotonic-a-quick-overview/" target="_blank"&gt;whatwebwhat.com&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Modules, the basic building block&lt;/p&gt;&lt;p&gt;A Zotonic web site is made of different functional parts:&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;Controllers, in fact Webmachine resources.&lt;/li&gt;&lt;li&gt;Templates, all what you see. Templates can include other templates.&lt;/li&gt;&lt;li&gt;Screen components, &lt;em&gt;scomps&lt;/em&gt;, those are templates with their own little controller.&lt;/li&gt;&lt;li&gt;Actions, everything that you can do with buttons, forms, jQuery effects etc.&lt;/li&gt;&lt;li&gt;Validators, used to check submitted input elements.&lt;/li&gt;&lt;li&gt;Css, Javascript, static images.  Those are all put in &lt;em&gt;lib&lt;/em&gt; directories.&lt;/li&gt;&lt;li&gt;Dispatch rules. They map a request url to the correct controller.&lt;/li&gt;&lt;li&gt;And a bunch of supporting Erlang code to make it all work.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A module contains one or more of the above items.  All templates, actions, validations, css, javascript, dispatch rules and scomps are contained in modules.  Modules have a priority and can overrule components of modules with lower priority.&lt;/p&gt;&lt;p&gt;Modules are directories with at least one Erlang module implementing a &lt;em&gt;gen_server&lt;/em&gt; that manages the module.  Subdirectories in the module contain all the templates, Webmachine resources, dispatch rules, actions etc.&lt;/p&gt;&lt;p&gt;Modules communicate with each other using notifications.  Modules can be activated or deactivated using the admin interface (which is implemented using multiple modules).&lt;/p&gt;&lt;h3&gt;Data Model&lt;/h3&gt;&lt;p&gt;The data model is inspired by semantic web triple stores. But then adapted to make it work with a relational database and usual CMS interfaces and methods.&lt;/p&gt;&lt;p&gt;All (ok, most) data in Zotonic is a resource.  Resources are connected with edges, creating a directed graph of information.  Every edge has also a predicate.  The predicate defines the meaning of the edge.  For example &lt;em&gt;author&lt;/em&gt;, as in the author of an article.&lt;/p&gt;&lt;p&gt;For example, a news article is a resource.  The image of the news article is another resource, connected to the article with an edge, and so is the author of the article, the place the article is happening etc.&lt;/p&gt;&lt;p&gt;You could say that Zotonic has only two tables.  A resource table and an edge table.&lt;/p&gt;&lt;p&gt;Resources are typed using a hierarchical category system.  Some predefined resource categories are: text, news, image, video, sound, person, group, predicate, category and other.&lt;/p&gt;&lt;h4&gt;A Data Resource&lt;/h4&gt;&lt;p&gt;A resource has some fixed fields and can have any additional fields.  The fixed fields are:&lt;/p&gt;&lt;ul class="bullet-list"&gt;&lt;li&gt;Id, an unique integer.&lt;/li&gt;&lt;li&gt;Title.&lt;/li&gt;&lt;li&gt;Slug. Used to make understandable uris&lt;/li&gt;&lt;li&gt;Introduction, a short abstract used in lists.&lt;/li&gt;&lt;li&gt;Body, the textual body of a resource.  A body contains HTML.&lt;/li&gt;&lt;li&gt;Unique name, used by the system to find resources by name instead of id.&lt;/li&gt;&lt;li&gt;Featured flag, to show things at important places on your site.&lt;/li&gt;&lt;li&gt;Published flag.&lt;/li&gt;&lt;li&gt;Publication period.  From when till when a resource is published.&lt;/li&gt;&lt;li&gt;Uri. The originating uri of the resource when it is imported from another site.&lt;/li&gt;&lt;li&gt;Authoritative flag.  Defines if the resource is imported or created locally.&lt;/li&gt;&lt;li&gt;Category, defines what the resource represents.  For example a person, article, event, image or video.&lt;/li&gt;&lt;li&gt;Group. Editors work together in groups, all content belonging to a group can be edited by editors in that group.&lt;/li&gt;&lt;li&gt;Visibility level.  Defines if the resource is viewable by the group, community or the world.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All textual fields (except name and uri) can be multilingual.  Any resource can have multiple extra data fields.  Think of a date range, name or address.&lt;/p&gt;&lt;p&gt;In the next article I will show a bit of a template.&lt;/p&gt;</content>
			
			
			
			
				
			<category term="blog" scheme="http://zotonic.com/id/category" />
		</entry>
	


	
	
</feed>

