My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
Filters  
What are filters and how they can be used
Updated Feb 17, 2010 by serge....@gmail.com

Zen Coding v0.6 introduces a new concept called filters. Filters are special post-processors that modifies expanded abbreviation right before output to the editor. To better understand how filters works, let's walk through a simple tutorial.

Go to demo page and try to expand the following abbreviation: div#content>p.title. As you may expect, it will be expanded into the following HTML code:

<div id="content">
	<p class="title"></p>
</div>

Now, try to expand this abbreviation: div#content>p.title|e. You'll have a slightly different result:

&lt;div id="content"&gt;
	&lt;p class="title"&gt;&lt;/p&gt;
&lt;/div&gt;

We've just applied "e" (escape) filter by appending its name after pipe character. This filter escaped all XML-unsafe symbols with entities right before ZC sent output to the editor. Now, try this one: div#content>p.title|e|e:

&amp;lt;div id="content"&amp;gt;
	&amp;lt;p class="title"&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;

We have a double-escaped code (e.g. we applied "e" filter twice). As you can see, we can apply as many filters to abbreviation as we want, and as many times as we want.

Let's do something more interesting. Try to expand this abbreviation: div#content>p.title|haml

#content
	%p.title

Isn't it nice? We've just expanded abbreviation as a HAML template!

As you can see, filtering is a key concept of Zen Coding v0.6. They can anything: from small tweaks as placing whitespace after CSS-rule to more complex tasks as outputting result in different syntax. Even HTML output is defined as html filter.

Implicit filter call

You can apply filter to abbreviation explicitly, by adding pipe character and its name right after abbreviation. But filters also can be applied implicitly, depending on document type you're currently edit. You don't want to append |haml every time you expand abbreviation in HAML document, right?

Default filters are defined in zen_settings.js (or .py) file in filters section of each syntax:

zen_settings = {
	...
	'html': {
		...
		'filters': 'html'
	}
}

If there's no such section, html filter is applied by default. If you want to apply more than one filter by default, you can write a comma- or pipe-separated list of filter names in filters section:

zen_settings = {
	...
	'html': {
		...
		'filters': 'html, e'
	}
}

Now, every time you expand abbreviation in HTML document, html and e filters will be applied by default.

But be careful! You always have to place one of the syntax filter—html or haml—at first place of default filters in zen_settings file, otherwise you'll have empty output because syntax filters are defining primary output result.

List of available filters

haml

HAML syntax filter: output abbreviation as HAML template. Applies by default for HAML files.

html

HTML syntax filter: output abbreviation as HTML tags. Applies by default everywhere except HAML files.

e

Escapes XML-unsafe characters: <, > and &.

For example, div#header|e will be expanded into &lt;div id="header"&gt;&lt;/div&gt;. This filters will be extremely useful for tech bloggers/writers who wants to show code snippets on website (if you add Zen Coding support into you CMS, of course).

c

Add comments around important tags. Important tags are those tags with ID and/or CLASS attribute.

div>div#page>p.title+p|c

will be expanded into

<div>
	<!-- #page -->
	<div id="page">
		<!-- .title -->
		<p class="title"></p>
		<!-- /.title -->
		<p></p>
	</div>
	<!-- /#page -->
</div>

fc

Format CSS rule: add whitespace after CSS property name.

fl:l|fc

will be expanded into

float: left;

If you prefer this coding style, you'll definitely want to modify zen_settings file and add this filter as default one for CSS syntax. But remember: you should add html filter first:

zen_settings = {
	...
	'css': {
		...
		'filters': 'html, fc'
	}
}

xsl

This filter removes select attribute from <xsl:variable> and <xsl:with-param> tags if they have child nodes. For example:

ap>wp

will be expanded into

<xsl:apply-templates select="" mode="">
	<xsl:with-param name="" select=""/>
</xsl:apply-templates>

...but

ap>wp>call

will be expanded into

<xsl:apply-templates select="" mode="">
	<xsl:with-param name="">
		<xsl:call-template name=""/>
	</xsl:with-param>
</xsl:apply-templates>

Applies by default in XSL files.

Comment by yveli...@gmail.com, Feb 17, 2010

Nice filter with "c" - comments

Comment by DarrochR...@gmail.com, Feb 18, 2010

Any chance you could explain how to edit the comment filter so that it only provides the comments to elements that contain id's? Does anyone else want comments wrapping each class?

