Arch Linux Windows Secure Boot sounds more complicated than it really is. If you dual-boot Windows and Arch Linux, you can keep Secure Boot enabled for Windows, keep rEFInd, use your own Linux signing key, and stop manually approving every new kernel. If you dual-boot Windows and Linux, you may have run into an annoying…
Read Article3 Search Results for: Secure Boot
How to Create Swapfile on Linux (Ubuntu, Fedora, Alma)
Do you need to create swapfile configurations for your Linux server? Whether you are managing a high-performance VPS or a local workstation, running out of memory can abruptly crash your database or web server. In this guide, we will walk you through the standard process for Ubuntu, Fedora, Debian, and RHEL-based systems like AlmaLinux. Even…
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 Article