Skip to content

Add ERB-like trim mode for tags and outputs#214

Closed
nickpearson wants to merge 2 commits intoShopify:masterfrom
nickpearson:trim-mode
Closed

Add ERB-like trim mode for tags and outputs#214
nickpearson wants to merge 2 commits intoShopify:masterfrom
nickpearson:trim-mode

Conversation

@nickpearson
Copy link
Copy Markdown
Contributor

This change adds support for ERB-like trimming to Liquid. Tags and outputs are supported, though they behave differently. In the descriptions below, "newline" means \n and/or \r (specifically, /\n?\r?/).

TAG BEHAVIOR

For any tag starting with {%-, as with any ERB segment starting with <%-, all tabs and spaces between the beginning of the line and the beginning of the tag will be removed.

For any tag ending with -%}, as with any ERB segment ending with -%>, the newline character immediately following the tag will be removed.

For example:

<p>
  {%- if true -%}
  hi
  {%- endif -%}
</p>

becomes:

<p>
  hi
</p>

Unlike ERB, this implementation for Liquid is more forgiving in that (a) it also removes any tabs and spaces that precede the newline character, and (b) it does not require a newline to be present.

OUTPUT BEHAVIOR

Trim mode for output segments behaves a little differently.

For any output starting with {{-, all tabs and spaces between the beginning of the line and the beginning of the output and the newline preceding it will be removed. (Tabs and spaces preceding the newline will not be removed.)

For any output ending with -}}, all tabs and spaces and the newline character immediately following the output and all tabs and spaces after the newline will be removed.

For example:

<p>
  {{- 'hi' -}}
</p>

becomes:

<p>hi</p>

NOTES

The beginning and ending trim modes can be used independently. For example, {%- if x %} or {{ x -}}.

The reason tabs and spaces preceding the newline in a {{- trim are not removed is so that whitespace between multiple output segments can be controlled. The reason tabs and spaces following a newline in a -}} trim are removed is so that indentation can be removed. For example, consider the following, where underscores are shown in the place of spaces:

<p>
__{{- 'abc' -}},_
__{{- 'def' -}}
</p>

becomes:

<p>abc,_def</p>

The space after the comma is kept, but the indentation spaces before 'abc' and 'def' are removed.

BENCHMARKS

Before:

Rehearsal ------------------------------------------------
parse:        12.130000   0.030000  12.160000 ( 12.167833)
parse & run:  28.780000   0.080000  28.860000 ( 28.874338)
-------------------------------------- total: 41.020000sec

                   user     system      total        real
parse:        12.350000   0.030000  12.380000 ( 12.386125)
parse & run:  28.630000   0.080000  28.710000 ( 28.722666)

After:

Rehearsal ------------------------------------------------
parse:        16.750000   0.040000  16.790000 ( 16.802643)
parse & run:  33.250000   0.080000  33.330000 ( 33.342917)
-------------------------------------- total: 50.120000sec

                   user     system      total        real
parse:        16.900000   0.050000  16.950000 ( 16.959132)
parse & run:  33.260000   0.100000  33.360000 ( 33.375376)

@fw42
Copy link
Copy Markdown
Contributor

fw42 commented Jun 21, 2013

Hm, that's kind of a big deal, performance-wise :-(

@nickpearson
Copy link
Copy Markdown
Contributor Author

If I remove support for output trimming ({{- x -}}), as well as the relaxed post--%} tab/space trimming, the numbers get a little bit better. I think it's the {%- if x -%} trimming people are wanting most anyway.

I reran the "before" so the two could be run back-to-back for a good comparison.

Before:

Rehearsal ------------------------------------------------
parse:        12.150000   0.040000  12.190000 ( 12.189427)
parse & run:  28.540000   0.070000  28.610000 ( 28.629135)
-------------------------------------- total: 40.800000sec

                   user     system      total        real
parse:        12.340000   0.040000  12.380000 ( 12.381043)
parse & run:  28.630000   0.070000  28.700000 ( 28.709242)

After:

Rehearsal ------------------------------------------------
parse:        15.140000   0.040000  15.180000 ( 15.188784)
parse & run:  31.510000   0.070000  31.580000 ( 31.599854)
-------------------------------------- total: 46.760000sec

                   user     system      total        real
parse:        15.320000   0.030000  15.350000 ( 15.359789)
parse & run:  31.550000   0.050000  31.600000 ( 31.615508)

I'll leave it to you on whether this is too big a performance hit for the functionality it provides. If so, maybe there's a way to easily and non-invasively make it opt-in configurable. Or maybe I could move the implementation so that the trimming happens before the parsing, though that seems much more prone to bugs.

@fw42
Copy link
Copy Markdown
Contributor

fw42 commented Jun 21, 2013

I like the feature in principle, but this is definitely too much of an impact and most of Shopify's users don't care about white space in their HTML. Making this opt-in sounds like a good compromise.

@nickpearson
Copy link
Copy Markdown
Contributor Author

I've reimplemented this by handling the trimming before the template is parsed. I'll submit a separate PR momentarily. I'm leaving this open for now in case we decide to come back to it and make it opt-in.

@fw42
Copy link
Copy Markdown
Contributor

fw42 commented Jul 3, 2013

See #215.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants