The Art of zen-coding: Bringing Snippets to a New Level

Posted: August 17, 2009

If I had to single out one thing that most significantly changed the way I write markup, code, and style, it would without a doubt be snippets. To get even more specific, it would be the snippet implementation of TextMate. When I first saw the feature at work via screencast, I was literally flabbergasted. I can’t explain how much it changed the way I thought about writing code, productivity, and overall quality of work. I was currently running Linux at the time, so I spent day and night trying to find replicate functionality in a native editor for myself.

This was before the days of the Gedit implementation of snippets so I did my best to replicate TextMate in SciTE. It was awesome. Incorporating snippets changed the way I worked by orders of magnitude, and the implementation found in TextMate is the bar to which I compare every other editor I’ve tried.

What’s great is that snippets seem to have hit the mainstream. Besides OS X specific editors such as Panic’s Coda and MacRabbit’s Espresso, platform independent editors and IDEs have their own implementations as well. Apart from E TextEditor on Windows, however, I haven’t seen an editor implement snippets to the full effect of TextMate.

The big deal about snippets

The deciding factor for me is the ability to have multiple stops per snippet. This gives you the ability to not only share snippets (through Bundles or otherwise) but also very easily write your own. Every designer/developer has his or her own set of tricks, and a generic bundle isn’t going to cover you 100%. The great thing about a solid implementation of snippets puts the power in your hand to finish the job and add the final touch of customization you need.

I’m always on the hunt for a newer, better editor. It’s a curse I’ve had for years and one that will never go away. To be brutally honest, snippets are the only thing holding me to TextMate at this point, as there are a number of strong contenders on the market now, targeted specifically toward Web developers. They’re also gorgeous to boot.

I was to the point where I was simply waiting for the various editors to publish a few dot releases including a solid snippets implementation a la TextMate. That is until I discovered zen-coding. My mind was blown all over again.

zen-coding takes snippets to a new level

zen-coding touts itself as a “set of plugins for HTML and CSS hi-speed coding” and my gosh it lives up to the name. The snippets implementation provided by zen-coding are based on specification drafts, and a heck of a lot has been included by default.

Instead of going over the documentation here, I’d just like to call a bit of attention to the HTML selectors linked above. This is truly what made my jaw drop.

The biggest calling point for zen-coding for me is its implementation of HTML selectors as snippet triggers. zen-coding includes an entirely new angle to writing markup, and it facilitates the feature by letting you write HTML based on CSS selectors. It’s so simple it’s confusing at first. I think it’s best explained by doing a quick before and after. If you were to type:

div#name.one.two

and follow that with the zen-coding plugin keystroke (CMD+E in TextMate), the plugin will reformat the line as:

<div id="name" class="one two"></div>

Let’s get a bit more advanced, typing:

ul#name>li.item

will result in:

<ul id="name">
    <li class="item"></li>
</ul>

Last, but not least:

p.one+p.two

will result in:

<p class="one"></p>
<p class="two"></p>

It doesn’t stop there. zen-coding has included an even more elaborate set of possibilities on top of valid CSS selectors.

Element multiplication and variables

A really fascinating feature of the CSS selector abilities comes from element multiplication. Perhaps one of the most tedious things to mark up (when not working from existing copy) is a list (or eight). zen-coding does its part to lighten the load, quite a bit:

ul#name>li.item*3

provides:

<ul id="name">
    <li class="item"></li>
    <li class="item"></li>
    <li class="item"></li>
</ul>

By including a multiplication modifier, you can control how many child elements are included in the snippet!

The other really interesting implementation deals with variables in snippet output, which is neat:

select>option#item-$*3

gives you:

<select>
    <option id="item-1"></option>
    <option id="item-2"></option>
    <option id="item-3"></option>
</select>

By including the dollar sign, you can include a reference to the index of the element you’re multiplying. Although really specific, it could (and probably will) come in very handy from time to time.

I mean if you’re not impressed yet, I just give up!

