Programming a mobile app for different platforms can be now much easier with Apache Cordova. The reason is simple. Cordova is an open-source mobile development framework for developing mobile apps in more than one platform. This avoids you programming in each platform native language using technologies such as JavaScript, HMTL5 and CSS3.

System setup

We will use Linux operating system to deploy our app in a Android device. We need to download and install Eclipse, the ADT plugin and the Android SDK tools. To do that the best option is install the ADT Bundle. After that we can unzip the downloaded file and launch eclipse.

You also have to set up the following environment variables in your .bashrc file in Linux. Make sure include the necessary ones in your PATH environment variable.

We also will use Mac operating system to deploy our app in a real iOS device. We have to download and install Xcode tool in this case and launch it.

Installing Cordova Apache

First download Node.js for installing cordova utility later in the operating system you like the most.

sudo npm install -g cordova

Creating the app

Type the following command which will generate a example directory for your project. You also can include a second argument for set a domain and a third argument for name the application’s display text. These two arguments can be edited later in the config.xml file.

cordova create example

Adding the desire platforms

The next step is run the following commands to add an android platform and an ios platform under each operating system. And this is important because Linux doesn’t support iOS platform. After that, run the build command and you will get your specific code for each one.

cd example

cordova platform add android

cordova build android

cordova platform add ios

cordova build ios

We can now open our Android code from Eclipse through File/New Project/Android Project from Existing Code and our iOS code through Open menu.

Developing your app

The important issue here is that unless you want to write specific code for each operating system you can develop your app only modifying the main code. So every time you change the main code in example/www directory you only have to rebuild the app under each platform. And this is a really easy way to develop a app for different platforms.

Twitter is a wonderful service, but, until now, you have to subscribe to some websites to be alerted when a selected word (maybe your trademark) is tweeted. We’ll try to develop a service that filters the tweeter api, stores the interesting ones in our database, and show them in the browser in real time.

What?

We’ll take twitter real time results for a given word (or words) and visualize them in a browser window, like monitter.com, but on our own servers and a bit more automatic. This is going to be useful to get our own alerts and work with them.

How?

We are going to use the twitter stream API to get the comments containing a given word. Since the results are given in Json format, we’ll need to filter the data, take the interesting bits and store them. From the other side, we’re going to write a bit of javascript to read the data from the server into a web page using ajax. We could use other technologies, like comet, to push the data to the browser, but, while it would be a much cleaner implementation, I think I’m not ready to write about that yet (check this space ;)). We need to decouple the reading of the stream from twitter and the serving to our clients because we can only have a single active instance of the twitter streaming api at a given time, and we’re going to leave the listening proccess on for a long time using a daemon/service approach. On top of that, we want to store the tweets in a database for later perusal and data mining.

The tools

We are trying to make a useful system. To do this, we’ll need some tools:

Server side programming language: This time, PHP. While probably not as elegant or fast as Python or as cool as Ruby, gets the work done and it’s available in almost all web hosting plans. And the documentation is pretty extensive.

A database to store all the info

Client side programming: We are going to use HTML, javascript and the jQuery javascript library to simplify AJA(X) programming and for the effects.

A twitter acount: Yours own is OK but maybe you want to create a new one for this kind of tasks. Write down your user and password, we are going to need them soon.

The twitter API. Twitter people are so kind they have developed a restful API free for everyone to use. And it’s sub-zero cool.

The Twitter streaming API

Twitter has published a Streaming API that’s described as “The Twitter Streaming API allows near-realtime access to various subsets of Twitter public statuses”. In fact, this is jus what we need. You can read all the documentation at https://twitterapi.pbworks.com/Streaming-API-Documentation, but I’ll try to take the interesting parts for this project so you don’t need to yet.

We are going to use just one method (status/filter) to get results including one or several words. This method can return a stream of data in xml or json formats, has to be called using POST and can get some parameters. You can use it from the command line if you have access to some kind of unix in the following way:

Until you exit it (with CTRL+C) . This is a Json stream and can be read and parsed by several means. In fact, it’s eval-uable javascript code that we could read from the browser. But right now, we’re going to use a server-side language to read it and work with the interesting parts.

Reading Twitter stream

As I told you in the tools section, we are going to use PHP as our server side language. For the first part, the reading of the twitter stream, we don’t even need a web server, since we can run it from the command line. And if we run it from the command line, we can convert it to a kind of daemon/service and leave it on for a long time. But first, some code:

We create an $opts array (in fact an array of arrays) that contain the parameters. In this particular case, we’re using two, the POST method and the search line (track=google). Then, we can treat the twitter stream as a file, using stream_context_create and fopen and just start reading lines. Each line is going to be a JSON encoded tweet, similar to what we’ve seen when we called the API from command line. Since we want to use the contents as easily as possible, we’ll need the json_decode function to parse it into PHP objects, print them and call flush just in case we’re calling the script from a browser.

Storing the results

The best way to store the results for later perusal is a database. I’m using MySQL but any other database should be OK. To be able to store the data, we need to create a database with a single table.

We are only going to store the following data:

Text: This is the twetter status. 140 chars max.

User screen name: The screen name of the poster. This is needed to create the link to twitter

Id: A unique id for the tweet. It’s a sequential number, so, we can order the tweets acording to this, and use it along with the user screen name to built a link back to twitter, and use it as our primary key.

Followers count: The number of people that are going to receive the tweet in their inboxes. We are using it to style the real-time viewer. Since my primal intention is to watch a trademark, I care about the number of people that are watching the messages.

