CSS and XML: applying styles

CSS can be actually used to stylize XML documents. Anyway, there are a few gotchas to keep in mind when using CSS stylesheets with XML.

Default styles

Default styles (that is, styles used by the browser when none is specified) don't exist in XML. That's because XML has no predefined DTD to use when no stylesheet is provided. For example, if you don't specify any rule for the body element in XHTML, Firefox uses the following rule:

body {
  display: block;
  margin: 8px;
}

This is not the case of XML, where you have to esplicitly declare if every single element is a block-level element or not (or whatever type of display rule you want to be applied on it). Don't forget to do this, because browsers treat XML elements as inline by default, so you'll get only a single bunch of inline text by default.

Default algorithms

While browsers tend to adjust their algorithms with XHTML elements, they follow strictly CSS specifications with XML elements. So if a particular browser show a certain behavior for an XHTML element, you should not rely on this when it comes to XML.

Simply put, that means that if a browser doesn't fully implement a CSS feature, this lack of support will be shown entirely when dealing with XML elements. For example, suppose that you want to use relative and absolute positioning inside an XHTML table cell. CSS specifications say explicitly that this is an unpredictable behavior. Anyway, some browsers (like Opera), tend to adjust their rendering to prevent page layout from being broken. But this happens only with XHTML elements.

Instead, in XML you will see your layout completely broken and the positioned elements being scattered throughout the entire page. As a rule of thumb, you should always test if a feature if fully supported or not, or you might stumble on some strange surprises.

Using template blocks in XHTML

Template blocks are a common feature used in many template engines, such as Smarty. Basically, a template block usually looks like this:

<!-- BEGIN element -->
    element
<!-- END element -->

We can use the same syntax in XHTML while preparing our static files for later using in a dynamic environment. Example:

<!-- BEGIN branding -->
   <div id="branding">

  </div>
<!-- END branding -->

By doing so, we achieve the result of writing more flexible and reusable template files, which is very handy when it comes to converting them into something dynamic (such for example the inclusion in a CMS).

On the importance of prefixes in SQL structure

Disambiguation is one of the key aspects of every good database structure. If we don't structure our data properly, we might stumble on some problems while querying a database. Consider the following two tables (MySQL):

CREATE TABLE documents (
  id INT(11) NOT NULL AUTO_INCREMENT,
  title VARCHAR(64),
  content TEXT);

CREATE TABLE posts (
  id INT(11) NOT NULL AUTO_INCREMENT,
  title VARCHAR(64),
  posts_content TEXT);

I've omitted table options and table type for the sake of brevity. If we try to run a query which selects, say, both title from the two tables, we'll see an SQL error, because this is an ambiguous query. The solution is pretty simple: always use prefixes to avoid ambiguity. This is also a good SQL coding practice.

User stylesheets: Feel Like Lynx

This is an experimental user stylesheet that you can include in your browser preferences in order to make it display web pages like Lynx, the textual browser. Feel free to modify it. Enjoy!

/* Name: Feel Like Lynx (FLL)
   Author: Gabriele Romanato
   Author URI: www.css-zibaldone.com | http://onwebdev.blogspot.com
   Version: 1.0
   License: Free */


body {
background-color: #000 !important; 
background-image: none !important;
color: #808000 !important;
font-family: "Lucida Console", Monaco, "Courier New", Courier, monospace !important;
margin: 8px !important;
padding: 0 !important;
font-weight: bold !important;
}

*, *[id], *[class], *[style], *[bgcolor] {
 float: none !important;
 position: static !important;
 text-align: left !important;
 background-color: #000 !important;
 background-image: none !important;
 color: #808000 !important;
 border: none !important;
 font-family: "Lucida Console", Monaco, "Courier New", Courier, monospace !important;
 width: auto !important;
 height: auto !important;
 padding: 0 !important;
 font-weight: bold !important;
 font-size: 1em !important;
}

