Playing with vuetify in this project I came across v-text-field
and the validation.
The documentation shows only very little information in that regard and if you need more conditional validation, how would you do that?
Continue reading “vuetify v-text-field validation if length 0 and length greater than x”
Crayon Syntax Highlighter Updated for PHP 8
I have updated the Crayon Syntax Highlighter to work with PHP8 and above.
While I have tagged the release as 2.8.6 I’m moving away from that version scheme.
1 2 |
cd wp-content/plugins/ git clone https://code.icod.de/dalu/crayon-syntax-highlighter.git |
and use master branch.
Remember to visit the settings page and save your settings, especially when switching PHP versions.
To my knowledge this is the only public repository of a working Crayon Syntax Highlighter plugin, feel free to correct me.
TypeError: Cannot read properties of null (reading ‘length’)
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.
Explanation:
1 2 3 4 |
const urls = JSON.parse(localStorage.getItem('urls')) if (urls.length > 0) { // do something } |
In this case localStorage’s ‘urls’ key or rather value of the ‘urls’ key was empty and JSON.parse transformed that to null
.
So if you check for urls.length to be greater than 0, you can’t do it and receive this error message.
How do you solve it?
1 2 3 |
if (urls && urls.length > 0) { // do something } |
This is the Javascript (and Typescript) way to check if a variable isn’t null and then check its property if it isn’t.
I know, logically this makes no sense, because it’s a logical AND. But hey, it’s Javascript so you don’t have to understand, you have to believe. 😉 HTH
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 it.
Happy coding.
Using 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