Solving your Arabic problems using the new HTML bdi element

Let's assume that you are getting a list of book titles out of a database and you want to print them in a nice <ul>. Every book's title and number of reviews it has received. You will be doing something roughly similar to the following:

<html>  
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    </head>
<body>  
  <ul>
   ${ for book in books }
     <li>${book.title} - ${book.reviews_count} Review</li>
   ${ endfor }
  </ul>
</body>  
</html>  

Let's see what happens when you run this code and you get a list of books out of your database that contain some arabic book titles. You get a generated HTML that looks like the following, note that it's generated "correctly" even if you see the arabic title is swapped with the number in a funky way.

<html>  
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    </head>
<body>  
  <ul>
   <li>Peace and War - 10 Review</li>
   <li>كتاب مالوش اسم - 2 Reviews</li>
  </ul>
</body>  
</html>  

No BDI

Try to copy that to a text file, name it to "t1.html" and open in your browser. Funky?, This is exactly what is going to happen in production and that is/was the typical pain of a developer trying to mix Arabic words with English words in specific/most cases.

What actually happened is that the Bidi (Bidirectional) text-direction detection algorithm decided that the ("- 2") part written after the arabic book title are in the same direction, this means that it's written from right to left, but you actually mean the opposite, you mean that the book title is the only (right-to-left) element. So you basically need a way to isolate the arabic title in an isolated bidi context.

Thanks to the new HTML tag which isolates the bidi context for certain words. Try surrounding the book title with that...ex:

<html>  
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    </head>
<body>  
  <ul>
  ${ for book in books }
     <li><bdi>${book.title}</bdi> - ${book.reviews_count} Review</li>
   ${ endfor }
  </ul>
</body>  
</html>  

The generated output will look like:

<html>  
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    </head>
<body>  
  <ul>
   <li><bdi>Peace and War</bdi> - 10 Review</li>
   <li><bdi>كتاب مالوش اسم</bdi> - 2 Reviews</li>
  </ul>
</body>  
</html>  

With BDI

Neat!. Try that generated HTML in your browser and see the effect for yourself. I've been somehow involved in the incorporation of this tag into Firefox, but happily, it's also supported now on Google Chrome too.

comments powered by Disqus