A template to build dynamic web apps quickly using Go, html/template and javascript

gomodest-template

A modest template to build dynamic web apps in Go, HTML and sprinkles and spots of javascript.

Why ?

  • Build dynamic websites using the tools you already know(Go, HTML, CSS, Vanilla Javascript) for the most part.
  • Use bulma components to speed up prototyping a responsive and good-looking UI.
  • Use turbo & stimulusjs for most of the interactivity.
  • For really complex interactivity use Svelte 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.

Usage

or

brew install gh
gh repo create myapp --template adnaan/gomodest-template
cd myapp
git pull origin main
make install
goreplace gomodest-template -r myapp
make watch

gomodest tempalte home

TOC

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:

          {{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:

        {{define "content"}}
            App's {{.dashboard}}
        {{end}}

    View is rendered within a layout:

        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.

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.

... ">
<meta charset="UTF-8">
<meta name="description" content="A modest way to build golang web apps">
<meta name="viewport"content="width=device-width, initial-scale=1.0, maximum-scale=5.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
...

Step 2: Add a layout

Create index.html file in templates/layouts and use the above partial.

{{.app_name}} {{include "partials/header"}} ... ">
>

<html lang="en">
<head>
    <title>{{.app_name}}title>
    {{include "partials/header"}}
head>
<body ...>
...
body>
html>

Step 4: Add a view partial

Create main.html in templates/partials

Hello {{.hello}}

{{end}} ">
{{define "main"}}
    <main>
        <div class="columns is-centered is-vcentered is-mobile py-5">
            <div class="column is-narrow" style="width: 70%">
                <h1 class="has-text-centered title">Hello {{.hello}}h1>
            div>
        div>
    main>
{{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.

{{template "main" .}}
{{end}} ">
{{define "content"}}
<div class="columns is-mobile is-centered">
    <div class="column is-half-desktop">
        {{template "main" .}}
    div>
div>
{{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.

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.

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

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.

Step 2: Add data attributes to the target div

... ">
<body data-controller="util svelte"
      data-action="keydown@window->util#keyDown "
      data-util-active-class="is-active">
  
    ...
  <button class="button"
    data-action="click->util#goto"
    data-goto="/">Home
  button>
body>

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

      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.

{{end}} ">
{{define "content"}}
<div class="columns is-mobile is-centered">
 <div class="column is-half-desktop">
  <div
          data-svelte-target="component"
          data-component-name="app"
          data-component-props="{{.Data}}">
  div>
 div>
div>
div>
{{end}}

Step 2: Create and export svelte component

  • Create a new svelte component in src/components and export it in src/components/index.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.

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 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 to a list of sample views. Copy-paste at will from the templates/samples directory.

Dependencies

Owner
Adnaan Badr
Devops, Go, Kubernetes, Docker. Ex-Android Framework Engineer. Worked on a linux server, a tablet, a phone and a smartwatch. Reducing cloud native complexity.
Adnaan Badr
Similar Resources

Go-project-template - Template for a golang project

This is a template repository for golang project Usage Go to github: https://git

Oct 25, 2022

Go-api-template - A rough template to give you a starting point for your API

Golang API Template This is only a rough template to give you a starting point f

Jan 14, 2022

A scaffold to quickly create a go project

OpenMix 出品:https://openmix.org Mix CLI 一个快速创建 go 项目的脚手架 A scaffold to quickly create a go project Installation 安装 go get -u github.com/mix-go/mixcli

Nov 16, 2022

Templating system for HTML and other text documents - go implementation

FAQ What is Kasia.go? Kasia.go is a Go implementation of the Kasia templating system. Kasia is primarily designed for HTML, but you can use it for any

Mar 15, 2022

A strongly typed HTML templating language that compiles to Go code, and has great developer tooling.

A strongly typed HTML templating language that compiles to Go code, and has great developer tooling.

A language, command line tool and set of IDE extensions that makes it easier to write HTML user interfaces and websites using Go.

Dec 29, 2022

Code your next Go web project with (a) Mojito! No matter if its an API or a website, go-mojito assists you with dependency injection, simple routing, custom request / response objects and template rendering

 Code your next Go web project with (a) Mojito! No matter if its an API or a website, go-mojito assists you with dependency injection, simple routing, custom request / response objects and template rendering

Go-Mojito is a super-modular library to bootstrap your next Go web project. It can be used for strict API-only purposes as well as server-side renderi

May 1, 2022

Create cross-platform GUI apps with Golang + Elm!

README About Create GUI apps with Wails + Elm! Dev env requirements setup a golang toolchain setup a wails toolchain install elm-live globally: npm in

Oct 5, 2022

Safe HTML for Go

Safe HTML for Go safehtml provides immutable string-like types that wrap web types such as HTML, JavaScript and CSS. These wrappers are safe by constr

Dec 28, 2022

mold your templated to HTML/ TEXT/ PDF easily.

mold your templated to HTML/ TEXT/ PDF easily.

mold mold your templated to HTML/ TEXT/ PDF easily. install go get github.com/mayur-tolexo/mold Example 1 //Todo model type Todo struct { Title stri

Jun 7, 2019
Comments
  • sessions

    sessions

    • websocket sessions
    • update datalist to use received method for operations
    • concurrent map access, rename session to topic
    • change url path to represent a unique topic
    • default upgrade
    • refacor samples
    • reuse websocket router
    • validate and handle errors
Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application.

goview Goview is a lightweight, minimalist and idiomatic template library based on golang html/template for building Go web application. Contents Inst

Dec 25, 2022
Wrapper package for Go's template/html to allow for easy file-based template inheritance.

Extemplate Extemplate is a small wrapper package around html/template to allow for easy file-based template inheritance. File: templates/parent.tmpl <

Dec 6, 2022
Fast, powerful, yet easy to use template engine for Go. Optimized for speed, zero memory allocations in hot paths. Up to 20x faster than html/template

quicktemplate A fast, powerful, yet easy to use template engine for Go. Inspired by the Mako templates philosophy. Features Extremely fast. Templates

Dec 26, 2022
A simple template using Fiber for me to bootstrap API services quickly.

Fiber Template A simple template using Fiber for me to bootstrap API services quickly. Features Fiber GORM air for hot reloading ... and possibly more

Dec 16, 2021
Api-go-template - A simple Go API template that uses a controller-service based model to build its routes

api-go-template This is a simple Go API template that uses a controller-service

Feb 18, 2022
Template Repository for quickly bootstraping Go projects

go-template go-template overview setup Rust ToolChain Convco Just Bootstrap Repository Go Tools docker images prerequisites build scripts Github Actio

Feb 6, 2022
Package damsel provides html outlining via css-selectors and common template functionality.

Damsel Markup language featuring html outlining via css-selectors, extensible via pkg html/template and others. Library This package expects to exist

Oct 23, 2022
Golang Echo and html template.

golang-website-example Golang Echo and html template. move GitHub repository for hello to golang-website-example Visual Studio Code Run and Debug: lau

Feb 4, 2022
HTML template engine for Go

Ace - HTML template engine for Go Overview Ace is an HTML template engine for Go. This is inspired by Slim and Jade. This is a refinement of Gold. Exa

Jan 4, 2023
Made from template temporalio/money-transfer-project-template-go
Made from template temporalio/money-transfer-project-template-go

Temporal Go Project Template This is a simple project for demonstrating Temporal with the Go SDK. The full 20 minute guide is here: https://docs.tempo

Jan 6, 2022