Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/adnaan/gomodest-template
A template to build dynamic web apps quickly using Go, html/template and javascript
https://github.com/adnaan/gomodest-template
bulma go html stimulusjs sveltejs
Last synced: 2 months ago
JSON representation
A template to build dynamic web apps quickly using Go, html/template and javascript
- Host: GitHub
- URL: https://github.com/adnaan/gomodest-template
- Owner: adnaan
- License: mit
- Created: 2021-02-06T19:29:02.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2021-10-22T03:31:31.000Z (about 3 years ago)
- Last Synced: 2024-10-01T01:41:19.406Z (3 months ago)
- Topics: bulma, go, html, stimulusjs, sveltejs
- Language: HTML
- Homepage: https://gomodest-template.fly.dev
- Size: 1.05 MB
- Stars: 94
- Watchers: 3
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# gomodest-template
A [modest](https://modestjs.works) template to build dynamic web apps in Go, HTML and [sprinkles and spots](https://modestjs.works/book/part-2/same-ui-three-modest-ways/) of javascript.
## Why ?
- Build dynamic websites using the tools you already know(Go, HTML, CSS, Vanilla Javascript) for the most part.
- Use [bulma components](https://bulma.io/documentation/components/) to speed up prototyping a responsive and good-looking UI.
- Use [turbo & stimulusjs](https://hotwire.dev/) for most of the interactivity.
- For really complex interactivity use [Svelte](https://svelte.dev/) for a single div in a few spots.
- Lightweight and productive. Fast development cycle.
- Easy to start, easy to maintain.For a more complete implementation using this technique please see [gomodest-starter](https://github.com/adnaan/gomodest-starter).
## Usage
- [Use as a github template](https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-from-a-template#creating-a-repository-from-a-template)
- `git clone https://github.com//` and `cd /path/to/your/gomodest-template`
- `make watch` (starts hot-reload for go, html and javascript changes)
- open [localhost:3000](http://localhost:3000).or
```bash
brew install gh
gh repo create myapp --template adnaan/gomodest-template
cd myapp
make install # or (make install-x64)
# replace gomodest-template with your app name
go get github.com/piranha/goreplace
$(go env GOPATH)/bin/goreplace gomodest-template -r myapp
git add . && git commit -m "replace gomodest-template"
make watch # or make watch-x64
```![gomodest tempalte home](screenshots/gomodest-template-index.png?raw=true "")
## TOC
* [Folder Structure](#folder-structure)
* [Views using html templates](#views-using-html-templates)
+ [Step 1: Add a layout partial](#step-1--add-a-layout-partial)
+ [Step 2: Add a layout](#step-2--add-a-layout)
+ [Step 4: Add a view partial](#step-4--add-a-view-partial)
+ [Step 5: Add a view](#step-5--add-a-view)
+ [Step 6: Render view](#step-6--render-view)
* [Interactivity using Javascript](#interactivity-using-javascript)
+ [Stimulus Controllers](#stimulus-controllers)
- [Step 1: Add a controller](#step-1--add-a-controller)
- [Step 2: Add data attributes to the target div](#step-2--add-data-attributes-to-the-target-div)
+ [Svelte Components](#svelte-components)
- [Step 1: Add data attributes to the target div.](#step-1--add-data-attributes-to-the-target-div)
- [Step 2: Create and export svelte component](#step-2--create-and-export-svelte-component)
- [Step 3: Hydrate initial props from the server](#step-3--hydrate-initial-props-from-the-server)
* [Styling and Images](#styling-and-images)
* [Samples](#samples)
* [Dependencies](#dependencies)Table of contents generated with markdown-toc
## Folder Structure
- templates/
- layouts/
- partials/
- list of view files
- assets/
- images/
- src/
- components/
- controllers/
- index.js
- styles.scss- `templates` is the root directory where all html/templates assets are found.
- `layouts` contains the layout files. Layout is a container for `partials` and `view files`
- `partials` contains the partial files. Partial is a reusable html template which can be used in one of two ways:- Included in a `layout` file: `{{include "partials/header"}}`
- Included in a `view` file: `{{template "main" .}}`. When used in a view file, a partial must be enclosed in a `define` tag:
```html
{{define "main"}}
Hello {{.hello}}
{{end}}
```
- `view` files are put in the root of the `templates` directory. They are contained within a `layout` must be enclosed in a `define content` tag:```html
{{define "content"}}
App's {{.dashboard}}
{{end}}
```
`View` is rendered within a `layout`:
```go
indexLayout, err := rl.New(
rl.Layout("index"),
rl.DisableCache(true),
rl.DefaultHandler(func(w http.ResponseWriter, r *http.Request) (rl.M, error) {
return rl.M{
"app_name": "gomdest-template",
}, nil
}))
...
r.Get("/", indexLayout.Handle("home",
func(w http.ResponseWriter, r *http.Request) (rl.M, error) {
return rl.M{
"hello": "world",
}, nil
}))
```
Here the `view`: `home` is rendered within the `index` layout.Please see the `templates` directory.
- `assets` directory contains the public asset pipeline for the project.
- `styles.scss` is a custom `scss` file for [bulma][https://bulma.io] as [documented here](https://bulma.io/documentation/customize/with-webpack/).
- `index.js` is the entrypoint for loading `stimulusjs` controllers sourced from this [example](https://github.com/hotwired/stimulus-starter.
- `controllers` contains [stimulusjs controllers](https://stimulus.hotwire.dev/reference/controllers).
- `components` contains single file svelte components.## Views using html templates
There are three kinds of `html/template` files in this project.
- `layout`: defines the base structure of a web page.
- `partial`: reusable snippets of html. It can be of two types: `layout partials` & `view partials`.
- `view`: the main container for the web page logic contained within a `layout`. It must be enclosed in a `define content` template definition. It can use view partials.### Step 1: Add a layout partial
Create `header.html` file in `templates/partials`.
```html
...
```### Step 2: Add a layout
Create `index.html` file in `templates/layouts` and use the above partial.
```html
{{.app_name}}
{{include "partials/header"}}...
```
### Step 4: Add a view partial
Create `main.html` in `templates/partials`
```html
{{define "main"}}
Hello {{.hello}}
{{end}}
```This is a different from the `layout partial` since it's closed in a `define` tag.
### Step 5: Add a view
Create `home.html` in `templates` and use the above partial.
```html
{{define "content"}}
{{template "main" .}}
{{end}}
```
Notice that a `view` is always enclosed in `define content` template definition.### Step 6: Render view
To render the view with data we use a wrapper over the `html/template` package.
```go
r.Get("/", indexLayout.Handle("home",
func(w http.ResponseWriter, r *http.Request) (rl.M, error) {
return rl.M{
"hello": "world",
}, nil
}))
```To learn more about `html/template`, please look into this amazing [cheatsheet](https://curtisvermeeren.github.io/2017/09/14/Golang-Templates-Cheatsheet).
Reference:
- `templates/layout/index.html`
- `templates/partials/header.html`
- `templates/partials/main.html`
- `templates/home.html`
- `main.go`## Interactivity using Javascript
For client-side interactivity we use a bit of javascript.
### Stimulus Controllers
A stimulus controller is a snippet of javascript which handles a single aspect of interactivity. To add a new svelte component:
#### Step 1: Add a controller
Create a file with suffix: `_controller.js`
`util_controller.js`
```js
import { Controller } from "stimulus"export default class extends Controller {
...connect(){
}
goto(e){
if (e.currentTarget.dataset.goto){
window.location = e.currentTarget.dataset.goto;
}
}goback(e){
window.history.back();
}...
}```
See complete implementation in `assets/src/controller/util_controller.js`. To understand how stimulus works, please see the [handbook](https://stimulus.hotwire.dev/handbook/introduction).
#### Step 2: Add data attributes to the target div
```html
...
Home
```
Here we are attaching two controllers to the `body` itself since they are used often. Later we can add action and data attributes to use them.
Reference:
- `templates/layout/index.html`
- `templates/404.html`
- `assets/src/controllers/util_controller.js`### Svelte Components
A svelte component is loaded into the targeted div by a stimulujs controller: `controllers/svelte_controller.js`. This is hooked by declaring data attributes on the div which is to be contain the svelte component:
- `data-svelte-target`: Value is **required** to be `component`. It's used for identifying the divs as targets for the `svelte_controller`.
- `data-component-name`: The name of the component as exported in `src/components/index.js````js
import app from "./App.svelte"
// export other components here.
export default {
app: app,
}
```
- `data-component-props`: A string map object which is passed as initial props to the svelte component.To add a new svelte component:
#### Step 1: Add data attributes to the target div.
```html
{{define "content"}}
{{end}}
```#### Step 2: Create and export svelte component
- Create a new svelte component in `src/components` and export it in `src/components/index.js`
```js
import app from "./App.svelte"// export other components here.
export default {
app: app,
}
```The `controllers/svelte_controller.js` controller loads the svelte component in to the div with the required data attributes shown in step 1.
#### Step 3: Hydrate initial props from the server
It's possible to hydrate initial props from the server and pass onto the component. This is done by templating a string data object into the `data-component-props` attribute.
```go
r.Get("/app", indexLayout.Handle("app",
func(w http.ResponseWriter, r *http.Request) (rl.M, error) {
appData := struct {
Title string `json:"title"`
}{
Title: "Hello from server for the svelte component",
}
d, err := json.Marshal(&appData)
if err != nil {
return nil, fmt.Errorf("%v: %w", err, fmt.Errorf("encoding failed"))
}
return rl.M{
"Data": string(d), // notice struct data is converted into a string
}, nil
}))
```Reference:
- `templates/app.html`
- `src/controllers/svelte_controller.js`
- `src/components/*`
- `main.go`## Styling and Images
[Bulma](https://bulma.io/) is included by default. Bulma is a productive css framework with prebuilt components and helper utilities.
- `assets/src/styles.scss`: to override default bulma variables. `webpack` bundles and copies css assets to `public/assets/css.
- `assets/images`: put image assets here. it will be auto-copied to `public/assets/images` by `webpack`.## Samples
Go to [localhost:3000/samples](http://localhost:3000/samples/) to a list of sample views. Copy-paste at will from the `templates/samples` directory.
## Dependencies
- Backend:
- [Go](https://golang.org/)
- [renderlayout: a wrapper over foolin/goview](https://github.com/adnaan/renderlayout)
- [chi](https://github.com/go-chi/chi)
- Frontend:
- [html/template](https://golang.org/pkg/html/template/)
- [masterminds/sprig](http://masterminds.github.io/sprig/)
- [StimulusJS(sprinkles)](https://stimulus.hotwire.dev/)
- [SvelteJS(spots)](https://svelte.dev/)
- [Bulma CSS](https://bulma.io/)
- [Webpack](https://webpack.js.org/)