Being the Javascript newbie that I am… Javascript errors are still a mystery, more so if using Chrome/Chromium. With Firefox the error was actually more clear. TypeError: Cannot read properties of null (reading ‘length’) means you have a variable that you’re checking it’s property ‘length’ to be a certain value but the variable is null.…
Read ArticleCategory: Entwicklung
Webentwicklungg, Programmieren, Software, Server… irgendwie alles was in den Bereich Computer und Entwicklung fällt
Anything regarding web-development
The way is clear for Vue 3 with Keycloak
Since Pull Request 116 of dsb-norge/vue-keycloak-js today Keycloak works well with Vue 3. This is great news because you can now use Quasar v2, which uses vue 3 under the hood for your authentication purposes. If you missed the post on how to integrate keycloak with Quasar v1 and v2, click the link to read…
Read ArticleUsing gin with pongo2/v4 or v5 and embedded templates
You’d like to use pongo2/v4 with gin and embed templates with go:embed. I’m using cobra for my cli parsing and commands. So
|
1 2 3 4 |
mkdir -p ~/go/src/git.icod.de/dalu/ui cd ~/go/src/git.icod.de/dalu/ui cobra init --pkg-name git.icod.de/dalu/ui cobra add ui |
edit cmd/ui.go
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
package cmd import ( "errors" "fmt" "io/fs" "os" "strings" "<your pkg path>/ui" "code.icod.de/dalu/ginpongo2/v5" "github.com/flosch/pongo2/v5" "github.com/gin-gonic/gin" "github.com/spf13/cobra" ) const ( prefixTCP = "tcp:" prefixUNIX = "unix:" ) var ( uiDebug bool uiAddr string ) // uiCmd represents the ui command var uiCmd = &cobra.Command{ Use: "ui", Short: "serves the management ui over http", RunE: func(cmd *cobra.Command, args []string) error { if !uiDebug { gin.SetMode(gin.ReleaseMode) } r := gin.Default() r.SecureJsonPrefix(")]}',\n") r.MaxMultipartMemory = 8 << 20 if uiDebug { fmt.Println("debug mode") fl, e := pongo2.NewLocalFileSystemLoader("ui/templates/") if e != nil { return e } hr := ginpongo2.New(true, fl) r.HTMLRender = hr } else { fmt.Println("release mode") subFS, e := fs.Sub(ui.Templates, "templates") if e != nil { return e } fl := pongo2.NewFSLoader(subFS) hr := ginpongo2.New(false, fl) r.HTMLRender = hr } // Static r.Static("/assets/", "./assets/") r.GET("/", func(cx *gin.Context) { ctx := make(pongo2.Context) type Data struct { Target string Message string } ctx["data"] = &Data{ Target: "World", Message: "It's a great day to be alive", } cx.HTML(200, "index", ctx) }) // serve if strings.HasPrefix(uiAddr, prefixTCP) { addr := strings.TrimPrefix(uiAddr, prefixTCP) fmt.Println("listening on", addr) return r.Run(addr) } else if strings.HasPrefix(uiAddr, prefixUNIX) { addr := strings.TrimPrefix(uiAddr, prefixUNIX) if _, e := os.Stat(addr); errors.Is(e, os.ErrNotExist) { fmt.Println("listening on", addr) return r.RunUnix(addr) } else { if e := os.Remove(addr); e != nil { return e } else { fmt.Println("listening on", addr) return r.RunUnix(addr) } } } else { return nil } }, } func init() { rootCmd.AddCommand(uiCmd) uiCmd.Flags().BoolVar(&uiDebug, "debug", false, "enable dev mode") uiCmd.Flags().StringVar( &uiAddr, "addr", "tcp:localhost:8080", "either tcp: or unix: e.g. tcp:localhost:3030 unix:/tmp/listen.sock", ) } |
ui/templates.go
|
1 2 3 4 5 6 |
package ui import "embed" //go:embed templates/* var Templates embed.FS |
ui/templates/base.html.twig
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> {%- block meta %}{% endblock -%} <title>{{ title }}</title> {%- block js %}{% endblock -%} {%- block css %}{% endblock -%} </head> <body> {%- block body %}{% endblock -%} {%- block jsbottom %}{% endblock -%} </body> </html> |
ui/templates/layout.html.twig
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
{% extends "base.html.twig" %} {%- block css %} <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous"> {% endblock -%} {%- block js %} <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script> {% endblock -%} {%- block body %} <div class="container"> <div class="row"> <div class="col-2"> {%- block left -%}{% endblock -%} </div> <div class="col-8"> {%- block middle -%}{% endblock -%} </div> <div class="col-2"> {%- block right -%}{% endblock -%} </div> </div> </div> {% endblock -%} |
ui/templates/index.html.twig
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{% extends "layout.html.twig" %} {%- block middle %} <div class="px-4 py-5 my-5 text-center"> <h1 class="display-5 fw-bold">Hello {{data.Target}}</h1> <div class="col-lg-6 mx-auto"> <p class="lead mb-4">{{data.Message}}</p> <div class="d-grid gap-2 d-sm-flex justify-content-sm-center"> <button type="button" class="btn btn-primary btn-lg px-4 gap-3">You got it</button> <button type="button" class="btn btn-outline-secondary btn-lg px-4">Huh?</button> </div> </div> </div> {% endblock -%} |
and finally run
|
1 |
go mod tidy |
to download packages Any questions -> leave a comment
Read ArticleGo/Golang Run embedded bash script or node/js,python,php,ruby etc
Since Go v1.16 there’s the embed package, a simple tool to embed files as filesystems of simple strings or []bytes. While it has its downsides, I was recently met with a challenge. I’d like to run bash scripts I wrote because it’s more efficient to just run a bash script than breaking my fingers writing…
Read ArticleWatch out! It’s the Angular Thought Police!
So, yesterday I was visiting Angular’s discord server, because after a little over a month with Vue I was missing Angular’s components and way to express event listeners and 2-way binding of variables as well as the class based approach. Vue2 is a simple, super productive framework, especially with Quasar, with a rich ecosystem and…
Read Article