a-h / templ

A language for writing HTML user interfaces in Go.
https://templ.guide/
MIT License
8.4k stars 277 forks source link

Parser chokes on "<" in if statements #930

Closed kalafut closed 2 months ago

kalafut commented 2 months ago

v0.2.778

Pretty straightforward:

// ✅
if i > 1 {
    foo
}

// ✅
if i == 1 {
    foo
}

// ❌ (compilation errors about unterminated if)
if i < 1 {
    foo
}

Putting the expression in parens doesn't help.

phenpessoa commented 2 months ago

I'm unable to reproduce. This compiles just fine for me:

package main

templ foo(x int) {
    if x < 1 {
        <div>
            a
        </div>
    }
    if x == 1 {
        <div>
            b
        </div>
    }
    if x > 1 {
        <div>
            c
        </div>
    }
}
kalafut commented 2 months ago

Strange. For that exact code I get:

parsing error: if: unterminated (missing closing '{\n') - https://templ.guide/syntax-and-usage/statements#incomplete-statements: line 3, col 0
kalafut commented 2 months ago

OK, false alarm. It looks like the LSP or formatter with VSCode got into a funky state. I realized it was formatting stuff on save into something like this, which is invalid syntax:

templ foo(x int) {
    if x < 1 {  <div>
            a
        </div>
    }

This weird formatting only showed up when I was using < 🤷‍♂️. A restart fixed it.

I'll keep an eye out for it this reoccurs, but I hadn't restarted VSCode in many days so I'm not terribly surprised nor concerned.

chama-chomo commented 2 weeks ago

Hello, apparently I experience the same issue here, restart doesn't help

image
a-h commented 2 weeks ago

I haven't tested this yet, but I assume that it works OK if you put the expected new lines in place?

templ Resolution(width int) {
  if width > 1900 && width < 3800 {
    "FHD"
  } else if width > 3800 {
    // etc.
  }
}
chama-chomo commented 2 weeks ago

thx, my formatter is just not satisfied whatever indentation I use and basically messes the code like I've shown in my previous post. I guess the problem will be on formatter side then.

EDIT: I got it working somehow and compiler doesn't complain, but the formatted code looks really strange

templ resolution(w int) {
if w < 3800 && w> 1080 {
  FHD
  } else if w > 3800 {
  UHD
  } else if w< 1900 && w> 1080 {
    HD
    } else {
    SD
    }
    }
a-h commented 2 weeks ago

That is very ugly indeed. As a temporary workaround, I'd suggest dropping into Go.

func resolution(w int) templ.Component {
  res := "SD"
  if w < 3800 && w> 1080 {
    res = "FHD"
  } else if w > 3800 {
    res = "UHD"
  } else if w< 1900 && w> 1080 {
    res = "HD"
  }
  return templ.Raw(res)
}

Or, if you prefer to separate into a utility function:

func resolutionName(w int) string {
  if w < 3800 && w> 1080 {
    return "FHD"
  } else if w > 3800 {
    return "UHD"
  } else if w< 1900 && w> 1080 {
    return "HD"
  }
  return "SD"
}

func resolution(w int) templ.Component {
  return templ.Raw(resolutionName(w))
}
chama-chomo commented 2 weeks ago

thanks!