Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generator: enable script components on alpine.js attributes #579

Closed
hakanrw opened this issue Mar 3, 2024 · 10 comments
Closed

generator: enable script components on alpine.js attributes #579

hakanrw opened this issue Mar 3, 2024 · 10 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed NeedsInvestigation Issue needs some investigation before being fixed

Comments

@hakanrw
Copy link

hakanrw commented Mar 3, 2024

alpine.js is a lightweight javascript framework that has the potential to integrate nicely with templ.
all alpinejs attributes start with the prefix x-.

suppose the script component below

script alpineState() {
  return {
    "time": Date.now()
  }
}

it would be great if we could use this component as alpine.js state

<div x-data={alpineState()} x-text="time"></div>

more examples

script currentTime() {
  return  Date.now()
}

script logToConsole() {
  console.log("clicked")
}
<div x-data="{}">
  <span x-text={currentTime()}</span>
  <button x-on:click={logToConsole()}>click me</span>
</div>

recommendation:

templ/generator/generator.go

Lines 993 to 1000 in 2a7ab84

func isScriptAttribute(name string) bool {
for _, prefix := range []string{"on", "hx-on:"} {
if strings.HasPrefix(name, prefix) {
return true
}
}
return false
}

replace []string{"on", "hx-on:"} with []string{"on", "hx-on:", "x-"} to enable script components on all alpine.js attributes.

@hakanrw
Copy link
Author

hakanrw commented Mar 3, 2024

i've found a temporary workaround for this feature:

it is kind of a hacky solution, but the feature above can be achieved by changing the Alpine.js prefix to onx-

add this to your head tag:

<script>
    function changeAlpinePrefix() {
        Alpine.prefix("onx-");
        Alpine.start();
    }
    window.onload = changeAlpinePrefix;
</script>

now you can use:

templ Index() {

    <div onx-data={alpineState()}>
        <div>time: <span onx-text="time" /></div>
    </div>
}

script alpineState() {
  return {
      "time": Date.now()
  }
}

@a-h
Copy link
Owner

a-h commented Mar 3, 2024

Glad you have a temporary workaround.

I did notice that a lot of people use script components when there's no obvious need to, I think the documentation may have over-emphasized them, so I've added a new section into the docs so that this is the first thing you see on https://templ.guide/syntax-and-usage/script-templates/

templ body() {
  <script type="text/javascript">
    function handleClick(event) {
      alert(event + ' clicked');
    }
  </script>
  <button onclick="handleClick(this)">Click me</button>
}

I think of script templates as a way for bundling JS along with component libraries, and a way of passing data from Go to JS, rather than them being the standard way to write JS in templ.

@a-h
Copy link
Owner

a-h commented Mar 3, 2024

I think this just needs a decision on whether to implement the minor change or not.

I don't know if x- attributes are widely used elsewhere and changing the behaviour of x- attributes would cause a namespace clash, so I'd want to see some research that before adding it. I suspect not, but I think it's worth a check.

@a-h a-h added enhancement New feature or request help wanted Extra attention is needed good first issue Good for newcomers NeedsInvestigation Issue needs some investigation before being fixed labels Mar 3, 2024
@hakanrw
Copy link
Author

hakanrw commented Mar 3, 2024

Glad you have a temporary workaround.

I did notice that a lot of people use script components when there's no obvious need to, I think the documentation may have over-emphasized them, so I've added a new section into the docs so that this is the first thing you see on https://templ.guide/syntax-and-usage/script-templates/

templ body() {
  <script type="text/javascript">
    function handleClick(event) {
      alert(event + ' clicked');
    }
  </script>
  <button onclick="handleClick(this)">Click me</button>
}

I think of script templates as a way for bundling JS along with component libraries, and a way of passing data from Go to JS, rather than them being the standard way to write JS in templ.

i see, script templates improve readability and look nicer in my opinion. and i think generated function names that start with __templ might prevent clashes with some other global js functions?

like you mentioned, they also allow passing data from go to javascript, which i am using (although not in the example i gave above) to pass server-side state to client-side alpinejs state with the onx- prefix. i think script templates have the potential to be useful and improve readability in templ code.

all aside, thank you for your interest on the matter. i love my current experience with templ so far :)

@jkehler
Copy link

jkehler commented Mar 4, 2024

I also just ran into this issue today. I want to populate my x-data attribute with data passed in from Go. I guess the hack provided means that I would have to use the onx- prefix for everything in Alpinejs?

In my opinion I think the easiest fix is to just remove the random letters and numbers generated on the javascript function and just making it __templ_{functionName}. Then it can be called directly without any issues.

@jkehler
Copy link

jkehler commented Mar 4, 2024

Here is another hack solution I came up with.

<script>
  function getTemplFunction(name) {
    for ( var i in window) {
      if((typeof window[i]).toString()=="function"){
        if (i.includes("__templ_" + name)) {
          return window[i];
        }
      }
    }
  }
</script>

Then I can use x-data="getTemplFunction('functionName')()"

Edit: Actually this didn't work, since it's not possible to pass data into the function then. I found this alternative solution below which did work.

script myScriptName(data string) {
  window.myScriptName = function() {
     ... do whatever is needed with `data`
  }
}

then you can use x-data="myScriptName()" like usual.

@hakanrw
Copy link
Author

hakanrw commented Mar 4, 2024

I also just ran into this issue today. I want to populate my x-data attribute with data passed in from Go. I guess the hack provided means that I would have to use the onx- prefix for everything in Alpinejs?

In my opinion I think the easiest fix is to just remove the random letters and numbers generated on the javascript function and just making it __templ_{functionName}. Then it can be called directly without any issues.

the prefix needs to start with on for the templ compiler to recognize it, so in my case i used onx-.

1 similar comment
@hakanrw
Copy link
Author

hakanrw commented Mar 4, 2024

I also just ran into this issue today. I want to populate my x-data attribute with data passed in from Go. I guess the hack provided means that I would have to use the onx- prefix for everything in Alpinejs?

In my opinion I think the easiest fix is to just remove the random letters and numbers generated on the javascript function and just making it __templ_{functionName}. Then it can be called directly without any issues.

the prefix needs to start with on for the templ compiler to recognize it, so in my case i used onx-.

@peteraba
Copy link

peteraba commented Apr 3, 2024

my two cents: while I'm also interested in using Alpine with templ, I feel that this should be an opt-in feature, perhaps a full-blown setting to set the prefix(es).

@joerdav
Copy link
Collaborator

joerdav commented May 31, 2024

I believe we now have a standard for passing serverside data to the client here: https://templ.guide/syntax-and-usage/script-templates#passing-server-side-data-to-scripts

And in the case of using alpine functions it looks like there is a workaround to get started.

That combined with the recommendation away from script templates I think we can close this.

@joerdav joerdav closed this as not planned Won't fix, can't repro, duplicate, stale May 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed NeedsInvestigation Issue needs some investigation before being fixed
Projects
None yet
Development

No branches or pull requests

5 participants