Search code examples
pythonrubymustachespecifications

Compute variable expressions in mustache templates: what should we get?


Given these hash and Mustache template:

Hash:

{
'a': 3
}

Template:

"This is a+2: {{a+2}}"

Ruby and Python give me different outputs:

  • In ruby, I get:

    /usr/lib/ruby/gems/3.0.0/gems/mustache-1.1.1/lib/mustache/parser.rb:286:in `error': Unclosed tag (Mustache::Parser::SyntaxError)
    Line 1
      {{a+2}}
    
  • In python, just empty string

Who is right? What result should we get in official mustache specification: empty string or error (or something else)? I don't know what the result is other programming languages.


Solution

  • Both are not wrong as they adhere to Mustache spec requirements (or lack thereof in this case).

    1. Mustache interpolation spec (v1.2.2) only restricts that:

    The tag's content MUST be a non-whitespace character sequence NOT containing the current closing delimiter.

    1. Mustache spec does not explicitly Define syntax of tag names (mustache/spec#67).

    The Ruby implementation mustache/mustache further constrains the tag name to:

    # The content allowed in a tag name.
    ALLOWED_CONTENT = /(\w|[?!\/.-])*/
    

    The Python implementation noahmorrison/chevron considers a+2 as the tag name:

    import chevron
    chevron.render("This is a+2: {{a+2}}", {'a+2': 3})
    # 'This is a+2: 3'
    

    Notably, the Python implementation is not defaulting a syntax error to an empty string.