soasme / nim-mustache

Mustache in Nim

Home Page:https://mustache.github.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

different formatting (missing newlines) when using partials

pietroppeter opened this issue · comments

the following example is taken from mustache documentation where it says:

For example, this template and partial: [...] Can be thought of as a single, expanded template: [...]

As example below shows, currently we would have different output (the version using the partial is missing newlines).

I cannot find a reference in mustache documentation to rules about indentation and newlines but there is a test in specs that seems to cover similar stuff (partials.yml). I see that in the tests here there is the corresponding partials.json and I checked that it tests correctly. So maybe this is a different test case not covered by specs?

Or maybe I am making some silly mistake and this is not an issue at all...

Incidentally I found out that there is a test failing (in test_parser a newline is lost, see below for details).

Note that I am running all of this in windows (nim 1.4)

example

base.mustache:

<h2>Names</h2>
{{#names}}
  {{> user}}
{{/names}}

user.mustache:

<strong>{{name}}</strong>

single.mustache:

<h2>Names</h2>
{{#names}}
  <strong>{{name}}</strong>
{{/names}}

example.nim:

import mustache, json

var c = newContext()
c["names"] = %* [{"name": "soasme"}, {"name": "iffy"}, {"name": "pietroppeter"}]

echo "---base:\n", "{{> base}}".render(c), "\n---"
echo "---single:\n", "{{> single}}".render(c), "\n---"

output:

nim r example:

---base:
<h2>Names</h2>
  <strong>soasme</strong>  <strong>iffy</strong>  <strong>pietroppeter</strong>
---
---single:
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

---

expected output

I would expect the formatting to be the same.

failing test

nim r tests\test_parser

[...]
mustache\tests\test_parser.nim(140, 20): Check failed: s.render(c) == "Shown\n"
s.render(c) was Shown

[FAILED] render partial

nim version

nim --version

Nim Compiler Version 1.4.0 [Windows: amd64]
Compiled at 2020-10-16
Copyright (c) 2006-2020 by Andreas Rumpf

active boot switches: -d:release
commented

@pietroppeter regarding the example you provided, whether having a trailing newline at the end of user.mustache will have a different result.

$ echo -n '<strong>{{name}}</strong>' > user.mustache
$ nim r example.nim
---base:
<h2>Names</h2>
  <strong>soasme</strong>  <strong>iffy</strong>  <strong>pietroppeter</strong>
---
---single:
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

---

$ echo '<strong>{{name}}</strong>' > user.mustache
$ nim r example.nim
---base:
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

---
---single:
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

---

Could you please also explain how you run the test? The travis build log shows no failed test case in test_parser.

Regarding the failing test, I am testing on windows (as shown by output of nim --version above) and the reason it fails (I found out today) it is because \n is not a platform independent newline (see nim-lang/Nim#7089). If you replace "Shown\n" with "Shown\p" the test works fine on windows (and I tested on Linux through WSL and it also works fine there).

Btw the main issue reported is not related to this failing test, it is not a big issue (it does not change meaning for html files) but I thought it was worth mentioning it.

You might want also to remove label enhancements (I think it was applied by mistake).

Note that now since we have in-memory partials the issue can be reproduced also by this test (you need to add json to imports):

test "single vs composed template":
  let
    single = "{{> single}}"
    composed = "{{> base}}"
    partials = {
      "single": """<h2>Names</h2>
{{#names}}
  <strong>{{name}}</strong>
{{/names}}""",
      "base": """<h2>Names</h2>
{{#names}}
  {{> user}}
{{/names}}""",
      "user": "<strong>{{name}}</strong>"
    }.toTable()
  var c = newContext(partials = partials)
  
  c["names"] = %* [{"name": "soasme"}, {"name": "iffy"}, {"name": "pietroppeter"}]
  check single.render(c) == composed.render(c)

output:

Check failed: single.render(c) == composed.render(c)
single.render(c) was <h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

composed.render(c) was <h2>Names</h2>
  <strong>soasme</strong>  <strong>iffy</strong>  <strong>pietroppeter</strong>
commented

@pietroppeter given the test case single vs composed template, I think that's what I'd expect.

In fact, I ran a similar test in mustache/mustache and the behavior is the same.

$ cat test.rb
require 'mustache'

class Base < Mustache
  def names
    [{name: "soasme"}, {name: "iffy"}, {name: "pietroppeter"}]
  end
end

Base.template = <<EOF
<h2>Names</h2>
{{#names}}
  {{> user}}
{{/names}}
EOF

puts Base.render

Base.template = <<EOF
<h2>Names</h2>
{{#names}}
  <strong>{{name}}</strong>
{{/names}}
EOF

puts Base.render

$ echo -n '<strong>{{name}}</strong>' > user.mustache
$ bundle exec ruby test.rb
<h2>Names</h2>
  <strong>soasme</strong>  <strong>iffy</strong>  <strong>pietroppeter</strong>
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

$ echo '<strong>{{name}}</strong>' > user.mustache
$ bundle exec ruby test.rb
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>
<h2>Names</h2>
  <strong>soasme</strong>
  <strong>iffy</strong>
  <strong>pietroppeter</strong>

Thanks, that makes perfect sense now, the reported behaviour is indeed correct! If I want the composed version to have newlines it should have them in the partial (i.e. "user": "<strong>{{name}}</strong>\n").