Open farhank3389 opened 1 month ago
There is some documentation on passing server side data to client scripts:
I also use a slightly different pattern on occasion, but tbh I'm not too happy with either way of doing it and much preferred the now deprecated script templates (https://templ.guide/syntax-and-usage/script-templates#script-templates):
templ test(teststring string) {
<script teststring={teststring}>
const teststring=document.currentScript.getAttribute("teststring");
console.log({ "the value of teststring is " + teststring });
</script>
}
ah yeah that does look like what I need. And agreed, I prefer the script
template method too.
I can see why you like the script templates. There might be some middle ground to hit in the future, but need to control the scope of what we're working on in the short term - i.e. need to prioritise, and I think scripts are ... OK.
The problem with the script templates is really around how the initial design has boxed us in a bit. I don't think there's a clear way for us to expand on them to do async JS templates, add typescript, introduce formatting or LSP features etc. so it's more of a pause on progressing that feature direction than anything else.
Although... in August we did add a pretty cool new feature to it: https://github.com/a-h/templ/commit/ef4dde62b8cd6e53ed55b15b7443f292cc8d4d76
The need to pass variables from the Go world to the JS world won't go away, but I was looking at introducing templ variables directly into <script>
tags instead. Combined with templ.Once
which limits rendering of the block to once per HTTP request, it would provide all the same features, but fit better into the ecosystem.
However, I would need to find a way to slot Go variables into the JS code, by parsing the content, or using a helper function.
Just typing this out has put a new idea in my head.
type Data struct {
X int `json:"x"`
Y int `json:"y"`
}
templ Component(d Data) {
<script type="text/javascript" data-templ-jsvar-name={ d }>
alert(name.x * name.y)
</script>
}
If there's a data-templ-jsvar-*
attribute, templ could generate a JS closure that includes the -name
as a variable, e.g.:
<script type="text/javascript">
let name = { x: 1, y: 3 };
alert(name.x * name.y)
</script>
However, that would mean that the variable wouldn't exist in the dev environment while you're coding, which might trigger linters, since they wouldn't know how to resolve the values.
templ could generate a JS file containing type definitions (classes?) for the data, e.g.: if you add an attribute for data-templ-jsvar-name
it takes the name of the Go type (Data
) and creates a JS class that matches in another file.
class Data {
constructor(o) {
//TODO: Get the data from a JSON variable in the attribute of the parent script tag.
this.x = x;
this.y = y;
}
}
templ Component(d Data) {
<script type="text/javascript" data-templ-jsvar-name={ d }>
let d = new Data(this); // The Data class was auto-generated by templ.
alert(d.x * d.y)
</script>
}
Thoughts? @joerdav?
Just typing this out has put a new idea in my head.
Looks cool! Good to have the feature, just shorten the name of tag maybe? Like data-templ-let
or something like this?
Just going to humbly ask: please do not fully remove the script name()
templ components until <script data-templ-let-name={} >
tag variable are implemented.
I'm looking at a bit of a migration when this happens (maybe others?). Data transfer go -> js is too useful of a feature.
Stability is important. Would never want to break people's code.
Also, if we really wanted to remove something, we'd likely add an automatic migration feature, plus keep the old method around for at least two Go release cycles.
And also, I think we would want to make sure that it was desireable to migrate a way. The alternative should be a smoother experience, I don't think we want to force a move to a unfinished solution. Once we have a proper solution hopefully people will want to move to it because it is easier.
I have a templ block defined like this:
However this does not work. The HTML it generates looks like this:
I'm not sure if I'm doing something completely wrong here as this is my first time using templ. It seems to me that something like this should work. I had a look at the
Using JavaScript with templ
docs page and it says to not use thescript
template method of doing this, which does work for me. I'm not sure how I can do the same thing using script tags as the docs say.