The time of the tweet: basically for filtering purposes. We are going to store our server time to avoid lengthy conversions.

We could store several other fields, and a complete solution should probably take into account that you can have some different tweet types, but for the time, these four fields should suffice.

To create the table, we can run the following SQL script from the server:

It’s as ugly as sin but it works. If you run it from the command line, it should start storing tweets in your database and keep on until you stop it. So, our database is starting to fill with tweets concerning our desired word. Now we need to be able to navigate them…

Creating the code from the server side

Now we need to publish the tweets in our browser. To do that, we need a small PHP script that returns the tweets when called. If we call it with a parameter start it’ll return all the tweets with an id bigger than that. Otherwise, it’ll return the last ten tweets stored in our database. To do that, we will use two different queries, the first one to return the last ten results, and the second one to return all results since the given id. We use subqueries (SELECT from SELECT) to get the results in our wished order.

We are going to poll this code every ten seconds and refresh the tweets list to show the most recent ones, using javascript, and the output format will be JSON.

Writing a front-end

Since, as Larry Wall said, one of the cardinal virtues of a programmer is lazyness, we are going to use jQuery to construct the interface and the business logic. And we’re not even serving it, but linking from the Google CDN, as Dave Ward posted in his wondeful blog.

Let’s see… This is probably the most complex part of the article, so, I’ll try to go slow and explain every function:

getTweets(id)

This function calls the server using the getJSON jQuery method. Then, it takes each response line and calls addNew with it. If we call it with an id parameter, it’ll ask the server for all tweets with ids greater than that. Otherwise, it will grab the last ten tweets.

addNew(item)

It takes an item (a tweet) as input. It hides the first tweet, remove it’s ‘tweet’ class, appends a new tweet at the bottom and shows it. It calls the renderTweet function to get the tweet in HTML format.

renderTweet(item)

Just one line to call getImportanceColor() and a return with the HTML code. It’s a bit long but that’s because we’re adding a couple of links to the tweet to be able to visit the original one.

getImportanceColor(number)

It takes a number of followers and returns a rgb color that will be between total black, for people without followers, and total red, for Ashton Kutchner. It uses logarithms to scale between the two extremes, because there are 6 orders of magnitude between the extremes. We will use it to paint (it) black the twitters with few followers and red the twitter stars.

poll()

This is the timeout function that calls itself every 200ms and gets the new tweets.

The last block just starts the polling as soon as the document is loaded.

The Result

This is a small screen capture of my browser visiting the HTML/javascript page while running storing_tweets_in_the_database.php. It’s watching the word ‘twitter’ and, as you can see, it’s running too fast for the human eye -at least mine -, but since we are keeping all the data in our database, it’s not lost forever

Limits

Right now, because of the Twitter API limits, just one instance of the watching process can be run at once. Anyhow, you can write several words, separated by commas, and Twitter will return results for all of them.This code should not be used in production, since there are almost no security checks to avoid missuse. If you want to use it in a machine open to the public, you should check -twice- every input for missbehaviour.

Further work

Obviously, this is just a sample. It can be made much better looking, and we could even analyze the tweets and tweet back a response to any questions concerning our keywords. The watch module should be daemonized or converted to a service to be left unatended. The HTML page could be able to filter between two dates and so on. Keep on watching. We’ll try to keep on posting this kind of contents.

Shameless plug

I’m part of Corunet, a web agency in Spain, that can deliver consistent good results in all kind of internet projects. You can visit our website http://coru.net/ or contact me at david@corunet.com if you have any special needs

]]>http://blog.corunet.com/twitter-alerts-using-twitter-streaming-api/feed/36Automatic CSS: The stylizatorhttp://blog.corunet.com/automatic-css-the-stylizator/
http://blog.corunet.com/automatic-css-the-stylizator/#commentsWed, 20 Jun 2007 20:15:15 +0000http://blog.corunet.com/english/automatic-css-the-stylizatorWriting CSS is good fun, but analyzing an html document to find how the page is structured us, at the very least, tiring. If you have ever had to write CSS for a blog or CMS template, you already know how time-consuming is to find every ID and CLASS in a large document. We’re going to write a simple script that takes an HTML file as input and gives us two things:

First, some CSS and Javascript to generate a visual structure with all the names like the one that can be seen at the top image (and a javascript only version!!).

Second, a CSS file without any rules, but with every ID and class in the document.

Let’s go:

The tools

We need to use any scripting language to read the HTML and act accordingly. This time we’re going to use perl, since it’s a simple and powerful language for text managing. It’s available in most operating systems and for windows users, it’s downloadable from http://activestate.com/ .

It should be possible to write in ruby, python, java or any other programming language. Take it as a guideline or, if you just want to use it, grab the code
We’re going to use some CSS and Javascript too. Let’s get wet…

Reading and parsing HTML

First of all, we need an HTML document to be parsed. As I’ll recall later, I used HTML code from csszengarden to try the code.
First thing to do is read the html from a file. The script we’re going starts the following way:

This first part opens a file, reads it and assign the contents to a variable. Now, we need to find all the id’s present in the file. To do that we could use a full-fledged HTML parser, but since many documents in the real world are not correct and our necessities are quite easy, there’s a simpler solution. So, regular expressions to the rescue.
Regular expressions find patterns in a file. We can tell perl to find things like /\w+/ and it will match alphanumeric characters. Probably to find named elements it should be enough to write:

/id=\"?\w+\"?/i

Where “id=” means exactly that, \”? means a possible quotation mark, (\w+) is a group of letters or numbers, another possible quote and the last “i” tells us to ignore the case of the text. In this particular case, we’re going to use a slightly more complicated expression, to take into acount possible missing quotes and so on:

/id\s*=\s*"?([^"\s>]+)/

Creating the CSS template

We’re going to write an empty CSS file. I like to use a previously written template that includes links to my CSS-reset file and some more files I always use. Then, for every named element, we need a line:

With all that code, we already have a CSS template. You could start right now editing it to suit your needs. But we don’t know yet what the structure is. Why don’t we create a new HTML file that shows us how the document is laid? OK. Let’s write some more code

Javascript: The magic

Here is where the fun begins. Probably, I’ll need to wite another post about this piece of code, since there are a couple of sleights of hand, but, briefly, the following piece of code removes all the stylesheets and the inline CSS rules, then takes all the elements in the dom and finds the ones that have an ID, and adds a P element with the ID name to each one.

As you can see, there are only two functions. The first one, removeSheets(), disables every stylesheet included from the HTML, and then calls the other one, findNamedElements(), This function gets all the elements in the DOM (getElementsByTagName(‘*’)) and iterates over them, doing a couple of things:

For the elements with an ID, some styles are added (a silver box around them)

A child P tag with the ID text is created too, giving it a class ‘sign’

Then, we create a new stylesheet only for that class. We have to code a different way for Explorer and Firefox/Opera/Others because of compatibility issues.
Last, the function is called with removesheets(). You can even save the code as a bookmarklet and apply it to any website. It’s truly portable.

Now we need some perl code to insert the javascript into the HTML file, just before the </body>: tag.Update: My pal Félix has just tol me that I need to add an “s” in the javascript substitution, to cope with multi-line javascript. Thanks, Félix

$html=~s/<script.*?<\/script>//sg;
open (JS,"stylizator.js") || die("You also need the file stylizator.js in the same folder");
my @js=<JS>;
close (JS);
my $js='<script type="text/javascript">'.join("",@js).'</script></body>';
$html=~s/<\/body>/$js/e;
print HTML $html;
close (CSS);
close (HTML);

When you run the full script, another HTML file will be generated, that shows how the document is laid.

Trying it out

The best example I can think of is CSSzengarden, a site where a default layout is given to designers to skin it the better they can. I downloaded the HTML code (CC license, by-nc-sa) and called he script over it:

$> perl stylizator.pl csszengarden.html

And I got a csszengarden CSS file, with all the named tags, and a csszengarden.structure.html file with the visual structure of the site.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta name="author" content="Dave Shea" />
<meta name="keywords" content="design, css, cascading, style, sheets, xhtml, graphic design, w3c, web standards, visual, display" />
<meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design." />
<meta name="robots" content="all" />
<title>css Zen Garden: The Beauty in CSS Design</title>
<!-- to correct the unsightly Flash of Unstyled Content. http://www.bluerobot.com/web/css/fouc.asp -->
<script type="text/javascript"></script>
<style type="text/css" title="currentStyle" media="screen">
@import "/001/001.css";
</style>
<link rel="Shortcut Icon" type="image/x-icon" href="http://www.csszengarden.com/favicon.ico" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.csszengarden.com/zengarden.xml" />
</head>
<!--
This xhtml document is marked up to provide the designer with the maximum possible flexibility.
There are more classes and extraneous tags than needed, and in a real world situation, it's more
likely that it would be much leaner.
However, I think we can all agree that even given that, we're still better off than if this had been
built with tables.
-->
<body id="css-zen-garden">
<div id="container">
<div id="intro">
<div id="pageHeader">
<h1><span>css Zen Garden</span></h1>
<h2><span>The Beauty of <acronym title="Cascading Style Sheets">CSS</acronym> Design</span></h2>
</div>
<div id="quickSummary">
<p class="p1"><span>A demonstration of what can be accomplished visually through <acronym title="Cascading Style Sheets">CSS</acronym>-based design. Select any style sheet from the list to load it into this page.</span></p>
<p class="p2"><span>Download the sample <a href="/zengarden-sample.html" title="This page's source HTML code, not to be modified.">html file</a> and <a href="/zengarden-sample.css" title="This page's sample CSS, the file you may modify.">css file</a></span></p>
</div>
<div id="preamble">
<h3><span>The Road to Enlightenment</span></h3>
<p class="p1"><span>Littering a dark and dreary road lay the past relics of browser-specific tags, incompatible <acronym title="Document Object Model">DOM</acronym>s, and broken <acronym title="Cascading Style Sheets">CSS</acronym> support.</span></p>
<p class="p2"><span>Today, we must clear the mind of past practices. Web enlightenment has been achieved thanks to the tireless efforts of folk like the <acronym title="World Wide Web Consortium">W3C</acronym>, <acronym title="Web Standards Project">WaSP</acronym> and the major browser creators.</span></p>
<p class="p3"><span>The css Zen Garden invites you to relax and meditate on the important lessons of the masters. Begin to see with clarity. Learn to use the (yet to be) time-honored techniques in new and invigorating fashion. Become one with the web.</span></p>
</div>
</div>
<div id="supportingText">
<div id="explanation">
<h3><span>So What is This About?</span></h3>
<p class="p1"><span>There is clearly a need for <acronym title="Cascading Style Sheets">CSS</acronym> to be taken seriously by graphic artists. The Zen Garden aims to excite, inspire, and encourage participation. To begin, view some of the existing designs in the list. Clicking on any one will load the style sheet into this very page. The code remains the same, the only thing that has changed is the external .css file. Yes, really.</span></p>
<p class="p2"><span><acronym title="Cascading Style Sheets">CSS</acronym> allows complete and total control over the style of a hypertext document. The only way this can be illustrated in a way that gets people excited is by demonstrating what it can truly be, once the reins are placed in the hands of those able to create beauty from structure. To date, most examples of neat tricks and hacks have been demonstrated by structurists and coders. Designers have yet to make their mark. This needs to change.</span></p>
</div>
<div id="participation">
<h3><span>Participation</span></h3>
<p class="p1"><span>Graphic artists only please. You are modifying this page, so strong <acronym title="Cascading Style Sheets">CSS</acronym> skills are necessary, but the example files are commented well enough that even <acronym title="Cascading Style Sheets">CSS</acronym> novices can use them as starting points. Please see the <a href="http://www.mezzoblue.com/zengarden/resources/" title="A listing of CSS-related resources"><acronym title="Cascading Style Sheets">CSS</acronym> Resource Guide</a> for advanced tutorials and tips on working with <acronym title="Cascading Style Sheets">CSS</acronym>.</span></p>
<p class="p2"><span>You may modify the style sheet in any way you wish, but not the <acronym title="HyperText Markup Language">HTML</acronym>. This may seem daunting at first if you&#8217;ve never worked this way before, but follow the listed links to learn more, and use the sample files as a guide.</span></p>
<p class="p3"><span>Download the sample <a href="/zengarden-sample.html" title="This page's source HTML code, not to be modified.">html file</a> and <a href="/zengarden-sample.css" title="This page's sample CSS, the file you may modify.">css file</a> to work on a copy locally. Once you have completed your masterpiece (and please, don&#8217;t submit half-finished work) upload your .css file to a web server under your control. <a href="http://www.mezzoblue.com/zengarden/submit/" title="Use the contact form to send us your CSS file">Send us a link</a> to the file and if we choose to use it, we will spider the associated images. Final submissions will be placed on our server.</span></p>
</div>
<div id="benefits">
<h3><span>Benefits</span></h3>
<p class="p1"><span>Why participate? For recognition, inspiration, and a resource we can all refer to when making the case for <acronym title="Cascading Style Sheets">CSS</acronym>-based design. This is sorely needed, even today. More and more major sites are taking the leap, but not enough have. One day this gallery will be a historical curiosity; that day is not today.</span></p>
</div>
<div id="requirements">
<h3><span>Requirements</span></h3>
<p class="p1"><span>We would like to see as much <acronym title="Cascading Style Sheets, version 1">CSS1</acronym> as possible. <acronym title="Cascading Style Sheets, version 2">CSS2</acronym> should be limited to widely-supported elements only. The css Zen Garden is about functional, practical <acronym title="Cascading Style Sheets">CSS</acronym> and not the latest bleeding-edge tricks viewable by 2% of the browsing public. The only real requirement we have is that your <acronym title="Cascading Style Sheets">CSS</acronym> validates.</span></p>
<p class="p2"><span>Unfortunately, designing this way highlights the flaws in the various implementations of <acronym title="Cascading Style Sheets">CSS</acronym>. Different browsers display differently, even completely valid <acronym title="Cascading Style Sheets">CSS</acronym> at times, and this becomes maddening when a fix for one leads to breakage in another. View the <a href="http://www.mezzoblue.com/zengarden/resources/" title="A listing of CSS-related resources">Resources</a> page for information on some of the fixes available. Full browser compliance is still sometimes a pipe dream, and we do not expect you to come up with pixel-perfect code across every platform. But do test in as many as you can. If your design doesn&#8217;t work in at least IE5+/Win and Mozilla (run by over 90% of the population), chances are we won&#8217;t accept it.</span></p>
<p class="p3"><span>We ask that you submit original artwork. Please respect copyright laws. Please keep objectionable material to a minimum; tasteful nudity is acceptable, outright pornography will be rejected.</span></p>
<p class="p4"><span>This is a learning exercise as well as a demonstration. You retain full copyright on your graphics (with limited exceptions, see <a href="http://www.mezzoblue.com/zengarden/submit/guidelines/">submission guidelines</a>), but we ask you release your <acronym title="Cascading Style Sheets">CSS</acronym> under a Creative Commons license identical to the <a href="http://creativecommons.org/licenses/by-nc-sa/1.0/" title="View the Zen Garden's license information.">one on this site</a> so that others may learn from your work.</span></p>
<p class="p5"><span>Bandwidth graciously donated by <a href="http://www.dreamfirestudios.com/">DreamFire Studios</a>. Now available: <a href="http://www.amazon.com/exec/obidos/ASIN/0321303474/mezzoblue-20/">Zen Garden, the book</a>.</span>&nbsp;</p>
</div>
<div id="footer">
<a href="http://validator.w3.org/check/referer" title="Check the validity of this site&#8217;s XHTML">xhtml</a> &nbsp;
<a href="http://jigsaw.w3.org/css-validator/check/referer" title="Check the validity of this site&#8217;s CSS">css</a> &nbsp;
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/" title="View details of the license of this site, courtesy of Creative Commons.">cc</a> &nbsp;
<a href="http://www.contentquality.com/mynewtester/cynthia.exe?Url1=http:%2F%2Fcsszengarden.com%2F" title="Check the accessibility of this site according to U.S. Section 508">508</a> &nbsp;
<a href="http://mezzoblue.com/zengarden/faq/#aaa" title="Check the accessibility of this site according to Web Content Accessibility Guidelines 1.0">aaa</a>
</div>
</div>
<div id="linkList">
<div id="linkList2">
<div id="lselect">
<h3 class="select"><span>Select a Design:</span></h3>
<ul>
<li><a href="?cssfile=/202/202.css&amp;page=0" title="AccessKey: a" accesskey="a">Retro Theater</a> by <a href="http://space-sheeps.info/" class="c">Eric Rog&eacute;</a></li>
<li><a href="?cssfile=/201/201.css&amp;page=0" title="AccessKey: b" accesskey="b">Lily Pond</a> by <a href="http://www.tulips4rose.com" class="c">Rose Thorogood</a></li>
<li><a href="?cssfile=/200/200.css&amp;page=0" title="AccessKey: c" accesskey="c">Icicle Outback</a> by <a href="http://www.timovirtanen.com/" class="c">Timo Virtanen</a></li>
<li><a href="?cssfile=/199/199.css&amp;page=0" title="AccessKey: d" accesskey="d">Zen Army</a> by <a href="http://www.niceguy.com/" class="c">Carl Desmond</a></li>
<li><a href="?cssfile=/198/198.css&amp;page=0" title="AccessKey: e" accesskey="e">The Original</a> by <a href="http://www.bluejam.com/" class="c">Joachim Shotter</a></li>
<li><a href="?cssfile=/197/197.css&amp;page=0" title="AccessKey: f" accesskey="f">Floral Touch</a> by <a href="http://www.jahmasta.com/" class="c">Jadas Jimmy</a></li>
<li><a href="?cssfile=/196/196.css&amp;page=0" title="AccessKey: g" accesskey="g">Elegance in Simplicity</a> by <a href="http://www.manisheriar.com/blog/" class="c">Mani Sheriar</a></li>
<li><a href="?cssfile=/195/195.css&amp;page=0" title="AccessKey: h" accesskey="h">Dazzling Beauty</a> by <a href="http://blog.denysri.com/" class="c">Deny Sri Supriyono</a></li>
</ul>
</div>
<div id="larchives">
<h3 class="archives"><span>Archives:</span></h3>
<ul>
<li><a href="/?cssfile=/001/001.css&amp;page=1" title="View next set of designs. AccessKey: n" accesskey="n"><span class="accesskey">n</span>ext designs &raquo;</a></li>
<li><a href="http://www.mezzoblue.com/zengarden/alldesigns/" title="View every submission to the Zen Garden. AccessKey: w" accesskey="w">Vie<span class="accesskey">w</span> All Designs</a></li>
</ul>
</div>
<div id="lresources">
<h3 class="resources"><span>Resources:</span></h3>
<ul>
<li><a href="/001/001.css" title="View the source CSS file for the currently-viewed design, AccessKey: v" accesskey="v"><span class="accesskey">V</span>iew This Design&#8217;s <acronym title="Cascading Style Sheets">CSS</acronym></a></li> <li><a href="http://www.mezzoblue.com/zengarden/resources/" title="Links to great sites with information on using CSS. AccessKey: r" accesskey="r"><acronym title="Cascading Style Sheets">CSS</acronym> <span class="accesskey">R</span>esources</a></li>
<li><a href="http://www.mezzoblue.com/zengarden/faq/" title="A list of Frequently Asked Questions about the Zen Garden. AccessKey: q" accesskey="q"><acronym title="Frequently Asked Questions">FA<span class="accesskey">Q</span></acronym></a></li>
<li><a href="http://www.mezzoblue.com/zengarden/submit/" title="Send in your own CSS file. AccessKey: s" accesskey="s"><span class="accesskey">S</span>ubmit a Design</a></li>
<li><a href="http://www.mezzoblue.com/zengarden/translations/" title="View translated versions of this page. AccessKey: t" accesskey="t"><span class="accesskey">T</span>ranslations</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- These extra divs/spans may be used as catch-alls to add extra imagery. -->
<div id="extraDiv1"><span></span></div><div id="extraDiv2"><span></span></div><div id="extraDiv3"><span></span></div>
XXXX
</body>
</html>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<meta name="author" content="Dave Shea" />
<meta name="keywords" content="design, css, cascading, style, sheets, xhtml, graphic design, w3c, web standards, visual, display" />
<meta name="description" content="A demonstration of what can be accomplished visually through CSS-based design." />
<meta name="robots" content="all" />
<title>css Zen Garden: The Beauty in CSS Design</title>
<!-- to correct the unsightly Flash of Unstyled Content. http://www.bluerobot.com/web/css/fouc.asp -->
<style type="text/css" title="currentStyle" media="screen">
@import "/001/001.css";
</style>
<link rel="Shortcut Icon" type="image/x-icon" href="http://www.csszengarden.com/favicon.ico" />
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.csszengarden.com/zengarden.xml" />
</head>
<!--
This xhtml document is marked up to provide the designer with the maximum possible flexibility.
There are more classes and extraneous tags than needed, and in a real world situation, it's more
likely that it would be much leaner.
However, I think we can all agree that even given that, we're still better off than if this had been
built with tables.
-->
<body id="css-zen-garden">
<div id="container">
<div id="intro">
<div id="pageHeader">
<h1><span>css Zen Garden</span></h1>
<h2><span>The Beauty of <acronym title="Cascading Style Sheets">CSS</acronym> Design</span></h2>
</div>
<div id="quickSummary">
<p class="p1"><span>A demonstration of what can be accomplished visually through <acronym title="Cascading Style Sheets">CSS</acronym>-based design. Select any style sheet from the list to load it into this page.</span></p>
<p class="p2"><span>Download the sample <a href="/zengarden-sample.html" title="This page's source HTML code, not to be modified.">html file</a> and <a href="/zengarden-sample.css" title="This page's sample CSS, the file you may modify.">css file</a></span></p>
</div>
<div id="preamble">
<h3><span>The Road to Enlightenment</span></h3>
<p class="p1"><span>Littering a dark and dreary road lay the past relics of browser-specific tags, incompatible <acronym title="Document Object Model">DOM</acronym>s, and broken <acronym title="Cascading Style Sheets">CSS</acronym> support.</span></p>
<p class="p2"><span>Today, we must clear the mind of past practices. Web enlightenment has been achieved thanks to the tireless efforts of folk like the <acronym title="World Wide Web Consortium">W3C</acronym>, <acronym title="Web Standards Project">WaSP</acronym> and the major browser creators.</span></p>
<p class="p3"><span>The css Zen Garden invites you to relax and meditate on the important lessons of the masters. Begin to see with clarity. Learn to use the (yet to be) time-honored techniques in new and invigorating fashion. Become one with the web.</span></p>
</div>
</div>
<div id="supportingText">
<div id="explanation">
<h3><span>So What is This About?</span></h3>
<p class="p1"><span>There is clearly a need for <acronym title="Cascading Style Sheets">CSS</acronym> to be taken seriously by graphic artists. The Zen Garden aims to excite, inspire, and encourage participation. To begin, view some of the existing designs in the list. Clicking on any one will load the style sheet into this very page. The code remains the same, the only thing that has changed is the external .css file. Yes, really.</span></p>
<p class="p2"><span><acronym title="Cascading Style Sheets">CSS</acronym> allows complete and total control over the style of a hypertext document. The only way this can be illustrated in a way that gets people excited is by demonstrating what it can truly be, once the reins are placed in the hands of those able to create beauty from structure. To date, most examples of neat tricks and hacks have been demonstrated by structurists and coders. Designers have yet to make their mark. This needs to change.</span></p>
</div>
<div id="participation">
<h3><span>Participation</span></h3>
<p class="p1"><span>Graphic artists only please. You are modifying this page, so strong <acronym title="Cascading Style Sheets">CSS</acronym> skills are necessary, but the example files are commented well enough that even <acronym title="Cascading Style Sheets">CSS</acronym> novices can use them as starting points. Please see the <a href="http://www.mezzoblue.com/zengarden/resources/" title="A listing of CSS-related resources"><acronym title="Cascading Style Sheets">CSS</acronym> Resource Guide</a> for advanced tutorials and tips on working with <acronym title="Cascading Style Sheets">CSS</acronym>.</span></p>
<p class="p2"><span>You may modify the style sheet in any way you wish, but not the <acronym title="HyperText Markup Language">HTML</acronym>. This may seem daunting at first if you&#8217;ve never worked this way before, but follow the listed links to learn more, and use the sample files as a guide.</span></p>
<p class="p3"><span>Download the sample <a href="/zengarden-sample.html" title="This page's source HTML code, not to be modified.">html file</a> and <a href="/zengarden-sample.css" title="This page's sample CSS, the file you may modify.">css file</a> to work on a copy locally. Once you have completed your masterpiece (and please, don&#8217;t submit half-finished work) upload your .css file to a web server under your control. <a href="http://www.mezzoblue.com/zengarden/submit/" title="Use the contact form to send us your CSS file">Send us a link</a> to the file and if we choose to use it, we will spider the associated images. Final submissions will be placed on our server.</span></p>
</div>
<div id="benefits">
<h3><span>Benefits</span></h3>
<p class="p1"><span>Why participate? For recognition, inspiration, and a resource we can all refer to when making the case for <acronym title="Cascading Style Sheets">CSS</acronym>-based design. This is sorely needed, even today. More and more major sites are taking the leap, but not enough have. One day this gallery will be a historical curiosity; that day is not today.</span></p>
</div>
<div id="requirements">
<h3><span>Requirements</span></h3>
<p class="p1"><span>We would like to see as much <acronym title="Cascading Style Sheets, version 1">CSS1</acronym> as possible. <acronym title="Cascading Style Sheets, version 2">CSS2</acronym> should be limited to widely-supported elements only. The css Zen Garden is about functional, practical <acronym title="Cascading Style Sheets">CSS</acronym> and not the latest bleeding-edge tricks viewable by 2% of the browsing public. The only real requirement we have is that your <acronym title="Cascading Style Sheets">CSS</acronym> validates.</span></p>
<p class="p2"><span>Unfortunately, designing this way highlights the flaws in the various implementations of <acronym title="Cascading Style Sheets">CSS</acronym>. Different browsers display differently, even completely valid <acronym title="Cascading Style Sheets">CSS</acronym> at times, and this becomes maddening when a fix for one leads to breakage in another. View the <a href="http://www.mezzoblue.com/zengarden/resources/" title="A listing of CSS-related resources">Resources</a> page for information on some of the fixes available. Full browser compliance is still sometimes a pipe dream, and we do not expect you to come up with pixel-perfect code across every platform. But do test in as many as you can. If your design doesn&#8217;t work in at least IE5+/Win and Mozilla (run by over 90% of the population), chances are we won&#8217;t accept it.</span></p>
<p class="p3"><span>We ask that you submit original artwork. Please respect copyright laws. Please keep objectionable material to a minimum; tasteful nudity is acceptable, outright pornography will be rejected.</span></p>
<p class="p4"><span>This is a learning exercise as well as a demonstration. You retain full copyright on your graphics (with limited exceptions, see <a href="http://www.mezzoblue.com/zengarden/submit/guidelines/">submission guidelines</a>), but we ask you release your <acronym title="Cascading Style Sheets">CSS</acronym> under a Creative Commons license identical to the <a href="http://creativecommons.org/licenses/by-nc-sa/1.0/" title="View the Zen Garden's license information.">one on this site</a> so that others may learn from your work.</span></p>
<p class="p5"><span>Bandwidth graciously donated by <a href="http://www.dreamfirestudios.com/">DreamFire Studios</a>. Now available: <a href="http://www.amazon.com/exec/obidos/ASIN/0321303474/mezzoblue-20/">Zen Garden, the book</a>.</span>&nbsp;</p>
</div>
<div id="footer">
<a href="http://validator.w3.org/check/referer" title="Check the validity of this site&#8217;s XHTML">xhtml</a> &nbsp;
<a href="http://jigsaw.w3.org/css-validator/check/referer" title="Check the validity of this site&#8217;s CSS">css</a> &nbsp;
<a href="http://creativecommons.org/licenses/by-nc-sa/1.0/" title="View details of the license of this site, courtesy of Creative Commons.">cc</a> &nbsp;
<a href="http://www.contentquality.com/mynewtester/cynthia.exe?Url1=http:%2F%2Fcsszengarden.com%2F" title="Check the accessibility of this site according to U.S. Section 508">508</a> &nbsp;
<a href="http://mezzoblue.com/zengarden/faq/#aaa" title="Check the accessibility of this site according to Web Content Accessibility Guidelines 1.0">aaa</a>
</div>
</div>
<div id="linkList">
<div id="linkList2">
<div id="lselect">
<h3 class="select"><span>Select a Design:</span></h3>
<ul>
<li><a href="?cssfile=/202/202.css&amp;page=0" title="AccessKey: a" accesskey="a">Retro Theater</a> by <a href="http://space-sheeps.info/" class="c">Eric Rog&eacute;</a></li>
<li><a href="?cssfile=/201/201.css&amp;page=0" title="AccessKey: b" accesskey="b">Lily Pond</a> by <a href="http://www.tulips4rose.com" class="c">Rose Thorogood</a></li>
<li><a href="?cssfile=/200/200.css&amp;page=0" title="AccessKey: c" accesskey="c">Icicle Outback</a> by <a href="http://www.timovirtanen.com/" class="c">Timo Virtanen</a></li>
<li><a href="?cssfile=/199/199.css&amp;page=0" title="AccessKey: d" accesskey="d">Zen Army</a> by <a href="http://www.niceguy.com/" class="c">Carl Desmond</a></li>
<li><a href="?cssfile=/198/198.css&amp;page=0" title="AccessKey: e" accesskey="e">The Original</a> by <a href="http://www.bluejam.com/" class="c">Joachim Shotter</a></li>
<li><a href="?cssfile=/197/197.css&amp;page=0" title="AccessKey: f" accesskey="f">Floral Touch</a> by <a href="http://www.jahmasta.com/" class="c">Jadas Jimmy</a></li>
<li><a href="?cssfile=/196/196.css&amp;page=0" title="AccessKey: g" accesskey="g">Elegance in Simplicity</a> by <a href="http://www.manisheriar.com/blog/" class="c">Mani Sheriar</a></li>
<li><a href="?cssfile=/195/195.css&amp;page=0" title="AccessKey: h" accesskey="h">Dazzling Beauty</a> by <a href="http://blog.denysri.com/" class="c">Deny Sri Supriyono</a></li>
</ul>
</div>
<div id="larchives">
<h3 class="archives"><span>Archives:</span></h3>
<ul>
<li><a href="/?cssfile=/001/001.css&amp;page=1" title="View next set of designs. AccessKey: n" accesskey="n"><span class="accesskey">n</span>ext designs &raquo;</a></li>
<li><a href="http://www.mezzoblue.com/zengarden/alldesigns/" title="View every submission to the Zen Garden. AccessKey: w" accesskey="w">Vie<span class="accesskey">w</span> All Designs</a></li>
</ul>
</div>
<div id="lresources">
<h3 class="resources"><span>Resources:</span></h3>
<ul>
<li><a href="/001/001.css" title="View the source CSS file for the currently-viewed design, AccessKey: v" accesskey="v"><span class="accesskey">V</span>iew This Design&#8217;s <acronym title="Cascading Style Sheets">CSS</acronym></a></li> <li><a href="http://www.mezzoblue.com/zengarden/resources/" title="Links to great sites with information on using CSS. AccessKey: r" accesskey="r"><acronym title="Cascading Style Sheets">CSS</acronym> <span class="accesskey">R</span>esources</a></li>
<li><a href="http://www.mezzoblue.com/zengarden/faq/" title="A list of Frequently Asked Questions about the Zen Garden. AccessKey: q" accesskey="q"><acronym title="Frequently Asked Questions">FA<span class="accesskey">Q</span></acronym></a></li>
<li><a href="http://www.mezzoblue.com/zengarden/submit/" title="Send in your own CSS file. AccessKey: s" accesskey="s"><span class="accesskey">S</span>ubmit a Design</a></li>
<li><a href="http://www.mezzoblue.com/zengarden/translations/" title="View translated versions of this page. AccessKey: t" accesskey="t"><span class="accesskey">T</span>ranslations</a></li>
</ul>
</div>
</div>
</div>
</div>
<!-- These extra divs/spans may be used as catch-alls to add extra imagery. -->
<div id="extraDiv1"><span></span></div><div id="extraDiv2"><span></span></div><div id="extraDiv3"><span></span></div>
<script type="text/javascript">
function removeSheets(){
if(document.styleSheets){
var c = document.styleSheets.length;
for(var i=0;i<c;i++){
document.styleSheets[i].disabled=true;
}
}
findNamedElements();
}
function findNamedElements(){
allElements = document.getElementsByTagName('*');
for(i=0;i<allElements.length;i++){
allElements[i].style.cssText = '';
if(allElements[i].id){
allElements[i].style.position = 'relative';
allElements[i].style.border = '1px solid silver';
allElements[i].style.padding = '20px';
allElements[i].style.margin = '10px';
p=document.createElement('p');
sometext = document.createTextNode(allElements[i].id);
p.appendChild(sometext);
p.className = 'cartel';
allElements[i].appendChild(p);
}
}
if (window.innerWidth){
var styleText = '.cartel{border:1px dashed red;position:absolute;top:0;left:0;padding:2px;background-color:#fff}';
var head=document.getElementsByTagName("head")[0];
var styleNode = document.createElement("style");
styleNode.appendChild(document.createTextNode(styleText));
head.appendChild(styleNode);
}else{
var newStyle = document.createStyleSheet();
newStyle.addRule('.cartel','border:1px dashed red;position:absolute;top:0;left:0;padding:2px;background-color:#fff');
}
}
removeSheets();
</script>
</body>
</html>

The code

Download this file, unzip it in the same folder and call it via >perl stylizator.pl yourhtmlfile.html
It’ll create a file named yourhtmlfile.css and another one called yourhtmlfile.structure.html

Further work

There’s so much to be done. It could be possible to create a firefox extension that gives us the same visual result at the press of a button, or a system that keeps only structural CSS, discarding type and colors. The regular expressions could be better, too, to allow not-so-well-defined documents. If you have any further questions, drop me a line to david@corunet.com.

Sometimes I wish I could do things that were easily done with table-based layouts but quite hard using just CSS.
Following a couple of posts in a CSS related Spanish mailing list (Ovillo), a guy called Zafonic showed me how to use negative margins and positive paddings to make equal sized columns. With a couple javascript functions, I patched it to fill the full browser window. Let’s see how…Update: Error in code solved. Thanks to the testers.

The problem

We’re going to write a three-column plus footer layout that covers all the browser space. The requisites are the following:

We want the page to cover the full height of the browser. So, the footer will be at the bottom of the screen.

The layout has to degrade gracefully for javascript disabled browsers

All the code has to be valid and accesible

The beginning

The first part is simple. We need some html that defines three columns and a footer. Lets wrap the three columns within a div (called, by the way, container) and call the three columns col1, col2 and col3. The html code will be something like:

So, we already have a three column layout, but each column has a diferent height and the footer is far from the bottom:

Negative margins to the rescue

As I already told you, I had’t heard about creating layouts using negative margins (I should have read this article from A List Apart some time ago). In a nutshell, it says that you can use a large negative margin and the opposite positive padding to “make room for the columns”. I recommend to read it if you haven’t, it’s very useful.
So, let’s go on the code. We’re going to add a -5000 pixel margin-bottom and a 5000 pixel padding-bottom to each column:

This function returns the height of the browser window. It does one thing and does it well… Using this new knokledge, we can set the height of the columns, making them the browser’s window height minus the footer, to fill the screen completely. The other function we’ll need is:

This function works by calling the last one (windowHeight) and substracting the footer size. If we’re in Explorer, we use style.height to modify the height of the columns and in all other browsers, minHeight, since Explorer doesn’t support that attribute. We’re going to call that function via onload.
And we get this:

If the window is not tall enough to fit the column height, the page behaves normally:

If you use it in a production environment, it’d be wise to split the javascript and the CSS into their own files, and review all the code, since it’s done in a quick and dirty way.

You can download the code using this link. People without javascript don’t get the full height but the site is equally usable and visually pleasant. I you have any further questions or just want to talk, drop me a line to david@corunet.com

]]>http://blog.corunet.com/three-column-layout-with-full-page-height/feed/3Clickmaps in sourceforgehttp://blog.corunet.com/clickmaps-in-sourceforge/
http://blog.corunet.com/clickmaps-in-sourceforge/#commentsMon, 21 Aug 2006 16:55:49 +0000http://blog.corunet.com/english/clickmaps-in-sourceforgeToday, all the code for creating clickmaps has been uploaded to sourceforge and made public under a GPL license. You can find it at http://sourceforge.net/projects/clickmaps

Thanks to jerret, the code now uses RMagick calls and it’s usable with logs sporting more than ten thousand clicks per page.