Skip to content

Instantly share code, notes, and snippets.

@wingedpig
Created October 14, 2020 20:47
Show Gist options
  • Select an option

  • Save wingedpig/6d10fe11ef802bd8e258cea889084611 to your computer and use it in GitHub Desktop.

Select an option

Save wingedpig/6d10fe11ef802bd8e258cea889084611 to your computer and use it in GitHub Desktop.
A thought experiment about a new Go-based UI framework.
package testpage
/*
This is a thought experiment about a new Go-based UI framework. A project to accomplish the same thing as React or Vue.js.
I strongly dislike Javascript and all the existing reactive UI frameworks. For whatever reason, and try as I might, I cannot get my head around
them. Hence this thought experiment about what kind of UI framework I would like to use.
== Goals ==
- I want to be able to build a responsive website easily.
- Easy integration with a GO backend.
- Strong type checks/compilation checks.
- Utilize the syntax of Quicktemplate.
- None of the 'magic' of react-based frameworks.
This framework would transpile Go into Javascript or WASM. The main addition to this Go package is in the Render() func, with its code
surrounded by {% render %}{% endrender %}. Think of it somewhat like JSX, but using the syntax of Quicktemplate. Calling this function
will generate and instantiate the appropriate UI component as a child of the parentID DOM element.
There is also a Refresh() function, which takes a document ID and does a refresh of that. There is no automatic react-like magic
refresh.
The index.html page would look like:
<html>
<body>
<div id="app"></div>
<script src="compiled.js"></script>
<script>
Run("app");
</script>
</body>
</html>
== My questions ==
- What do you think about this and do you have any suggestions for improvements?
- It seems like there are 3 options for Go transpilation to Javascript(or WASM):
- GopherJS
- Joy
- TinyGo to WASM
Am I missing any projects? Joy appears abandoned, but I like its approach in generating small code. GopherJS seems to result in a huge runtime,
and hasn't been updated in awhile. And I'm not sure about TinyGo/WASM. How would you approach transpilation?
*/
type Data struct {
parentID string
count int
single string
items []string
}
func (data *Data) Render(parentID string) {
{% render %}
<p>This is a counter: {%d data.count %} <button {% onclick data.incrementCount() %}>Increment</button></p>
<p>
{% if data.count > 2 && data.count < 5 %}
count is > 2 and < 5
{% elseif data.count > 4 && data.count < 9 %}
count is > 4 and < 9,
{% if data.count == 6 %}
and we have six!
{% elseif data.count == 7 %}
and we have seven!
{% endif %}
{% else %}
this is my else.
{% endif %}
</p>
<p>single string value: {%s data.single %}</p>
<p>Here are some items:
<ul>
{% for _, item := range data.items %}
<li>{%s item %}</li>
{% endfor %}
</ul>
{% endrender %}
}
func Run(parentID) Data {
var data Data
data.count = 1
data.single = "single string"
data.items = []string{"one", "two", "three"}
data.parentID = parentID
data.Render(parentID)
return data
}
func (data *Data) incrementCount() {
data.count++
data.single = "smart string"
// Refresh will refresh all the values in the id 'mypage'
Refresh(data.parentID)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment