##
6.6 #filter

The template:

      #attr $ode = ">> Rubber Ducky, you're the one!  You make bathtime so much fun! <<"
      $ode
      #filter WebSafe
      $ode
      #filter MaxLen
      ${ode, maxlen=13}
      #filter None
      ${ode, maxlen=13}

The output:

      >> Rubber Ducky, you're the one!  You make bathtime so much fun! <<
      &gt;&gt; Rubber Ducky, you're the one!  You make bathtime so much fun! &lt;&lt;
      >> Rubber Duc
      >> Rubber Ducky, you're the one!  You make bathtime so much fun! <<

The `WebSafe` filter escapes characters that have a special meaning in HTML. The `MaxLen` filter chops off values at the specified length. `#filter None` returns to the default filter, which ignores the `maxlen` argument.

The generated code:

       1  write(filter(VFS(SL,"ode",1))) # generated from '$ode' at line 2, col 1.
       2  write('\n')
       3  filterName = 'WebSafe'
       4  if self._filters.has_key("WebSafe"):
       5      filter = self._currentFilter = self._filters[filterName]
       6  else:
       7      filter = self._currentFilter = \
       8                  self._filters[filterName] = getattr(self._filtersLib,
                             filterName)(self).filter
       9  write(filter(VFS(SL,"ode",1))) # generated from '$ode' at line 4, col 1.
      10  write('\n')
      11  filterName = 'MaxLen'
      12  if self._filters.has_key("MaxLen"):
      13      filter = self._currentFilter = self._filters[filterName]
      14  else:
      15      filter = self._currentFilter = \
      16                  self._filters[filterName] = getattr(self._filtersLib,
                             filterName)(self).filter
      17  write(filter(VFS(SL,"ode",1), maxlen=13)) # generated from
              #'${ode, maxlen=13}' at line 6, col 1.
      18  write('\n')
      19  filter = self._initialFilter
      20  write(filter(VFS(SL,"ode",1), maxlen=13)) # generated from
             #'${ode, maxlen=13}' at line 8, col 1.
      21  write('\n')

As we've seen many times, Cheetah wraps all placeholder lookups in a `filter` call. (This also applies to non-searchList lookups: local, global and builtin variables.) The `filter` ``function'' is actually an alias to the current filter object:

      filter = self._currentFilter

as set at the top of the main method. Here in lines 3-8 and 11-16 we see the filter being changed. Whoops, I lied. `filter` is not an alias to the filter object itself but to that object's `.filter` method. Line 19 switches back to the default filter.

In line 17 we see the `maxlen` argument being passed as a keyword argument to `filter` (not to `VFS`). In line 20 the same thing happens although the default filter ignores the argument.