Monthly Archive for May, 2009

Jamin-Puech

Jamin-Puech is a French company that designs and sells handbags and jewelry worldwide. Still, people couldn’t buy these handbags online, because the brand had no e-commerce website.

This is where I come in: I was the technical lead of the development team brought together by my employer, Tangane, to build a new e-commerce website for Jamin-Puech. It consists mostly of a custom-skinned Magento website with some additional development in various functionality areas.

The result has been online for a short while now. If you’re interested in handbags:

http://www.jamin-puech.com/eboutique/

You cannot hide

You shouldn’t hide parts of your web pages by using display:none. At least, that’s what Roger Johansson says:

In most cases, using display:none to hide an element is a bad choice that reduces accessibility.

I can’t really agree with that. After all, the display:none CSS property exists for a reason, and that reason is precisely to let designers hide parts of the design that shouldn’t be shown in a particular display mode. For instance, there is no point in displaying a navigation bar in a “print” stylesheet, so the navigation bar will get a display:none property and disappear.

Aside from that, I also use display:none to hide things from users that don’t have JavaScript enabled. I see no reason to display AJAX-specific constructs (such as ‘loading’ sprites or containers used to display the result of asynchronous operations) to these users—instead, non-AJAX constructs should be displayed by default and replaced by their AJAX counterparts though JavaScript executed upon page load.

I believe the core of the disagreement here is what hide means. When I hide something, I want it to be completely gone for the user.

  • The user should not be able to see the element.
  • The user should not be able to hear the text on the element.
  • The user should not be able to select the text of the element by using the browser’s Find method.

It’s already bad enough that some web browsers include hidden text when highlighting and copy-pasting text around it (try copy-pasting the hidden text in this sentence), why go for an inferior solution that doesn’t really hide the element?

In the end, the real question is not how to hide elements—use display:none and that’s it—but rather when to hide elements. And hiding an element that you want some users to see (or hear, or interact with in any other way) is just silly.

Development…

I tend to write code mostly for my own projects (at work, my job consists mostly of understanding third party code, suggesting implementation tactics and gathering requirements), so I get a reasonably free choice of operating systems and development environments.

My basic work environment looks like this (click to enlarge):

editor

This is an xterm running emacs through an SSH connection, showing JavaScript and PHP code for JITBrain in two buffers, with js2-mode, php-mode and global-font-lock-mode enabled. What is shown here is what my laptop screen is able to display—my actual workstation fills two 22″ screens with four buffers of code and a smaller font, and the transparent dark terminal background lets me look at a browser window behind the editor for quick reference.

Why?

The main reason is that I’m used to it. I’m so used to the emacs way of working with code that I actually do counter-productive things when I use other editors: I expect the tab key to move the code to its natural indentation, but most editors just insert a tab, and I routinely save my work with Ctrl-X Ctrl-S, which usually just cuts the text. I can of course get by these limitations (I used to work with Visual C++ a lot when I was younger) but I still don’t have the same training as other developers with other IDEs—except, for some reason, the Visual Studio debugger.

The second reason is that xterm-friendly editors are the only editors I can use on both windows and linux with the exact same configuration. When I’m on my laptop, I can just SSH to the appropriate server and start hacking away code. I guess I could use a Windows-based VPN and use a graphical IDE remotely, but the performance of that has been quite low.

The third reason is that emacs is designed to be used with only a keyboard. By contrast, it’s certainly possible to use Visual Studio or another graphical IDE with keyboard shortcuts alone, but doing so is an order of magnitude more annoying than the emacs equivalent. The most fundamental things I tend to do is open source files: this is fairly optimized for mouse users in graphical IDEs (open solution panel, double-click file) but navigating a file tree with only the keyboard is quite harder. The basic issue with the mouse is that I don’t have one—my laptop only has a touchpad and I don’t have the room to carry or use an additional mouse with me.

And before you point out that this is ultimately a known troll and religious war topic, this is more about my own habits than about whether these habits are better than others. Feel free to discuss your own inferior development environments below ;)

The Law