See it in action

There are a few screencasts referenced on the Google Code page for zen-coding which illustrate the above really well:

Definitely check them out if my explanation is still a bit foggy, as the screencast really helps display what this plugin is capable of.

Compatibility

One of the finer points of zen-coding is the fact that the developer(s) are taking the time and effort to publish this genius for multiple editors both for OS X and cross-platform. Currently, according to the Google Code page, the plugin has versions for:

Unfortunately, I didn’t find a download link to the Espresso Sugar, but I will keep my eyes open for that as well. Update: the lead developer, in his comment below, let us know that the Sugar is included by default in Espresso releases. I’ve checked out the plugin both in TextMate and Coda and I can say that this plugin alone makes Coda a true contender for more advanced developers looking for a better implementation of Clips (until Coda natively supports snippets (fingers crossed for 2.0 bigtime)).

Note: to fully install in TextMate, you’ll need to download three bundles. At the time of this writing, the three download links are titled as:

  • Zen.Coding-TextMate.v0.3.zip (implements zen-coding)
  • TextMate.Zen.HTML.1.3.zip (implements HTML functionality)
  • TextMate.Zen.CSS.1.3.zip (implements CSS functionality)

Be sure to install each bundle you need!

Non OS X users may find a bit of luck in that the plugin is released for both Aptana and NetBeans, two very popular IDEs as of late. Windows users should be able to use the TextMate bundles in E as you’re accustomed. While there is definitely activity on the Google Code page, I’m not positive that other editors will be supported in future releases.

I love Web design.

This is the line of thinking that really gets me excited about what I do. zen-coding has again completely changed the way I approach writing code, and has raised the bar to a new height. What else is great is that this functionality was provided out of someone else’s love for the industry as well. Their great idea is now making my life even easier, and that cycle will definitely continue in the Web design community.

Comments

  1. I had glanced at the Zen Coding bundles a bit when you had posted about them on Twitter but didn’t download them yet. I had just read through the selectors but didn’t realize how advanced they really were to be able to take multiple classes or define a specific number of elements. Very cool. Downloading now.

  2. I’m glad you like my idea 🙂 If you really intersted, you can take part in development or writing documentation.

    BWY, Espresso Sugar is included in latest releases of Espresso.

  3. @afruit: I believe there may be issue with the plugin in the latest version of Espresso. I remember stumbling across the functionality in a dot release previous to the current version and it blowing me away then, but I had no idea it was zen-coding under the hood. Unfortunately as soon as I upgraded Espresso, it was gone! Rumor has it MacRabbit is back hard at work on the app, so hopefully we’ll see a new dot release soon with a working version of zen-coding!

  4. Cool. I’ve reinstated my status as “No So Dumb”.

    And I did note a bit of a manifesto MacRabbit posted on their blog not to long ago about how, they plan on picking up the slack. Read it Here.

    Personally, I”m a convert from Coda. Expresso just seems “lighter” when I’m using it. (I am on an old PPC G5 though).

  5. Thanks for this, I installed this and had fun with it. I just have to get used to using the ‘control’ key. It’s just so small and in an awkward spot.

  6. Thank you this is amazing. It’s working in Espresso for me but not fully (the shortcut is control + , ).
    This works: div#name.one.two
    This doesn’t: ul#name>li.item*3

  7. For those having trouble finding zen-coding in Espresso, it’s included with the TEA for Espresso sugar, and you can find the command for expanding zen coding abbreviations under Actions->HTML->Expand Abbreviation. The shortcut is control-, (control-comma).

    FYI, I’m the developer of TEA for Espresso and responsible for keeping things like zen coding up and running correctly. If you are having trouble with it, can you please report the problem either in the Espresso forums or the TEA for Espresso GitHub issues page? Thanks!

    http://github.com/onecrayon/tea-for-espresso/issues

  8. @leo: Yes, the TextMate bundles will work in E

    @Ian Beck: Ah ha! I didn’t realize that zen-coding was actually a part of TEA (as opposed to a standalone Sugar) – thanks for the clarification!

  9. Well Jon, you were right. Love it!

    I’ve been working with my head down for the past few weeks and while I saw mention of “zen coding” on Twitter, I never followed through.

    I too shed a tear when I discovered the glory of tab-triggered snippets in TextMate and have sworn by it ever since. zen-coding appears to take that to the next level, and I’m all for that shit!

    You know, I’ve been using CSSEdit since I switched to Mac nearly 3 years ago, but I still find CSS tedious to write. I’m going to have to try it out in TextMate with the zen-coding bundle installed. It might just be enough to make me abandon that app all together if it significantly speeds things up.

    Thanks for taking the time to write out some examples. Just what I needed to get a quick understanding of this hotness.

  10. Thanks for the hint on paths. I just started love this plugin.

    div#wrap>div#header+div#content+div#footer

    🙂

  11. @Matt Brett: Zen coding is an amazing kick in the pants for HTML, but I haven’t found it much use when doing CSS simply because of the sheer number of specific abbreviations. HTML is easy because you just need to know patterns, but zen coding’s CSS is a bit more overwhelming. CSSEdit is still quickest for me just because its auto-complete is a lot more intelligent than any other solution I’ve found (I particularly love the ability to advance into completions by typing hyphen or colon).

    I imagine if you put in the effort to learn zen coding’s abbreviations it would be more efficient than CSSEdit’s auto-complete. Too much trouble for me, personally.

  12. Just a heads up. I tried installing the Zen-HTML bundle for the e Text Editor in Windows and it doesn’t work. Troubleshooting why it isnt working lead me to the actual compressed file, where it the snippet file names have illegal characters in them (*, :, and others).

    As a result, some of the snippets work, but the more meaningful ones like html:xxx (where xxx is the type of document you’re trying to create) don’t exist because they are not being copied to the file system. Just wanted people to know in case they were having problems getting this package installed on e.

  13. Just a follow-up on the Windows installation, unpacking the files with 7Zip worked. 7Zip strips the illegal Windows file name characters but the it has full functionality.

    I originally unpacked the files with WinRAR, which did not handle the characters gracefully at all, picking and choosing what files it wanted to save and what the file name actually was. I was running an older version so I tried running an evaluation of the latest version and it behaved WORSE than the older version. Just a word of caution for anyone attempting to install this in a Windows environment.

  14. Yes, tab-triggers don’t seem to work for Zen-Coding snippets (eg “input:hidden” or “html:xs”) in Espresso, unlike Textmate. Sigh!

  15. I can’t seem to get this working in TextMate. The CMD+E doesn’t do anything and I’m not sure how to check what the default key combo is set to. The bundle is installed and if I enter div and hit TAB a menu appears asking me to choose the HTML snippet or the ZEN-HTML snippet. However, something like div#mydiv>span.theclass produces nothing when I hit tab or CMD+E. Any ideas? I’d love to get this working. Looks really amazing!

  16. @Simon: It looks like you may have installed TextMate.Zen.HTML.1.3.1.zip only. That will only get you the various tab triggers (and also that redundant menu every time you fire a tab trigger (the default HTML and zen use many of the same)). You’ll want to install Zen.Coding-TextMate.v0.3.zip to get the truly impressive expansion as outlined in the article above. To fire the triggers you’ll need to remember to hit CMD+e (instead of tab) as well. Good luck!

  17. This is neat but I must say the screencast you link to have nothing that Intype can do. Intype is a windows super light text editor that has awesome snippets straight from the install. Looking to read more about this though 🙂

  18. Very handy. Thanks a lot.

    Unfortunately I’m using E – TextEditor and it doesn’t work 100% – e.g. “d:ib” results in “display:inline”, “bg+” in “bacground:” etc. (by using ctrl+e)

    Though it looks just great.

  19. I do believe I’ve turned a corner and OMG another new awesome Mac App, and I’m an old Macster. Thanks for sharing. Any plans for an occasional tip and/or technique post (with eg’s) in your future? I may just have to shelve my old friend BBEdit. I’ve been after them for a while now trying to get them to implement RSS feed syntax, and newer CSS. This is a tasty morsel indeed!
    Thank You!

  20. Anyone know why I’m getting this error when using the expand command?:

    Traceback (most recent call last):
    File “/tmp/temp_textmate.vWAopj”, line 37, in
    result = cur_line[0:start_index] + zen_core.expand_abbr(abbr, doc_type)
    File “/Users/petelove/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/zen_core.py”, line 172, in expand_abbr
    tree = parse_into_tree(abbr, doc_type)
    File “/Users/petelove/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/zen_core.py”, line 104, in parse_into_tree
    root = Tag(”, 1, doc_type)
    File “/Users/petelove/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/zen_core.py”, line 192, in __init__
    self.name = Tag.get_real_name(name, doc_type)
    File “/Users/petelove/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/zen_core.py”, line 219, in get_real_name
    if zen_settings[doc_type].has_key(‘aliases’):
    AttributeError: ‘dict’ object has no attribute ‘has_key’

    I’m trying to run on TextMate Tiger OS X, I upgraded to python version 3.1

  21. It seems great. How can I install this plugin in windows netbeansIDE 6.5. I downloaded the package but I can’t understand how to install it. there is two xml file but i can’t figure it out what to do? If you can help me on this it will be great helpful. thanks in advance..

  22. @Pete in TextMate 1.5.8 under 10.4, I get this after pushing command + E to expand “div.navi”

    Traceback (most recent call last):
    File “/tmp/temp_textmate.GcqVGP”, line 9, in ?
    from zencoding import zen_core
    File “/Users/me/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/zen_core.py”, line 208
    @staticmethod
    ^
    SyntaxError: invalid syntax

  23. I am struggling to find where to download this for CODA? The only mention on the google code page is a link to coda? Which package do I download?
    Thanks

  24. Sweet stuff Jonathan, I watched one of the screen casts the other day but haven’t had a chance to work with it yet. Would be nice if someone created a snippet library of zen-coding snippets and allowed us to extend it ..

  25. Bummer! no RubyMine support.
    I do wish that the dev team at JetBrains would add this support.

  26. I installed the three bundle for textMate but when i writ e an abbreviation and hit cmf+e i get an error message:

    Traceback (most recent call last):
    File “/Users/zapata/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/expand_abbreviation.py”, line 7, in ?
    from zencoding import zen_core
    File “/Users/zapata/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/zen_core.py”, line 390
    return text[start_index] if start_index != -1 else ”
    ^
    SyntaxError: invalid syntax

    video looks lovely i’d love to try it 🙁

  27. Just trying to get this working highlights inconsistency all over the place! Some downloads are marked as deprecated, finding the right ones is confusing as some of the Google code links go to pages that state that Zen Coding for Coda is discontinued, Tea for Coda is now a Github project, there’s no mention of the various shortcut commands in the readme files (ctrl+E and various other attempts do nothing in Coda), and (finally) installing to TextMate on Tiger 10.4 (where is the ‘minimum system requirements’ info??) yields a similar Python invalid syntax error as Pete and Yannick:

    Traceback (most recent call last):
    File “/Users/deveritt/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/expand_abbreviation.py”, line 7, in ?
    import zencoding
    File “/Users/deveritt/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/__init__.py”, line 1, in ?
    import utils
    File “/Users/deveritt/Library/Application Support/TextMate/Pristine Copy/Bundles/Zen Coding.tmbundle/Support/zencoding/utils.py”, line 71
    return text[pos] if pos < len(text) else ''
    ^
    SyntaxError: invalid syntax

    Not happy!! It's a mess. Can someone please put up a definitive guide that overrides all the dead links, deprecated files, and broken code?

Leave a Reply

Your email address will not be published. Required fields are marked *