21

How would I format HAML to output a style similar to the conditional HTML tags used for cross-browser targeting?

<!doctype html>
<!--[if lt IE 8]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if IE 9]>    <html class="no-js ie9 oldie" lang="en"> <![endif]-->
<!--[if gt IE 9]><!--> <html class="no-js" lang="en"> <!--<![endif]-->

If I add a conditional, it wraps entire page in the conditional as well. I thought about using HAML's :plain filter at the top and manually adding </html> at the bottom, but this seems less than ideal to me.

typeoneerror
  • 55,990
  • 32
  • 132
  • 223

2 Answers2

44

The first three of these are pretty simple, as they are just plain HTML comments and you can use the Haml support for conditional comments:

/[if lt IE 8] <html class="no-js ie7 oldie" lang="en">
/[if IE 8] <html class="no-js ie8 oldie" lang="en">
/[if IE 9] <html class="no-js ie9 oldie" lang="en">

The last one is a bit different. Breaking it down, what you want is two comments surrounding the html opening tag, so the second comment is the first content of the html element. Also you can’t use the Haml syntax for conditional comments, you’ll have to use a literal comment. In Haml this would look like:

<!--[if gt IE 9]><!-->
%html{:class => 'no-js', :lang => 'en'}
  <!--<![endif]-->

This will produce HTML like this:

<!--[if gt IE 9]><!-->
<html class='no-js' lang='en'>
  <!--<![endif]-->

If you wanted you could use the whitespace removal syntax to make the generated HTML more like your example:

<!--[if gt IE 9]><!-->
%html{:class => 'no-js', :lang => 'en'}<>
  <!--<![endif]-->

Putting it all together:

!!!
/[if lt IE 8] <html class="no-js ie7 oldie" lang="en">
/[if IE 8] <html class="no-js ie8 oldie" lang="en">
/[if IE 9] <html class="no-js ie9 oldie" lang="en">
<!--[if gt IE 9]><!-->
%html{:class => 'no-js', :lang => 'en'}<>
  <!--<![endif]-->
  content here

which produces:

<!DOCTYPE html>
<!--[if lt IE 8]> <html class="no-js ie7 oldie" lang="en"> <![endif]-->
<!--[if IE 8]> <html class="no-js ie8 oldie" lang="en"> <![endif]-->
<!--[if IE 9]> <html class="no-js ie9 oldie" lang="en"> <![endif]-->
<!--[if gt IE 9]><!--><html class='no-js' lang='en'><!--<![endif]-->
content here</html>

An alternative technique would be to use Haml’s surround helper:

= surround "<!--[if gt IE 9]><!--><html class='no-js' lang='en'><!--<![endif]-->", "</html>" do
  content here
Community
  • 1
  • 1
matt
  • 78,533
  • 8
  • 163
  • 197
  • 1
    wonderful answer. props for the surround alternative as well. – typeoneerror Oct 15 '12 at 21:44
  • @matt Shouldn't that last bit be: ``? – Noz Jul 18 '13 at 00:10
  • 2
    @nozpheratu Do you mean should it have `!(IE)` part? Not necessarily – non IE browsers will ignore the condition anyway and render the content, and IE browsers will be covered by the existing clause. You could add it for documentation I suppose. – matt Jul 18 '13 at 12:30
2
<!doctype html>
/[if lt IE 8] <html class="no-js ie7 oldie" lang="en">
/[if IE 8] <html class="no-js ie8 oldie" lang="en">
/[if IE 9] <html class="no-js ie9 oldie" lang="en">
/ [if gt IE 9]><!
%html.no-js{:lang => "en"}
  / <![endif]
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
  • pretty close! though the last line is a bit different. will probably still work though? – typeoneerror Oct 13 '12 at 02:30
  • Tested; the result is exactly the same as the HTML you wanted (except obviously the s are not aligned; no biggie) and it has the upside of syntax consistency. If you use Sublime Text, you will definitely want the HTML2Haml plugin - it parsed my whole layout page perfectly, including this exact example you wanted (I, too, was using Boilerplate). For a web version, http://html2haml.heroku.com/ – iono Nov 16 '12 at 04:10