Many online communities follow an a posteriori moderation scheme to eliminate unwanted content. This improves participation, because anything is published immediately without prior authorization and therefore motivates contributors to contribute more. Besides, it also reduces the cost of moderation by letting the users themselves tag unwanted content for removal.

Of course, things can get nasty once a team decides to post a heap of porn videos to youtube (read the CNET article): an a posteriori moderation scheme involves keeping any content, no matter how controversial, online for everyone to view for at least a short while.

And things get even uglier when the community wants the content to stay online, but external forces move in to remove it: parents do not want their teenage children to view naughty videos, industry majors do not want their music to be distributed freely on BitTorrent, and your ex-boyfriend doesn’t want you to publish that picture of him picking his nose on facebook.

The technical question of tagging content for removal is pretty simple: if you have a central authority controlling the content distribution, create an API to mark some content to be reviewed and, if applicable, removed. If there’s no central authority, too bad.

The legal question, however, is somewhat more complex, and revolves around three questions:

  • How should the claimant request the removal of some content in a way that can be used as proof in court?
  • Under what circumstances should the community be forced to withdraw the content?
  • If the issue is taken to court, what charges can be upheld against the community and against the author?

This obviously depends on the country in which the community operates, since different countries are bound to have different laws.

In France, the main law on the subject is the LCEN—Loi pour la Confiance dans l’Economie Numerique, loosely translated as Law for Trust in the Digital Economy. It is quite restrictive.

First, whenever you use a public communication tool (such as a forum, a blog’s comments, or even your e-mail) you have to make your identity known to anyone reading your content. This means you have to provide your first and last name, home address and phone number. The penalty for giving out incorrect or incomplete information is up to one year in jail and a €75000 fine.

If you don’t want your public information to be freely available to everyone, you can provide all of that information to a service provider responsible for the technical infrastructure of your communication tool, and then provide the identity of that provider instead of yours. This is what happens when you send mail using a mail provider based in France: the provider knows who you are, and a court can find out who you are by tracking the e-mail back to its source and asking the provider.

So, what happens when you post a comment to my blog? Since I am based in France and am responsible for the technical infrastructure for publishing your comments, there are only two possibilities as far as the LCEN is concerned: either I am a mere hosting service, or I am the editor of your comment. The problem is that, as a hosting service, I am not allowed to edit the comments in any way, including for instance cropping out spam comments: everything published on the blog has to be posted as-is without my intervention.

Besides, as a hosting service, I am also required by law to ask you for your name, address and phone number, and I am pretty certain that you’re not going to give them to me. And even if you did, keeping that kind of information around means I have to sign up for a CNIL authorization (which is mandatory for keeping personal information) and must keep that information well-protected under penalty of one year in jail and a €15000 fine, and there’s no way I will risk a year in jail for such a silly reason.

So, I am an editor, and am therefore legally responsible for anything that gets published on my website, including comments from anonymous readers.

Now, do Facebook or Youtube behave as editors or hosting services with respect to French law? Not that it matters—the LCEN is only applicable when you actively set up shop in France to distribute content, not if you distribute content from outside the country.

HADOPI

The HADOPI law was recently adopted by the French parliament. I have an issue with this law: it deals with technical things that few people are knowledgeable in (including most members of parliament) such as the Internet Protocol and the use of IP addresses.

So, I have made a small effort on this website to explain the basic technical principles underlying the HADOPI law [fr].

Inline Help

Your average user does not know what a trackback is. Yet, WordPress must let experienced users ping trackbacks. How to include trackback information without scaring away the inexperienced users (and possibly even educating them along the way)?

The solution chosen by WordPress is to use slightly more verbosity to describe what trackbacks are:

wordpress-back

By contrast, Magento involves a lot more knowledge than just publishing a blog. While it’s possible to assume that Magento users earn their wages by knowing how to use it, most of the time they only manipulate the system as a side-effect of handling sales in their brick-and-mortar company, or they are new to sales altogether. So, the result is a complex product with outright terse field descriptions that have very complex effects:

magento-backWho, among normal Magento users, knows what a meta keyword or meta description is? Or whether meta keywords are as useful now as they were in the good old days? But that’s not very important, since you could just ignore those fields.