a:link, a:visited {color: #008000 !important; text-decoration: none !important;}
a:hover {color: #0f0 !important; background: #800000 !important;}
a:focus {
 outline-style: none !important;
}
a img {
 border: none !important;
}

h1, h2, h3, h4, h5, h6 {color: #008080 !important; font-size: 1em !important;}
blockquote {
 color: #0ff !important; 
}
 
q, cite, em, li {color: #ff40ff !important;}
 
code, cite, pre {color: #0ff !important;}

strong, b {
 color: #008080 !important;
}

q, cite, em, dfn, var, code, samp, kbd, strong, a, label {
 display: inline !important;
}

input[type="text"][class][id],
input[type="text"][class],
input[type="text"][id] {
 border-width: 0 0 2px 0 !important;
 border-style: solid !important;
 border-color: #008000 !important;
 display: inline !important;
 vertical-align: baseline !important;
 padding: 0 !important;
}

input[type="submit"][class][id],
input[type="submit"][class],
input[type="submit"][id] {
 border: none !important;
 background: transparent !important;
 color: #008000 !important;
 display: inline !important;
 vertical-align: baseline !important;
 padding: 0 !important;
 text-transform: none !important;
 font-weight: bold !important;
 position: relative !important;
 top: 0.6em !important;
}

img {
 display: inline !important;
}

img[alt]:after {
 content: attr(alt) !important;
 color: #008080 !important;
 background: transparent !important;
}

img[src]:not([alt]):after {
 content: attr(src) !important;
 color: #008080 !important;
 background: transparent !important;
}



ul, ol, dl, ul li {
 display: block !important;
}


ul li:before {
 content: "\002A" !important;
 padding-right: 0.2em !important;
 color: #808000 !important;
}

h1, h2, h3, h4, h5, h6, p, dl, ul, ol, address, blockquote, pre {
 margin-top: 0.5em !important;
 margin-bottom: 0.5em !important;
 display: block !important;
}

div, div[class], div[id] {
 margin: 0 !important;
 display: block !important;
}

ul, ol {
 margin-left: 2.5em !important;
 margin-right: 0 !important;
 padding: 0 !important;
}


form, form[id], form[class], form[class][id] {
 margin: 0 !important;
 padding: 0 !important;
 width: auto !important;
 height: auto !important;
}

table, table[border], table[cellspacing], table[cellpadding],
table[border][cellspacing][cellpadding] {
 border: none !important;
 padding: 0 !important;
 border-spacing: 0 !important;
 width: auto !important;
 height: auto !important;

}

td, th {
 padding: 0 !important;
 width: auto !important;
 height: auto !important;
 border: none !important;
}

th {
 text-align: left !important;
}

caption {
 text-align: left !important;
 margin: 0 !important;
 padding: 0 !important;
 color: #008080 !important;
 width: auto !important;
 height: auto !important;
 border: none !important;

}

caption:before {
 content: "CAPTION:" !important;
 padding-right: 0.4em !important;
}

hr {
 display: block !important;
 color: #808080 !important;
 background: #808080 !important;
 height: 1px !important;
 width: auto !important;
}

font[face],
font[size],
font[color],
font[face][size][color] {
 font-size: 1em !important;
 font-family: "Lucida Console", Monaco, "Courier New", Courier, monospace !important;
 color: #808000 !important;
 background: transparent !important;
}

marquee {
 -moz-binding: none !important; /* Firefox */
 overflow: hidden !important;  /* Safari */
 display: inline !important; /* Opera */
}


blink {
 text-decoration: none !important;
}

Overuse of PCRE in PHP considered harmful

PCRE (Perl-Compatible Regular Expressions) in PHP can be really useful, but only when used properly. A common error with this kind of approach occurs when we try to extract complex markup snippets from a web document. The sad truth is that we're actually assuming that a document has a well-formed and regular markup structure, which is not always the case. Let's take for example a document that contains two paragraphs like the following:

<p>First paragraph on a single line.</p>

<p>Second paragraph on two lines.
</p>

We could use the following PHP code to extract the content of both paragraphs:

$test_file = file_get_contents('test.html');
    $single_line_para = '#<p>.+</p>#';
    
    if(preg_match_all($single_line_para, $test_file, $matches)) {
        
        foreach($matches[0] as $match) {
            
            
            $match = strip_tags($match);
            
            
        }
        
        echo '<p>The content of the first paragraph is: <em>' . $match . '</em></p>' . "\n";
        
        
    }
    
    $two_line_para = '#<p>.+\n</p>#';

    if(preg_match_all($two_line_para, $test_file, $matches)) {
        
        foreach($matches[0] as $match) {
            
            
            $match = strip_tags($match);
            
            
        }
        
        echo '<p>The content of the second paragraph is: <em>' . $match . '</em></p>' . "\n";
        
        
    }

So far so good. But what happens if paragraphs have no closing tags? Or what happens if there are many occurrences of the newline character? Simply put, everything fails. In short, PCRE should be used only in really predictable scenarios, like form validation, file and directory handling and URLs management. Everything else should be pondered carefully.

Using PHP array functions on a DOMDocument NodeList

The PHP DOMDocument class implements the W3C DOM. However, PHP implementation is quite different from its JavaScript counterpart, so it's not so easy to make something like this:

$dom = new DOMDocument();
$dom->load('test.xml');

$items = $dom->getElementsByTagName('item');
$items = array_slice($items, 0, 3); // returns an error

The fact is that we're actually dealing with a NodeList collection of DOM element objects, so it's not possible to use array functions on them (with JavaScript there are a couple of tricks to perform this operation, though). I have to test more extensively this feature to solve this problem. So far I've played a little bit with PHP iterators, but I wasn't lucky, perhaps because I'm using a wrong approach. I'll let you know, so stay tuned.

PHP 5 and the var keyword

Object-oriented support in PHP has been greatly improved with release 5. However, for backward compatibility reasons with older versions, some coding practices have been keeped. Among them there's the use of the var keyword in class definitions. Honestly, from an OOP perspective, I don't understand what this keyword is useful for. For example:

class myClass 
{
  var foo;
  var bar;
  var baz;
}

Seeing these declarations gets me confused, because I don't know at first glance what's the visibility of these members. Using a classic OOP, instead, makes life a lot easier and it's really much neater:

class myClass
{
  public $foo;
  protected $_bar;
  private $_baz;
}

So far I've never used var in my classes, and I have to say that my code is clearer and more intuitive. You should take into account the fact of getting rid of this old habit.

CSS forms: handling input background images

Sometimes stylizing a form input field is something that we have to learn by experience. As always, a trial-and-error approach is the best way to acquire a firm knowledge of a technique. Suppose that you have a text field like this:

<input type="text" name="query" id="query" />

Now imagine that you want to use a background image on this field, something like a 200 x 20 GIF image with rounded corners and a surrounding shadow. An innocent coder would be tempted to write something like this:

input#query {
  border: none;
  width: 200px;
  height: 20px;
  background: url("text-field.gif") no-repeat;
}

It does work, but there's a major drawback with this approach: the text cursor appears on the very left edge on the field and not where it was supposed to appear. So you have a cursor that blinks almost outside the field and this is not the effect you want to achieve. Why this? Two considerations:

  1. the dimensions of this kind of form elements are not simply given by a width or height declaration, but also (and mostly) by the font size and family used on them; so if you want to get consistent results across browsers, you have to specify a font family and size that equals that used on the page (or at least on the direct ancestor of the element), because browsers assign by default a proprietary font family and size to this kind of elements
  2. input fields are not block-level elements, but inline-block elements, so you have to consider the fact that their rendering is treated differently.

A good solution to this problems is as follows:

input#query {
  border: none;
  width: 200px;
  padding: 5px;
  background: url("text-field.gif") no-repeat;
}

Instead of declaring height: value on the element, we use padding to make sure that the text cursor will be placed exactly where we want (obviously we have to adjust the amount of padding required to show the background image entirely). This is a cross-browser approach with no drawbacks.

Rootkits: review of an infection

I think we finally discovered the potential damage of Windows rootkits when we have to deal with MBR (master boot record) rootkits. Recently my father got infected by one of those rootkits. It basically hides a service (random name), some registry keys and a DLL driver in %SystemRoot%, plus a directory in the MBR. I've tried with Gmer and I succeeded in removing the service, but I wasn't able to remove the registry entries and the DLL driver. What's more, this rootkit disables the view/hide hidden file option on Windows XP. According to Gmer and catchme, also Nod32 is affected by this rootkit, in the sense that the rootkit hides himself from the antivirus. Oh well. Sophos and Norman Cleaner don't detect any anomaly. Fine. I think I need a little help. Any ideas?

User-friendly URLs in user profiles

One of the worst things in a web application is the fact of using URLs such as user.php?id=1234 for displaying user profiles. For example, a web application such as Facebook wisely doesn't follow this approach. Instead, it uses something like directory/username for user profiles. This also allows the newly created page to be better indexed by search engine.

I don't have access (of course I don't!) to Facebook's database structure, but I guess that there should be a table which stores my credentials, such as first name and last name (say user_first_name and user_last_name), so the point is creating an unique URL by using these credentials, something like this:

$query = mysql_query("SELECT user_first_name, user_last_name FROM user WHERE user_id='$uid'");
$results = mysql_fetch_array($query);
 $first_name = $results['user_first_name'];
 $last_name = $results['user_last_name'];

$first_name = strtolower($first_name);
$last_name = strtolower($last_name);

$user_ url = $first_name . $last_name;

For the sake of brevity, I've omitted to remove any trailing white-space from both strings, but now you can get the idea. Obviously the variable $uid must be previously set. Anyway, by doing so, you have a good starting point for testing. A problem that will certainly arise is duplicate user credentials, for example when there are one or more users with the same first name or last name. In this case you can use other data from the table, such for example an ID or the username chosen during the registration process.

DOM Level 2: state of the support for namespace methods

DOM Level 2 specification defines a new series of methods to be used with XML namespaces (though, in theory, they should work also in XHTML). Methods such as getElementsByTagNameNS() or getAttributeNS() are really handy when dealing with complex XML documents featuring several namespaces. They basically accept a namespace URL and a local name by which we can get/set our elements or resources.

However, browser support is, as always, cut in half: on one side, there are Firefox, Safari, Opera and Chrome which all support the aforementioned features; on the other side, instead, there is Internet Explorer that, at the time of writing, doesn't support these features. So what? I've followed the IE9 preview but I only read about the support of the DOM standard event model. Nothing about DOM Level 2 namespace methods. I tried to test something with jQuery ($(element).find(element)). and I have to say that in some cases it works just well, but I didn't dig deep into the details of more complex XML documents. So I need more time to say if jQuery (and its related plugins) are a feasibile alternative when dealing with namespaces in a cross-browser way.

CSS floats or tables? A practical approach

I'm going to develop a web-based application for domestic use containing a database for all our DVDs. In that vein, I'd like to mention here a little problem occurred during the creation process of the markup used for displaying search results. The question is: floats or tables? Since I have to deal with items like director, year, actors and so on, using floats actually involves a markup like the following:

<ul class="dvd-info">
<li>
  <div class="dvd-item">
    <h4>Director</h4>
  </div>
  <div class="dvd-content">
    <p>Ridley Scott</p>
  </div>
</li>
<!-- more items here -->
</ul>

The CSS would be something like:

ul.dvd-info {
  width: 100%;
  margin: 0 0 0.4em 0;
  padding: 0;
  list-style: none;
}
ul.dvd-info li {
  height: 100%;
  overflow: hidden;
  margin-bottom: 4px;
}

ul.dvd-info li .dvd-item {
  float: left;
  width: 25%;
  text-align: right;
}
ul.dvd-info li .dvd-content {
  float: left;
  width: 70%;
  padding-left: 0.3em;
}

The problem with this approach is that we're actually dealing with a semantic relationship between items (e.g. "Director" and "Ridley Scott") that will be completely lost if we use the aforementioned markup and floats. In fact, we should use a table heading associated with a table cell. This approach also makes our content easier to navigate for assistive technologies that use keyboard shortcuts to extract and navigate page contents. In this case, I think, using a table is the right choice.

Setting a permanent link with PHP

I've found the following function in Practical Web 2.0 applications with PHP and MySQL:


function generateUniqueUrl($title)
{
  $url = strtolower($title);

  $filters = array (
                    '/&+/' => 'and',
                   '/[^a-z0-9]+/i' => '-',
                   '/-+/' => '-' );

  foreach($filters as $re => $replacement) {
    $url = preg_replace($re, $replacement, $url);
  }

  $url = trim($url, '-');
  $url = trim(substr($url, 0, 30));

  if(strlen($url) == 0) {
    $url = 'post';
  }

  // find similar URLs in the database
  
  $query = sprintf("select url from %s where id_user = %d and url like ?", $this->_table, $this->id_user);
  $query = $this->_db->quoteInto($query, $url . '%');
  $result = $this->_db->fetchCol($query);

  if(count($result) == 0 || !in_array($url, $result)) {
    return $url;
  }

  // generate an unique URL

  $i = 2;

  do {
    $_url = $url . '-' . $i++;
  } while(in_array($_url, $result));

  return $_url;
}

This function first filters all special characters that may occur in a post title, then check if there are similar URLs in other posts and finally generates an unique post identifier using a counter attached to the main URL. Very interesting!

Standards war, episode one: revenge of the embed element

As many of you have noticed yet, this blog has the bad habit to embed many YouTube videos taken from different sources. Since I should be, theoretically speaking, a stickler of web standards, this should be done only through the object element. But this is not the case, and that's not my fault and it doesn't depend on a personal choice. The sad truth is that the object element alone is supported by all browsers, but not all its features, such for example the parameters you can pass to it via the param element. Internet Explorer, in fact, fully supports this element, but this is not the case of Firefox, which still uses the embed element. Why? Because this is a relic of the age of the first browser wars, when every browser tried to beat its adversary by implementing new features. More specifically, the embed element was not that bad, but the official HTML specs didn't include it as a standard element so its use should be deprecated. I said "should", but when it comes to reality, this element takes its revenge on standards in the form of a widespread support by almost all the platforms used for sharing videos (headed by YouTube). So what? As always, we must wait until the use of the object element will reach its momentum or, alternatively, try the new cool features of the latest HTML 5 specs (if we have enough spare time... or we can afford to wait). If you want code to the standards, consider the use of JavaScript as an alternative to avoid validation issues.

Stop using Jaws for web accessibility testing?

I don’t follow the point of this post. Jaws is the only way that a developer has to surf the web as a visually-impaired user does. Other tools cannot mimic a real experience, the experience of listening to your content being read aloud by a syntethic voice. No online service can do this. I think that the reason should be found elsewhere. First, sighted people generally don’t take care too much of what other people experience, just because they see and they can’t imagine a world without colors and images. That’s a problem of sensitivity and need to experience (or try to experience) what other people feel when colors and images don’t exist. Second, the overwhelming majority of company websites don’t care about accessibility issues, just because accessibility doesn’t fall in their marketing strategy. We want an easy-going way to say “oh yes, I know what accessibility problems are and I’ve tested them!”. Be honest: accessibility arise problems that very few people want to face. First and over all, accessibility means looking at the world with the eyes of people who suffer from disabilities, so it’s a matter of how much we care about the problems of other persons. Are they important to us or are we forced to cope with them just because a law wants so? I’m not criticizing this post, but I’m simply saying that our motivations should be clear to ourselves. Everything else comes second.

Facebook doesn't support assistive browsers

Facebook, as I said in an earlier post, is almost inaccessible for people who use assistive technologies. Here's a screenshot taken while trying to connect to Facebook using Lynx, the textual browser:

Lynx and Facebook

As you can see, Lynx is not supported, so trying to log in results in a frustrating experience of redirections. I hope that Facebook will start to take into account this kind of users and their needs, because it's too bad that a web application like Facebook doesn't support assistive technologies.

How to build your own CSS website

Actually, there's something wrong in this tutorial. The first thing is that the author uses a page without DOCTYPE, so you will probably stumble on some of the most obtuse CSS bugs of Internet Explorer 6. Second, it's considered bad practice to embed your styles inside the main document. Anyway, this is one of the few tutorials on the subject hosted by YouTube. Probably I should record a video myself, provided that I'll be able to make my camera work...

Babysitting my little niece Matilde

Matilde I'm just about to go to babysit my little niece Matilde, so I'm going to spend a few ours with her this morning until her parents come back from work. Matilde is simply the best thing in the world ever occurred to our family since a long time. We all love her madly! I've got some nice photos of Matilde on my Facebook and Flickr account, so if you want to take a look just go there. Sorry for not posting some web-related stuff, but I think that this is even much more better!

Amazon's URLs: some reflections on URL rewriting

URL rewriting, SEO friendly URLs, PHP: these are the topics that I'm currently testing while developing a local CMS with PHP and MySQL. Then I stumbled on something beatiful: Amazon's URLs. I mean, these URLs are really interesting because they show a good way to handle dynamic URLs while dealing with search engines. For example, I found this URL on Google top results:

http://www.amazon.com/PHP-Architects-Guide-Design-Patterns/dp/0973589825

Did you notice how it works? The title of the item has been turned into a dashed-delimited sequence (word-word) and it's put before the actual item's ID (which is a sequence of numbers always starting with 0). By doing so, the problem of directory recursion is avoided, because a SE finds the title first (more significant) and then the remainder of the URL (this part doesn't matter, because it contains no keywords). A great lesson from Amazon!

CSS namespaces in Internet Explorer

Using namespaces in CSS (MSDN): does someone know if this solution works in Internet Explorer? Something like this:

element\:local-name {
  color: green;
}

That is, by escaping the ':' token (a CSS delimiter for a pseudo-element) we actually select an element with a given local name? Is that possible? Does this solution require the MSXML library to get it work? I honestly don't know. If someone has tested something like this, please let me know.

Ajax and jQuery: the beginning

This video gives just a fresh start on the topic. To be honest, jQuery's Ajax implementation is sometimes prone to error in IE, while Prototype's one works well. As I said before, to be on the safe side is better to write your own, simple Ajax classes instead of relying on something that you cannot fully control. Just write your classes in a reusable way and you won't need an entire library to fetch content or submitting a form. I can guarantee it.

Two PHP functions to handle MySQL dates

MySQL dates (datetime type) usually follow this pattern: 2010-03-11 17:18:02. Here are two PHP functions to create and format MySQL dates on your site/blog:

function create_sql_date() 
{
           
  // MySQL datetime: YYYY-MM-DD hh:mm:ss
          
  $timestamp = time();
          
  return strftime('%Y-%m-%d %H:%M:%S', $timestamp); 
           
}
       
function format_sql_date($date) 
{
           
  $date_time = new DateTime($date);
         
  return ($date_time->format('F j, Y'));   
           
           
}

The first function is useful to create fresh dates to be inserted in the database, while the latter can be deployed to format MySQL dates after retrieving them from a query.

On the names of CSS background images

Semantics is a good thing on the web, but it can actually turn out to be harmful if not used properly. A common approach in writing names of CSS background images is to map image names to element names. For example, if you have an element with an ID named branding, the corresponding image name should be branding.jpg and so on. So far so good, because IDs are something unique throughout an entire web page. But what happens with other elements, for example class names? As a rule of thumb, you should always choose image names that can be reused or you will end up with the same image having dozens of different names. For example, if you have an image named link.gif, you can use that either on a breadcrumb trail or on external links, instead of renaming it breadcrumbs.gif and external.gif, respectively. In a nutshell: use semantics properly and with a little bit of common sense, or you'll probably bang your head on the desk while trying to remember the name of your CSS background images.

Magento: first glance

I'm currently cooperating with a company based near Modena and I recently heard about the use of Magento as the default CMS for their e-commerce projects. To keep me up-to-date, I downloaded Magento, unzipped it and took a look at the main configuration files.

The first impression is good: Magento makes use of PEAR and the Zend Framework for its backend activity, but it doesn't use Smarty as default template engine (Smarty compiles everything, so it may generate a little overloading on the server). So far so good.

The installation file checks first if you're using a recent version of PHP. If not, it returns an error:

if (version_compare(phpversion(), '5.2.0', '<')===true) {
    die('ERROR: Whoops, it looks like you have an invalid PHP version. Magento supports PHP 5.2.0 or newer.');
}

That's cool, because we make sure that older, buggy versions of PHP are no longer in use. Magento allows you to install the CMS either via command line or through a web interface. Here's how it performs this initial check:

if ($installer->init($app)          // initialize installer
        && $installer->checkConsole()   // check if the script is run in shell, otherwise redirect to web-installer
        && $installer->setArgs()        // set and validate script arguments
        && $installer->install())       // do install
    {
      echo 'SUCCESS: ' . $installer->getEncryptionKey() . "\n";
        exit;
    }

Actually, the installation options are listed previously within PHP comments:

 * 2. Perform the installation
 *
 *  php -f install.php -- --license_agreement_accepted yes \
 *  --locale en_US --timezone "America/Los_Angeles" --default_currency USD \
 *  --db_host localhost --db_name magento_database --db_user magento_user --db_pass 123123 \
 *  --db_prefix magento_ \
 *  --url "http://magento.example.com/" --use_rewrites yes \
 *  --use_secure yes --secure_base_url "https://magento.example.com/" --use_secure_admin yes \
 *  --admin_lastname Owner --admin_firstname Store --admin_email "admin@example.com" \
 *  --admin_username admin --admin_password 123123 \
 *  --encryption_key "Encryption Key"
 *
 * Possible options are:
 * --license_agreement_accepted // required, it will accept 'yes' value only
 * Locale settings:
 * --locale                     // required, Locale
 * --timezone                   // required, Time Zone
 * --default_currency           // required, Default Currency
 * Database connection options:
 * --db_host                    // required, You can specify server port, ex.: localhost:3307
 *                              // If you are not using default UNIX socket, you can specify it
 *                              // here instead of host, ex.: /var/run/mysqld/mysqld.sock
 * --db_name                    // required, Database Name
 * --db_user                    // required, Database User Name
 * --db_pass                    // required, Database User Password
 * --db_prefix                  // optional, Database Tables Prefix
 *                              // No table prefix will be used if not specified
 * Session options:
 * --session_save <files|db>    // optional, where to store session data - in db or files. files by default
 * Web access options:
 * --admin_frontname <path>     // optional, admin panel path, "admin" by default
 * --url                        // required, URL the store is supposed to be available at
 * --skip_url_validation        // optional, skip validating base url during installation or not. No by default
 * --use_rewrites               // optional, Use Web Server (Apache) Rewrites,
 *                              // You could enable this option to use web server rewrites functionality for improved SEO
 *                              // Please make sure that mod_rewrite is enabled in Apache configuration
 * --use_secure                 // optional, Use Secure URLs (SSL)
 *                              // Enable this option only if you have SSL available.
 * --secure_base_url            // optional, Secure Base URL
 *                              // Provide a complete base URL for SSL connection.
 *                              // For example: https://www.mydomain.com/magento/
 * --use_secure_admin           // optional, Run admin interface with SSL
 * Admin user personal information:
 * --admin_lastname             // required, admin user last name
 * --admin_firstname            // required, admin user first name
 * --admin_email                // required, admin user email
 * Admin user login information:
 * --admin_username             // required, admin user login
 * --admin_password             // required, admin user password
 * Encryption key:
 * --encryption_key             // optional, will be automatically generated and displayed on success, if not specified
 *
 */

As you can see, if you come from Wordpress or another blogging-related CMS this can be quite shocking. I also noticed that Magento makes a massive use of XML for configuration tasks: that's good, because XML is notoriously easy to edit and modify. Well, next days I'll try to put it up on my local machine and to play a little bit with it. (Yes, I have to understand how to write good XHTML/CSS templates for Magento, but since I'm lazy and disorganized, that could take some time)

JavaScript libraries and application/xhtml+xml

It's too bad to discover that a big amount of JavaScript libraries don't support application/xhtml+xml, that is, the natural content type for XHTML. They fail spectacularly, returning a neverending list of DOM errors, mainly due to the junk content inserted into strings. SyntaxHighlighter falls into this category. But why bother? Because we want something more than tag soup, don't we? Basically, there are two kind of problems when dealing with an XML-based content type:

  1. well-formed markup

    All the markup inserted through the innerHTML property must be well-formed. Otherwise, everything fails silently.

  2. characters and entities

    All characters must be mapped to their corresponding XML entities. You cannot insert junk content into a DOMString without seeing an error. Further, you must be aware of the encoding used on your pages and code accordingly.

jQuery and other libraries work well, though. That's because they were designed for returning standard content.

Accessible CAPTCHAs

Michele Diodati is one of the most influent accessibility experts in Italy. He developed a very simple technique to make a CAPTCHA accessible. This technique relies on the existing difference between a human being and a robot. Basically, a robot is unable to understand the meaning of a human sentence or to answer to a simple question, such as "What is the capital of Italy?". Known that, you can tell robots and humans apart by simply asking them a question. If they answer correctly, the form will be submitted, otherwise not. I've tested this kind of filter on a recent project and it works great! No incoming spam!

What's more, you don't need to use an audio file to address the problems of persons who can't see the image, because all they have to do is to insert some text in a text field. That's all. I'd like to see more sites implementing this approach. In the meantime, please thank Michele for his idea.

Managing PHP include paths on shared hosts

Most shared hosts don't allow you to modify the include paths of PHP files. Further, they don't allow you to place include files and configuration files outside the document root (which poses a major security risk). To manage include paths without stumbling on some "no such file or directory" PHP error, you can use the following solution:

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . 'directory/includefile.php');
?>

This way you can call your includes on every single level of your directory structure. I've tested it on my main site and it works well, though I'm aware of the security implications of such a solution. Anyway, remember that most shared hosts don't allow you to modify Apache's configuration neither with an .htaccess file. Oh well...

Managing local hosts on Windows XP

The first thing to do is to locate the host file, which is typically under /windows/system32/drivers/etc. Usually this file contains the following line by default:

127.0.0.1    localhost

Then you can add the name of your local host, which must correspond to a physical directory on your PC:

127.0.0.1    localhost
127.0.0.2    yoursite

It doesn't matter whether you use "yoursite" or "yoursite.com" or even "www.yoursite.com": the important thing is that this name must correspond to a real directory. Done this, you can create a directory structure inside this folder, for example yoursite/htdocs and add a VirtualHost directive in Apache's httpd.conf file by also setting the DocumentRoot directive to a directory of your choice (in this case you can choose htdocs).

Note how the IP trick works: the last number on the right has been incremented by 1 (127.0.0.2), so you can add many other hosts to the host file. Always remember to edit the configuration file of Apache or, even better, use a custom .htaccess file.

XSLT and RSS: test results

I started my tests by stylizing a static RSS file with CSS after transforming it with XSLT and linking to the page through the link element. Browsers apply in this case their own custom template to the RSS file and display it accordingly, so there's no way to circumvent browser default formatting for an RSS document (static in this case). I need more time in order to use a server-side XSLT processing for displaying an RSS document generated on the fly. Time will tell.

The myth of JavaScript turned off

Let's face it: the overwhelming majority of users doesn't even know what JavaScript is, so including this problem between a feasible wish-list of accessibility problems is actually a relic of a bigon age when the web was a static sequence of monolitic sites with animated GIFs and the like. Let's face it: JavaScript may be supported or not supported, and that's the real problem when dealing with accessibility and scripting, so if you intend to build an accessible web site, you should provide a fallback mechanism in the case that JavaScript is not supported or ill-supported (which is even worse).

Sure, some paranoid sysadmins may configure their clients with JavaScript turned off, but they're perfectly aware that almost 100% of web sites uses this client-side language, so this means that their users will experience problems during web surfing, not to say that most of web site features won't be available. Is this a practical way to deal with security problems? Honestly, I don't think so. Forget this myth and try to focus on real scripting-related problems.

Internet Explorer 7 and CSS links: update

I'm a lazy and disorganized person. The code provided in the previous post didn't mention the fact that the XHTML structure was altered by jQuery this way:

<ul id="navigation">
  <li><a href="#"><span>Link</span></a></li>
  <!--more links-->
</ul>

So IE7 fails to correctly apply styles because of the presence of an extra element added by JavaScript (a span element). To avoid this problem, you have to specify your styles directly on the innermost element.

Internet Explorer 7 and CSS links

The worst never dies. I'm currently developing a testing site on my local machine. After implementing the server-side code, today I started applying styles to contents. First surprise: given the following CSS:

a:link, a:visited {
  color: #00f;
}
a:hover {
  color: #00c;
}

/* more styles ... */

#navigation li a:link,
#navigation li a:visited
  background: transparent;
  color: #fff;
}

#navigation li a:hover {
  background: #fff;
  color: #338;
}

The last rule doesn't work in IE7 and the background color doesn't change. It works in IE6 and 8, though. Another CSS bug of IE 7... cascade? specificity? colors? links priority? who knows?

The reincarnation of Internet Explorer 6

I think that the missing support to Internet Explorer 6 is not a good reason to claim that this browser is necessarily gone. In my opinion, since IE6 has still a market share of more than 6%, we should take it into account for some years now. This is exactly what happened to IE5. Meanwhile, let's devote to IE6 a little homage that you can find here.