All Projects → adnaan → gomodest-template

adnaan / gomodest-template

Licence: MIT license
A template to build dynamic web apps quickly using Go, html/template and javascript

Programming Languages

HTML
75241 projects
javascript
184084 projects - #8 most used programming language
go
31211 projects - #10 most used programming language
Svelte
593 projects
Makefile
30231 projects
Dockerfile
14818 projects

Projects that are alternatives of or similar to gomodest-template

gomodest-starter
A complex SAAS starter kit using Go, the html/template package, and sprinkles of javascript.
Stars: ✭ 68 (-11.69%)
Mutual labels:  bulma, sveltejs, stimulusjs
http-interceptors
The Web apps in this monorepo make HTTP requests and require uniform consistency in how they are executed and handled. This monorepo demonstrates the same app written with Angular and with Svelte. Each app uses HTTP interceptors. The Angular app uses HttpClient and its interceptors while the Svelte app uses Axios and its interceptors.
Stars: ✭ 46 (-40.26%)
Mutual labels:  bulma, sveltejs
bulma-material-form
Material Design Form Elements for Bulma (CSS Only)
Stars: ✭ 26 (-66.23%)
Mutual labels:  bulma
plugins
Elder.js plugins and community plugins.
Stars: ✭ 80 (+3.9%)
Mutual labels:  sveltejs
templates
tsParticles website templates collection
Stars: ✭ 42 (-45.45%)
Mutual labels:  sveltejs
15puzzle
A super simple PWA for 15 Puzzle game. Built with Svelte.
Stars: ✭ 29 (-62.34%)
Mutual labels:  sveltejs
eslint-plugin-svelte
ESLint plugin for Svelte using AST
Stars: ✭ 22 (-71.43%)
Mutual labels:  sveltejs
svelteWeb3
A simple, dependency minimized package for building modern dApps with Svelte
Stars: ✭ 14 (-81.82%)
Mutual labels:  sveltejs
svelte3-translation-ru
Russian translation of the official Svelte resources
Stars: ✭ 49 (-36.36%)
Mutual labels:  sveltejs
bulma-block-list
A simple scss package extending Bulma with block style list elements
Stars: ✭ 34 (-55.84%)
Mutual labels:  bulma
Bulma.io-axure
AxureRP Library with Bulma.io components
Stars: ✭ 90 (+16.88%)
Mutual labels:  bulma
chrome-snowplow-inspector
Web Extension for debugging Snowplow pixels.
Stars: ✭ 26 (-66.23%)
Mutual labels:  bulma
datatables-bulma
DataTables styling for the Bulma CSS framework
Stars: ✭ 80 (+3.9%)
Mutual labels:  bulma
bulmil
💄 A agnostic UI components library based on Web Components, made with Bulma & Stencil.
Stars: ✭ 121 (+57.14%)
Mutual labels:  bulma
esbuild-rails
Esbuild Rails plugin
Stars: ✭ 102 (+32.47%)
Mutual labels:  stimulusjs
theme-bulma
🎈 Customization of Oruga components with Bulma CSS framework
Stars: ✭ 88 (+14.29%)
Mutual labels:  bulma
yii-bulma
Yii Framework Bulma Integration
Stars: ✭ 23 (-70.13%)
Mutual labels:  bulma
bulma-pro
A professional theme for Bulma! https://mubaidr.github.io/bulma-pro/
Stars: ✭ 14 (-81.82%)
Mutual labels:  bulma
vue-checkbox-switch
A Vue component for checkbox's switch style
Stars: ✭ 36 (-53.25%)
Mutual labels:  bulma
svelte-starter-kit
Svelte with brilliant bells and useful whistles
Stars: ✭ 384 (+398.7%)
Mutual labels:  sveltejs

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

  • Use as a github template
  • git clone https://github.com/<user>/<mytemplate> and cd /path/to/your/gomodest-template
  • make watch (starts hot-reload for go, html and javascript changes)
  • open localhost:3000.

or

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

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.

<!DOCTYPE html>

<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

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

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

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].