What’s an URL key? Now, even an experienced web developer might have trouble with this one (it’s the equivalent of a WordPress slug, except WordPress displays that “URL key” field as a more easily understood “Permalink: http://www.nicollet.net/2009/05/inline-help/” with the last URL segment editable).

What about the Page Title? What’s the difference between the category name and the page title? Which is displayed where?

Things get even more complex with other areas of Magento. For instance, in a lot of places a given field is disabled and a “Use Config Defaults” checkbox next to it is checked. The problem is that there is no indication about where those configuration defaults can be changed.

Last but not least, there are several classic questions to be asked, such as “Why does this product appear as out-of-stock?” or “Why doesn’t this product appear in this category?” or “How do I set a table rate?” which require careful analysis of the dozen options that might affect the actual state of the item (enabled? present in website? present in category? stock greater that zero? set as in-stock? children items enabled, present in website and set as in-stock? …)

Inline help items

Modern Javascript libraries allow altering an existing page in a non-intrusive manner by decorating the page elements once they are loaded (or when the user asks for help). This means it’s possible to add novice-specific inline help as:

  • Short text snippets under complex or technical items to explain what they are, possibly with a link to the complete explanation.
  • Explanatory tooltips on hovering.
  • See-also links (where do I change this configuration default? where do I set table rates?) placed exactly where the user might be wondering something.
  • Move-along tutorials that detect whether data was entered in certain fields and guide the user to create items, add them to categories, and so on…
  • Troubleshooting checklists (with links) to determine why a product does not appear, or why it appears out of stock.

In fact, it would even be possible for IT companies to provide their customers with customized help messages that match their specific internal processes.

Konami Code

A quick excerpt from the custom JavaScript on the jQuery main website:

// Hehe.
if ( window.addEventListener ) {
        var kkeys = [], konami = "38,38,40,40,37,39,37,39,66,65";
        window.addEventListener("keydown", function(e){
                kkeys.push( e.keyCode );
                if ( kkeys.toString().indexOf( konami ) >= 0 )
                        window.location = "http://ejohn.org/apps/hero/";
        }, true);
}

In practice, this means that if you press “↑↑↓↓←→←→BA” while on the jQuery page, you will be redirected to some kind of guitar hero game. It’s a bit sloppy, though: the kkeys array will increase in size with every keypress, which means the page will get slower and slower as you press keys. Nothing problematic, since nobody sane would be doing this anyway.

If you’re wondering, this sequence is the konami code. You can find more websites supporting it here:

http://www.konamicodesites.com/

The joys of JavaScript Scoping

The identifier strategy of Objective Caml is fairly simple: to find out what a given identifier references, one simply has to climb back up in the syntax tree until they encounter a binding expression that binds that identifier. There are many binding expressions, but all of them are explicit.

For types:

type identifier = ...
class type identifier = object ... end
class identifier = object ... end

For classes:

class identifier = object ... end

For modules:

module Identifier
functor(Identifier) = ...

For constructors:

type ... = Identifier of ... | ...

For values:

let pattern(identifier) = ...
object (identifier) ... end
object ... inherit ... as identifier ... end
match ... with pattern(identifier) -> ...
function pattern(identifier) -> ...

The scope of a binding expression is either “everything below” or “everything within a sub-expression” depending on the rule, both of which are usually implemented so that an identifier is only used after it’s defined (in terms of left-right, top-bottom reading of the source code) with the notable exception of mutually recursive constructs and inheritance.

JavaScript, being a dynamic language, takes a more dynamic approach to identifiers. Scopes are represented at runtime as objects, with variables being properties of the scope objects. Every line of code, when executed, has access to a stack of scope objects where it can look for a given identifier.

In practice, the scope rules are designed in a somewhat similar way to those of ML: when you define a variable with ‘var’, that variable is in scope until the end of the current lexical scope, and when a function is defined it carries with it a copy of the scope it was defined in (that is, a classic lexical closure). Two unusual things do happen:

First, the ‘this’ variable behaves in an unusual manner: unlike Objective Caml where ‘self’ (or whatever name you use) is just a normal identifier, ‘this’ is an implicit argument of every function. This can be unsettling at first glance, because functions will appear not to include ‘this’ in their lexical closure, but quite easy to understand once you see it as an additional, implicit argument. In essence, when you write “obj.func(arg)”, the function automatically gains the value of ‘obj’ as the value of “this”. When you write “new func(arg)”, the function automatically gains a brand new object as the value of “this”. In other situations, ‘this’ is the global scope object (whatever that means in a particular implementation).

Second, the global scope has unusual behavior: instead of being included as-is inside functions lexical closures, it is included as a reference. This means that if you add an identifier to the global scope, then any functions will see that idenfier, including those functions that were defined before it. The purpose of this is to implement mutually recursive functions (the other way to do so is to use object member functions).

CSS Strategery

How do you prevent CSS from becoming a mess? Here are some tasty bits from my own design strategy.

Nature

CSS is based on rules, used to select only certain elements in the document and apply effects to these elements. While the rules themselves have some small level of semantics applied to them, most of the time the actual meaning is provided by the author, which makes it essential to decide exactly how the semantics should be described.

Most rules deal with an object with a certain nature. At this most basic level, the nature is merely the element the rule is applied to. For instance, for div.header a:link {} the nature is “link”, and for p img {} the nature is “image”. Some rules have no nature: p * {} does apply to anything, and div {} doesn’t really specify what the semantic nature of the div is. Nature can be further described using a class or identifier: img#logo {} applies to the logo, p span.mailaddr {} applies to spans that contain mail addresses.

One way of doing bad CSS is relying too much on nature. It consists in giving almost every element in the tree a specific nature by means of classes or identifiers, and then individually applying a rule to every nature. The problem is that quite often the intended meaning is to have the same nature, but to exist in different context.

Context

For instance, is a link in a menu different from a link in the actual page contents? Both are links, the difference between them is not one of nature, but one of context. In a way, while the nature is everything tied to the last element in the rule, the context is everything else in that rule.

.header a:link {}
.contents a:link {}

Orange is context, blue is nature. Splitting selector parts between context and nature does not change the overall size of the rule selector: a.header:link is ultimately the same length as .header a:link. However, relying on context means the XHTML is simpler: instead of having to decorate every link with a class, you merely have to decorate those elements that contain only header links (which, quite surprisingly, is usually the “header” block itself).

By consequent, it is essential to move as much information as possible to the context, within reasonable limits. The real question is what these limits really are.

Defaults

To put it bluntly, there’s no reason to tag a paragraph in the news section as having class “news” if all paragraphs in the news section have class “news”. In general, if the majority of elements with a default XHTML semantic have the same semantic in your document in a certain context, then that should be made the default semantic for those elements within that context. So you can avoid writing horrible things like:

div.contents p.content_text em.content_text_emphasis {}

And instead use the more reasonable:

div.contents p em {}

The main benefit is not that your CSS is shorter, although that does happen as well, but that your XHTML document is shorter, since you don’t have to add classes to every element.

XSL comma removal

Since I wrote my article on arrays and  commas last week, my blog has received quite a lot of Google searches about how to remove the last comma when using an XSLT stylesheet, so it seems only fitting that I should explain this in more detail.

It is possible for an XSLT stylesheet to generate a comma-separated list from a node set. The basic idea is to place a comma before every element, except the first. In essence:

<xsl:for-each select="...">
  <xsl:if test="position() &gt; 1">, </xsl:if>
  ...
</xsl:for-each>

When processing a node set, the position() function indicates the index of the element within that node set. The first element has position 1.

This gets much harder if you have to further filter the elements in the node set before printing them, because the position doesn’t let you find out the first displayed element. In XSLT 2.0 you can generate a new list from the old list by filtering, then traverse the new list to turn into a comma-separated output. In XSLT 1.0 you will have to either do all the filtering as part of the XPath selector of your loop, or determine the position of the valid element beforehand.



1150 feed subscribers
(readers who polled a feed this week)