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

Overview

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="[email protected]>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

Issues
  • 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
    opened by adnaan 0
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
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

foolin 292 Aug 2, 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 <

Danny van Kooten 50 Jul 31, 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

Aliaksandr Valialkin 2.5k Aug 6, 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

Victor Neo 0 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

Pedro Espíndula 1 Feb 18, 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

Daniel Skinner 25 Jan 24, 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

Ocki Bagus Pratama 0 Feb 4, 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

null 0 Feb 6, 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

Keiji Yoshida 818 Jul 2, 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

Michał Derkacz 74 Mar 15, 2022
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.

Adrian Hesketh 131 Aug 3, 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

Mix Go 20 Jul 12, 2022
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

MarkGorewicz 0 Jan 6, 2022
Go-project-template - Template for a golang project

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

KyberNetwork 3 Jul 9, 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

Only Tunes Radio 3 Jan 14, 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

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

Infinytum 17 May 1, 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

Google 280 Jul 8, 2022
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

Mayur Das 0 Jun 7, 2019
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

Benjamin Thomas 18 Jun 29, 2022