Comment by project member serge....@gmail.com, Feb 19, 2010

Find and edit filters/comment.js (of .py) file for you editor's plugin.

Comment by DarrochR...@gmail.com, Feb 21, 2010

Job done. Many thanks Serge :-)

Comment by Dowl...@gmail.com, Mar 9, 2010

I like filter "|c"

Comment by gtruf...@gmail.com, Mar 10, 2010

@Darroch:

As serge said Find and edit filters/comment.js (of .py) file for you editor's plugin.

Or the addComments function and remove references to the class attribute as below:

function addComments(node, i) {
		var id_attr = node.getAttribute('id'),
			//class_attr = node.getAttribute('class'),
			nl = zen_coding.getNewline();
			
		if (id_attr /*|| class_attr*/) {
			var comment_str = '',
				padding = (node.parent) ? node.parent.padding : '';
			if (id_attr) comment_str += '#' + id_attr;
			//if (class_attr) comment_str += '.' + class_attr;
			
			node.start = node.start.replace(/</, '<!-- ' + comment_str + ' -->' + nl + padding + '<');
			node.end = node.end.replace(/>/, '>' + nl + padding + '<!-- /' + comment_str + ' -->');
			
			// replace counters
			node.start = zen_coding.replaceCounter(node.start, i + 1);
			node.end = zen_coding.replaceCounter(node.end, i + 1);
		}
Comment by iae...@gmail.com, Mar 26, 2010

Is it possible to add the ending comment inline and not on new line? Example:

<!-- #myid -->
<div id="myid">
   content
</div> <!-- /#myid-->
Comment by project member serge....@gmail.com, Mar 26, 2010

You can modify filters/comment.py (or .js) for your editor

Comment by ari.rose...@gmail.com, Mar 30, 2010

I am using text wrangler. i know it was built separately, but is there a way to add filters? I doesn't seem to be working as described. and the files relating to comments don't seem to be included in the scripts?

Comment by angelw...@gmail.com, Mar 31, 2010

@ari.rosenbaum, the Zen Coding scripts for TextWrangler?/BBEdit (I'm the developer for those) do not have the 0.6 engine, so filters are not implemented as well as any other new features that 0.6 introduced.

Comment by simon.ma...@directbox.com, Jul 7, 2010

I'm using zencoding with gedit (Mike Crittenden's plugin) and if i enable the comment-filter by default, it will break my default ZC-behaviour. Example: abbreviations as "html:5" or any other abbreviation with a colon will not be expanded anymore. Additionaly, if I disable class-commenting as suggested earlier, abbreviations as div.demo will not be expanded either?

Anybody with similar problems? Any suggestions?

Comment by billbo...@gmail.com, Aug 22, 2010

i made it #a.b|c expands to <div id="a" class="b"> </div><!-- end a --> this is what i did,

function addComments(node, i) {
var id_attr = node.getAttribute('id'),
//removed by devric class_attr = node.getAttribute('class'), nl = zen_coding.getNewline();

if (id_attr || class_attr) {
var comment_str = '',
padding = (node.parent) ? node.parent.padding : '';
if (id_attr) comment_str += id_attr; //original if (id_attr) comment_str += '#' + id_attr; //removed by devric- if (class_attr) comment_str += '.' + class_attr;
//removed by devric- node.start = node.start.replace(/</, '<!-- ' + comment_str + ' -->' + nl + padding + '<'); node.end = node.end.replace(/>/, '>' + padding + '<!-- end ' + comment_str + ' -->'); //remove nl + before + nl + padding
// replace counters //removed by devric- node.start = zen_coding.replaceCounter(node.start, i + 1); node.end = zen_coding.replaceCounter(node.end, i + 1);
}
}

Comment by vishu.un...@gmail.com, Oct 28, 2010

the entire concept of zen-coding is phenomenal, love the |c filter btw :)

Comment by oncem...@gmail.com, Nov 3, 2010

I set the css to filters': 'html, fc now when I expand a css property with returns the following

margin-left: {%::zen-caret: :%};
Comment by project member serge....@gmail.com, Nov 4, 2010

In which editor?

Comment by oncem...@gmail.com, Nov 5, 2010

Espresso

Comment by *matt.me...@methodologie.com, Dec 24, 2010

I have the same issue in Textmate when I set the default css filters to html, fc.


Sign in to add a comment
Powered by Google Project Hosting