gofiber / template Goto Github PK
View Code? Open in Web Editor NEW๐งฌ Template engine middleware for Fiber
Home Page: https://docs.gofiber.io/guide/templates
License: MIT License
๐งฌ Template engine middleware for Fiber
Home Page: https://docs.gofiber.io/guide/templates
License: MIT License
How do I output specific sections or variable without them being HTML encoded for safety? I understand the implications of doing this and how I'm exposing myself to XSS etc but I have this one specific bit of code that absolutely needs to be outputted untouched. I checked the article linked to in the read me and tried using template.HTML but it doesn't seem to be working.
I appreciate any pointers. Thank you.
https://github.com/gofiber/template/tree/master/html
Specifically, where it says "click here to preview", it returns a 404 error
`
import (
"github.com/flosch/pongo2"
)
pongo2.RegisterFilter("nl2br", Nl2brHtml)
func Nl2brHtml(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, err *pongo2.Error) {
if !in.IsString() {
s3 := " "
return pongo2.AsValue(s3), nil
} else {
s1 := in.String()
s2 := strings.Replace(s1, "\n", "<br />", -1)
return pongo2.AsValue(s2), nil
}
}`
{{"mytext" | nl2br }}applicaiton.go
package main
import (
"log"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/html"
)
func main() {
engine := html.New("./views", ".html")
app := fiber.New(fiber.Config{
Views: engine,
})
app.Get("/", func(c *fiber.Ctx) error {
return c.Render("index", fiber.Map{
"Title": "Hello, World!",
}, "layout")
})
log.Fatal(app.Listen(":3000"))
}
layout.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.Title}}</title>
</head>
<body>
{{ embed }}
</body>
</html>
index.html
<h1>{{.Title}}</h1>
go.mod
module fiber.2
go 1.15
require (
github.com/fasthttp/session/v2 v2.2.3 // indirect
github.com/gofiber/fiber/v2 v2.0.1
github.com/gofiber/session/v2 v2.0.0
github.com/gofiber/template v1.6.0
golang.org/x/sys v0.0.0-20200915084602-288bc346aa39 // indirect
)
first run it show "Hello World" if I reload page some thing happen and show error "html/template: cannot Clone "layout" after it has executed"
Why call pongo2 style template django?
The readme for pongo2 says..
pongo2 is a Django-syntax LIKE templating-language.
(emphasis mine)
Since the syntax is not 100% alike I would rather not have to look for what libraries that is actually used for the django like syntax.
Just calling it pongo2 would be much more descriptive but I might have missed something.
Hello, How to get fiber.Ctx in add template(django) function ?
Some package still uses old logrus (1.2.0, 1.6.0), might be a good idea to update logrus
to the latest 1.8.1
.
Currently, this project homepage URL is https://docs.gofiber.io/middleware#template but it should be https://docs.gofiber.io/guide/templates
is there an example how to use functions passed with AddFunc in html templates?
this works only when the function is passed in via c.Render("", fiber.Map{"Static": ... but not with AddFunc
{{ call Static "bla" }}
| template: layout:8:45: executing "layout" at <Static>: wrong number of args for Static: want 1 got 0
Sample code:
package main
import (
"strconv"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/jet"
)
func CustomRoute() *fiber.App {
engine := jet.New("./views", ".jet")
route := fiber.New(fiber.Config{
Views: engine,
})
route.Get("/sample", func (c *fiber.Ctx) error {
return c.Render("main", fiber.Map{
"Title": "Hello, World!",
})
})
return route
}
And compile code or use go mod tidy
will get result:
go: github.com/gofiber/[email protected] requires
github.com/cbroglie/[email protected] requires
github.com/golangci/[email protected] requires
github.com/spf13/[email protected] requires
github.com/gogo/[email protected]/go.mod: verifying module: github.com/gogo/[email protected]/go.mod: malformed record data
Is anybody have same issue to me?
The inner "embed" template is correct, but the layout is shown as text in browser.
Demo repository at: https://github.com/jorgefuertes/fiber-tests
Thanks.
I'm struggled with PUG template using official PUG example like this one:
- var user = {description: 'foo bar baz'}
- var authorised = false
#user
if user.description
h2.green Description
p.description= user.description
else if authorised
h2.blue Description
p.description.
User has no description,
why not add one...
else
h2.red Description
p.description User has no description
I'm getting this error:
template:5: template:9: Error lex: lexClass: expect class name line: 9
Also comparison with ==
operator:
if .someVar== "someValue"
div someVar has someValue
leads to:
template: index:131: unexpected "=" in operand
I have structure of my project:
-public
--static
----resources
------css
-------*css files
----templates
-------*html files
don't know how to call my css files like what I do in mux.
I have 3 files: index.html, layout.html, and a partial/header.html
Using the django engine:
{% extends "./views/layout.html" %}
{% block content %}
CONTENT
{% endblock %}
<!DOCTYPE html>
<html>
<body>
{% include "./views/partials/header.html" %}
{% block content %}{% endblock %}
</body>
</html>
The engine fails with the following error
18:10:17 app | views: [Error (where: fromfile) in views\views\partials\header.html | Line 24 Col 32 near './views/partials/header.html'] unable to resolve template
Looks like it doubles the "views" folder path, and cannot find the partial exists
Hello Gofiber team,
First of all, thank you all for making a great product.
I have encountered a problem that I believe is very serious with gofiber's html package.
I use the sample of the package at https://github.com/gofiber/template, no problem happens. But when I added the layout path to the first router handle, race conditions occurred.
app.Get("/", func(c *fiber.Ctx) error {
// Render index
return c.Render("index", fiber.Map{
"Title": "Hello, World!",
}, "layouts/main")
})
I use the package https://github.com/tsliwowicz/go-wrk to test. The result is as follows:
==================
WARNING: DATA RACE
Read at 0x00c0003ae000 by goroutine 16:
github.com/gofiber/fiber/v2/internal/bytebufferpool.(*ByteBuffer).Write()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/internal/bytebufferpool/bytebuffer.go:73 +0x45
text/template.(*state).walk()
C:/Program Files/Go/src/text/template/exec.go:271 +0x763
text/template.(*state).walk()
C:/Program Files/Go/src/text/template/exec.go:264 +0x1ad
text/template.(*Template).execute()
C:/Program Files/Go/src/text/template/exec.go:220 +0x2fe
text/template.(*Template).Execute()
C:/Program Files/Go/src/text/template/exec.go:203 +0xda
html/template.(*Template).Execute()
C:/Program Files/Go/src/html/template/template.go:124 +0x8a
github.com/gofiber/template/html.(*Engine).Render.func1()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/[email protected]/html/html.go:208 +0x70
runtime.call16()
C:/Program Files/Go/src/runtime/asm_amd64.s:550 +0x44
reflect.Value.Call()
C:/Program Files/Go/src/reflect/value.go:337 +0xe4
text/template.safeCall()
C:/Program Files/Go/src/text/template/funcs.go:365 +0xf9
text/template.(*state).evalCall()
C:/Program Files/Go/src/text/template/exec.go:725 +0x6ee
text/template.(*state).evalFunction()
C:/Program Files/Go/src/text/template/exec.go:580 +0x1de
text/template.(*state).evalCommand()
C:/Program Files/Go/src/text/template/exec.go:467 +0x1ac
text/template.(*state).evalPipeline()
C:/Program Files/Go/src/text/template/exec.go:436 +0x224
text/template.(*state).walk()
C:/Program Files/Go/src/text/template/exec.go:255 +0x571
text/template.(*state).walk()
C:/Program Files/Go/src/text/template/exec.go:264 +0x1ad
text/template.(*Template).execute()
C:/Program Files/Go/src/text/template/exec.go:220 +0x2fe
text/template.(*Template).Execute()
C:/Program Files/Go/src/text/template/exec.go:203 +0xda
html/template.(*Template).Execute()
C:/Program Files/Go/src/html/template/template.go:124 +0x8a
github.com/gofiber/template/html.(*Engine).Render()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/[email protected]/html/html.go:211 +0x3a6
github.com/gofiber/fiber/v2.(*Ctx).Render()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/ctx.go:875 +0x1cf
main.main.func1()
D:/WORK/SelfServe/selfserve.project/test/main.go:24 +0x14e
github.com/gofiber/fiber/v2.(*App).next()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:127 +0x441
github.com/gofiber/fiber/v2.(*App).handler()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:155 +0x1e4
github.com/gofiber/fiber/v2.(*App).handler-fm()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:143 +0x64
github.com/valyala/fasthttp.(*Server).serveConn()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/server.go:2207 +0x1db6
github.com/valyala/fasthttp.(*Server).serveConn-fm()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/server.go:1984 +0x6a
github.com/valyala/fasthttp.(*workerPool).workerFunc()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:223 +0x10b
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x49
Previous write at 0x00c0003ae000 by goroutine 17:
github.com/gofiber/fiber/v2/internal/bytebufferpool.(*ByteBuffer).Write()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/internal/bytebufferpool/bytebuffer.go:73 +0xc4
text/template.(*state).walk()
C:/Program Files/Go/src/text/template/exec.go:271 +0x763
text/template.(*state).walk()
C:/Program Files/Go/src/text/template/exec.go:264 +0x1ad
text/template.(*Template).execute()
C:/Program Files/Go/src/text/template/exec.go:220 +0x2fe
text/template.(*Template).Execute()
C:/Program Files/Go/src/text/template/exec.go:203 +0xda
html/template.(*Template).Execute()
C:/Program Files/Go/src/html/template/template.go:124 +0x8a
github.com/gofiber/template/html.(*Engine).Render()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/[email protected]/html/html.go:211 +0x3a6
github.com/gofiber/fiber/v2.(*Ctx).Render()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/ctx.go:875 +0x1cf
main.main.func1()
D:/WORK/SelfServe/selfserve.project/test/main.go:24 +0x14e
github.com/gofiber/fiber/v2.(*App).next()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:127 +0x441
github.com/gofiber/fiber/v2.(*App).handler()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:155 +0x1e4
github.com/gofiber/fiber/v2.(*App).handler-fm()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:143 +0x64
github.com/valyala/fasthttp.(*Server).serveConn()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/server.go:2207 +0x1db6
github.com/valyala/fasthttp.(*Server).serveConn-fm()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/server.go:1984 +0x6a
github.com/valyala/fasthttp.(*workerPool).workerFunc()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:223 +0x10b
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x49
Goroutine 16 (running) created at:
github.com/valyala/fasthttp.(*workerPool).getCh()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:194 +0x1c4
github.com/valyala/fasthttp.(*workerPool).Serve()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:147 +0x6a6
github.com/valyala/fasthttp.(*Server).Serve()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/server.go:1737 +0x6b5
github.com/gofiber/fiber/v2.(*App).Listen()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/app.go:602 +0x13c
main.main()
D:/WORK/SelfServe/selfserve.project/test/main.go:36 +0x211
Goroutine 17 (running) created at:
github.com/valyala/fasthttp.(*workerPool).getCh()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:194 +0x1c4
github.com/valyala/fasthttp.(*workerPool).Serve()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/workerpool.go:147 +0x6a6
github.com/valyala/fasthttp.(*Server).Serve()
C:/Users/TungDT/go/pkg/mod/github.com/valyala/[email protected]/server.go:1737 +0x6b5
github.com/gofiber/fiber/v2.(*App).Listen()
C:/Users/TungDT/go/pkg/mod/github.com/gofiber/fiber/[email protected]/app.go:602 +0x13c
main.main()
D:/WORK/SelfServe/selfserve.project/test/main.go:36 +0x211
How do I fix this problem?
Also, is there a way to define the layout path one time only to avoid re-define it again inside Render function?
Thanks!
When using an embedded http.Filesystem
partials don't use that filesystem, i.e. the partials are not included.
This is due to the following call:
Lines 137 to 138 in 500f0fd
mustache.ParseString
method eventually callsHi, v1.6.5 currently breaks the embedding support. Running the application with a tool like packr
fails with an error like this:
2020/12/04 23:15:03 stat /web/templates: no such file or directory
panic: stat /web/templates: no such file or directory
goroutine 1 [running]:
log.Panic(0xc0000c1ba8, 0x1, 0x1)
/home/asrivastava/golang/go/src/log/log.go:351 +0xae
github.com/flosch/pongo2/v4.MustNewLocalFileSystemLoader(0xc0031353b0, 0xe, 0x1)
/home/asrivastava/go/pkg/mod/github.com/flosch/pongo2/[email protected]/template_loader.go:27 +0x8a
github.com/gofiber/template/django.(*Engine).Load(0xc001c60870, 0x0, 0x0)
/home/asrivastava/go/pkg/mod/github.com/gofiber/[email protected]/django/django.go:127 +0x11d
Is it possible to parse html files recursive ? Let's say I have this directory structure:
--templates
-------global
-----------header.html
-----------footer.html
-----------navbar.html
-------pages
-----------index.html
-----------about.html
Right now with html.New("./templates", ".html")
It will error with: render: template index does not exist
It would be nice if the html.New would have a recursive option allowing to parse all templates in all subdirectories
๐
How to get go variables for layout or partial include files.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.title}}</title> <!-- layouts file how get go variables -->
</head>
<body>
{{embed}}
</body>
</html>
The error: views: [Error (where: fromfile) in ./partials/desktop_sidebar.html | Line 21 Col 18 near './partials/desktop_sidebar.html'] unable to resolve template
main.html in ./public/layouts folder, the partial is inside another folder called partials in this folder(./partials/):
<html :class="{ 'theme-dark': dark }" x-data="data()" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{pageTitle}}Louve Admin Area</title>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="/assets/admin/css/tailwind.output.css" />
<script src="/assets/admin/js/alpine.min.js" defer></script>
<script src="/assets/admin/js/init-alpine.js"></script>
<link rel="stylesheet" href="/assets/admin/css/Chart.min.css" />
<script src="/assets/admin/js/Chart.min.js" defer></script>
<script src="/assets/admin/js/charts-lines.js" defer></script>
<script src="/assets/admin/js/charts-pie.js" defer></script>
</head>
<body>
<div class="flex h-screen bg-gray-50 dark:bg-gray-900" :class="{ 'overflow-hidden': isSideMenuOpen }">
{% include "partials/desktop_sidebar.html" %} {% include "partials/mobile_sidebar.html" %}
<div class="flex flex-col flex-1 w-full">
{% include "partials/header.html" %} {% block content %}{% endblock %}
</div>
</div>
{% if withModal %} {% include "partials/modal.html" %} {% endif %}
</body>
</html>
It seems that the include syntax is unsupported by pongo2 or there's something wrong with my initialization of the engine?
I did it like this:
engine := django.New("public", ".html"))
I have a public folder like this:
public
-- admin
-- assets
-- layouts
-- partials
-- pub
- admin-index.html
My intention is to separate the admin area templates with actual public templates, does this setup need an embedded filesystem instead of just plain location string?
Hi, thank you for creating this project and especially the latest new feature with pkger
etc.
I was testing with adding functions to django/pongo2 templates but seems its not working. Just for the sake of reproduction I have added a simple pull request with corresponding test here #19
I am writing an app that requires templates and switched to django because handlebars and html templates do not support template inheritance. However <% extends TAG in pongo2 seems to be failing because the baseDir is set to "/" and it uses http.ioFS Open() and that goes to embed.FS Open()... validation fails:
go/src/io/fs/fs.go
// ValidPath reports whether the given path name
// is valid for use in a call to Open.
//
// Path names passed to open are UTF-8-encoded,
// unrooted, slash-separated sequences of path elements, like โx/y/zโ.
// Path names must not contain an element that is โ.โ or โ..โ or the empty string,
// except for the special case that the root directory is named โ.โ.
// Paths must not start or end with a slash: โ/xโ and โx/โ are invalid.
//
// Note that paths are slash-separated on all systems, even Windows.
// Paths containing other characters such as backslash and colon
// are accepted as valid, but those characters must never be
// interpreted by an FS implementation as path element separators.
func ValidPath(name string) bool {
Seems you have fixed the issue:
10138ff
However there is no official release of this fix. TAG?
Using the "template/html" package I am having issues rendering templates that derive a base layout all located in the same directory. I have a base layout template like so:
base.html
{{define "base"}}
<!DOCTYPE html>
<html lang="en">
<body>
header...
{{block "content" .}}{{ end }}
footer...
</body>
</html>
{{end}}
a first page like so which renders fine:
first.html
{{ template "base" .}}
{{define "content"}}
Some content
{{end}}
and a second page like so:
second.html
{{ template "base" .}}
{{define "content"}}
Some more content
{{end}}
My template configuration looks as follows:
engine := html.New("./views", ".html")
engine.Reload(true)
app := fiber.New(fiber.Config{
Views: engine,
})
app.Get("/first", func(c *fiber.Ctx) error {
return c.Render("first", fiber.Map{})
})
app.Get("/second", func(c *fiber.Ctx) error {
return c.Render("second", fiber.Map{})
})
The issue I am encountering is that the second page renders the content of the first. Is this expected behavior in this situation? Normally with "template/html" I would call template.ParseFiles("first.html", "base.html")
for the first template and template.ParseFiles("second.html", "base.html")
for the second template. How exactly does Fiber determine which templates to parse based on the single template name? Thanks!
Attempting to get the Jet driver produces the following error:
~: go get -u -v github.com/gofiber/template/jet
github.com/gofiber/template (download)
github.com/CloudyKit/jet (download)
cannot find package "github.com/CloudyKit/jet/v3" in any of:
/usr/local/Cellar/go/1.15/libexec/src/github.com/CloudyKit/jet/v3 (from $GOROOT)
$HOME/go/src/github.com/CloudyKit/jet/v3 (from $GOPATH)
github.com/gofiber/fiber (download)
github.com/gofiber/utils (download)
github.com/gorilla/schema (download)
github.com/mattn/go-colorable (download)
github.com/mattn/go-isatty (download)
get "golang.org/x/sys/unix": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/unix?go-get=1
get "golang.org/x/sys/unix": verifying non-authoritative meta tag
golang.org/x/sys (download)
get "golang.org/x/sys/internal/unsafeheader": found meta tag get.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at //golang.org/x/sys/internal/unsafeheader?go-get=1
get "golang.org/x/sys/internal/unsafeheader": verifying non-authoritative meta tag
github.com/valyala/bytebufferpool (download)
github.com/valyala/fasthttp (download)
github.com/andybalholm/brotli (download)
github.com/klauspost/compress (download)
github.com/valyala/tcplisten (download)
I am getting these error when running go mod download
.
I didn't install template directly. It could be comes with gofiber
Have tried
rm go.sum
go clean -modcache
go mod tidy
Still doesn't work
github.com/gofiber/[email protected]: verifying module: checksum mismatch
downloaded: h1:4lp4wn3pVr0JVbCrlQl3W5Pi4KBdmO8UUexucx/frtQ=
sum.golang.org: h1:Vf4Fby9zUWVQyY2y69KKyRHsEYlIE+Pxb25M+jiaEL0=
SECURITY ERROR
This download does NOT match the one reported by the checksum server.
The bits may have been replaced on the origin server, or an attacker may
have intercepted the download attempt.
For more information, see 'go help module-auth'.
Hello,
Do you have any plans for supporting EJS?
Thanks.
Hi
I'm in the hunt of a best approach to add assets from build tools like webpack or Vite into the templates.
Most assets are bundled with assets tagged with version e.g index.12345678890.js and is mapped from within the manifest.json file .
And I would like to reference an asset like {{ asset eq "index.js" }} or {{ asset eq "main.css" }} which reads the manifest.json and adds the correct asset to the template .
Generaly speaking, I want to retrieve data from a server without reloading a page. I guess I can write a javascript code with something like get('fiber_api_route/get_data')
and include it in html template. Is there a better way to do is without a need to write js code? The desired way of doing this is to add to html template something like <button onClick=golang_fiber_function!_name>
.
Have a great day
Jacek
is there a function that is executed after template rendering?, for example to minify html
I am use Jet template
This not work:
err := c.Render("index", fiber.Map{
"qwe": "Hello, World ๐!",
})
This work:
err := c.Render("index", map[string]interface{}{
"qwe": "Hello, World ๐!",
})
Script data injection seems to be broken:
Go code:
StreetNumber int
StreetName string
}
type User struct {
Name string
Address Address
}
app.Get("/hello", func(c *fiber.Ctx) error {
return c.Render("views/layouts/index", fiber.Map{
"user": User{
Name: "Tom",
Address: Address{
StreetNumber: 10,
StreetName: "Oaks st",
},
},
})
})
Template code:
<script>
var d = {{{ user }}}
console.log(d);
</script>
template output:
<script>
var d = {Tom {%!s(int=10) Oaks st}}
console.log(d);
</script>
Notice how the json is displayed with internal template codes?
Shouldn't this be the json representation of the data?
I have a file like this in side of my project root views/index.html
. No matter what I try for a path to render the template I get the error template views/index does not exist
, or something of that nature depending on the path I try passing. I tried the same setup with mustache, and it worked fine.
package main
import (
"embed"
"log"
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/django"
)
//go:embed views/*
var viewsfs embed.FS
func main() {
engine := django.NewFileSystem(http.FS(viewsfs), ".html")
app := fiber.New(fiber.Config{
Views: engine,
})
app.Get("/", func(c *fiber.Ctx) error {
// Render index
return c.Render("views/index", fiber.Map{
"Title": "Hello, World!",
})
})
log.Fatal(app.Listen(":3000"))
}
Hello everyone.
I am trying to add a helper function via AddFunc to the handlebars template engine, but it crashes whenever I use this helper (when loading the page from the browser). I am using GO1.17.2 and the lastest packages (just downloaded them to test).
This is a minimal example case where it still crashes:
package main
import (
"github.com/gofiber/template/handlebars"
"github.com/gofiber/fiber/v2"
"math"
"log"
)
func main() {
templateEngine := handlebars.New("./templates", ".html")
templateEngine.Reload(true)
templateEngine.Debug(true) // prints template names when parsed
templateEngine.AddFunc("getLevelFromXP", func(xp uint) uint {
return uint((-87.5+math.Sqrt(87.5*87.5+50.0*float64(xp)))/25)
})
app := fiber.New(fiber.Config {
Views: templateEngine,
})
app.Get("/", func(c *fiber.Ctx) error {
return c.Render("index", nil)
})
log.Fatal(app.Listen(":3000"))
}
The template simply contains {{getLevelFromXP 1200}}
but it is not parsed because even when the index template is missing I still get the crash.
panic: Helper already registered: getLevelFromXP
goroutine 34 [running]:
github.com/aymerick/raymond.RegisterHelper({0xf84a9f, 0xe}, {0xef9b80, 0xfa9d00})
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/aymerick/[email protected]+incompatible/helper.go:43 +0x2a5
github.com/aymerick/raymond.RegisterHelpers(0xf90322)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/aymerick/[email protected]+incompatible/helper.go:55 +0x85
github.com/gofiber/template/handlebars.(*Engine).Load(0xc0003a36c0)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/[email protected]/handlebars/handlebars.go:112 +0xce
github.com/gofiber/template/handlebars.(*Engine).Render(0xc0003a36c0, {0x104f7c0, 0xc0000b5248}, {0xf828be, 0xa}, {0xf167c0, 0xc0004a0840}, {0x0, 0x0, 0x0})
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/[email protected]/handlebars/handlebars.go:184 +0x77
github.com/gofiber/fiber/v2.(*Ctx).Render(0xc0004b6000, {0xf828be, 0xa}, {0xf167c0, 0xc0004a0840}, {0x0, 0x0, 0x0})
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/[email protected]/ctx.go:1004 +0x1af
main.main.func1(0xf0c260)
D:/projects/minimal/main.go:53 +0x245
github.com/gofiber/fiber/v2.(*App).next(0xc0002d6b60, 0xc0004b6000)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:127 +0x1d8
github.com/gofiber/fiber/v2.(*Ctx).Next(0x0)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/[email protected]/ctx.go:747 +0x53
github.com/gofiber/fiber/v2/middleware/logger.New.func2(0xc0004b6000)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/[email protected]/middleware/logger/logger.go:159 +0x1f7
github.com/gofiber/fiber/v2.(*App).next(0xc0002d6b60, 0xc0004b6000)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:127 +0x1d8
github.com/gofiber/fiber/v2.(*App).handler(0xc0002d6b60, 0x8ea577)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/gofiber/fiber/[email protected]/router.go:155 +0xe5
github.com/valyala/fasthttp.(*Server).serveConn(0xc0000c4000, {0x1062350, 0xc000408008})
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/[email protected]/server.go:2278 +0x122d
github.com/valyala/fasthttp.(*workerPool).workerFunc(0xc0000dc3c0, 0xc00040e060)
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/[email protected]/workerpool.go:223 +0xa9
github.com/valyala/fasthttp.(*workerPool).getCh.func1()
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/[email protected]/workerpool.go:195 +0x38
created by github.com/valyala/fasthttp.(*workerPool).getCh
D:/coding/gosdk/go1.17.2/bin/pkg/mod/github.com/valyala/[email protected]/workerpool.go:194 +0x1b5
Any help is appreciated.
I want my layout
to be a template for all my pages. However the
c.Render("index", fiber.Map{
"Title": "Hello, World!",
})
Can only change the content within body
.
I need to change the HTML Title in the header as well.
Any way to do that? thx.
On the about section atleast on this middleware there is still a link to the old fiber.wiki page which is not in use anymore.
The fiber.wiki links should be changed with links to the new documentation site (docs.gofiber.io).
I don't quite understand where I went wrong, but it seems quite logical to me. I made a simple copy for you to see, I am sharing the link below. Can someone help me with where I went wrong?
Dear all,
According to go.sum (line 66), gofiber/template (indirectly) uses few GPL licensed packages, do I understand correctly that if my program uses gofiber/template, then my program must be open sourced under GPL?
gofiber/template (MIT)
|
\|/
github.com/cbroglie/mustache (MIT)
|
\|/
github.com/golangci/golangci-lint (GPL)
|
\|/
github.com/denis-tingajkin/go-header (GPL)
Compare the graph of dependent packages with and without github.com/cbroglie/mustache
:
Hi, I am trying to include partial from a file but seem to have no success.
app := fiber.New()
app.Settings.TemplateEngine = template.Handlebars()
app.Settings.TemplateFolder = "./views"
And in the route I do the following
func consoleDefault(c *fiber.Ctx) {
bind := fiber.Map{
"name": "John",
"age": 35,
}
if err := c.Render("index.hbs", bind); err != nil {
c.Status(500).Send(err.Error())
}
}
My index.hbs includes and renders the name variable currently. But the partial is not working. I have tried with relative paths, with and without extensions and no luck.
I keep getting this error.
I have looked into the Raymond repo and there are no clear examples of how to use it.
Thanks in advance.
views: [Error (where: parser) in <string> | Line 70 Col 62 near '('] '}}' expected
Django engine (pongo2) can not resolve the layout template file with the sample code in this repo. Here's how to reproduce it.
Tested environments
$ git clone --depth=1 [email protected]:gofiber/recipes.git
$ cd recipes/template/
$ go mod vendor && go mod download && go mod tidy
$ cd django/
$ go run main.go
views: [Error (where: fromfile) in ./layouts/main1.html] unable to resolve template
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Fiber v2.0.1 โ
โ http://127.0.0.1:3000 โ
โ โ
โ Handlers ............. 4 Threads ............. 1 โ
โ Prefork ....... Disabled PID .............. 3073 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
If i changed the first in views/index.html
from {% extends "./layouts/main1.html" %}
to {% extends "./views/layouts/main1.html" %}
, then it works. But since we have django.New("./views", ".html")
in main.go
, isn't it expected that pongo2 looks for files under views/
directory and no need to write this directory name in the extends
tag?
Also, with the modified working template file ({% extends "./views/layouts/main1.html" %}
), it failed with embed
package. Sample code below:
package main
import (
"embed"
"log"
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/template/django"
)
//go:embed views/*
var embedDirViews embed.FS
func main() {
// Create a new engine
// engine := django.New("./views", ".html")
engine := django.NewFileSystem(http.FS(embedDirViews), ".html")
// Or from an embedded system
// See github.com/gofiber/embed for examples
// engine := html.NewFileSystem(http.Dir("./views", ".django"))
// Pass the engine to the Views
app := fiber.New(fiber.Config{
Views: engine,
})
app.Get("/", func(c *fiber.Ctx) error {
// Render with and extends
return c.Render("index", fiber.Map{
"Title": "Hello, World!",
})
app.Get("/embed", func(c *fiber.Ctx) error {
// Render index within layouts/main
return c.Render("embed", fiber.Map{
"Title": "Hello, World!",
}, "layouts/main2")
})
log.Fatal(app.Listen(":3000"))
}
No matter how i changed the path in extends
tag, always error like this:
views: [Error (where: fromfile) in ./views/layouts/main1.html] unable to resolve template
The issue is that in jetVarMap
it assumes that a nil binding
should result in a nil jet.VarMap
.
Lines 233 to 237 in c4b2c7e
But if a layout is specified, it is then used to set a function and panics:
Lines 219 to 229 in c4b2c7e
This could be solved either by replacing var bind jet.VarMap
with bind := make(jet.VarMap)
or by checking if bind
is nil (and make
ing it if not) in Render
right after if len(layout) > 0 {
.
// var bind jet.VarMap
bind := make(jet.VarMap)
Or in Render
bind := jetVarMap(binding)
if len(layout) > 0 {
if bind == nil {
bind = make(jet.VarMap)
}
lay, err := e.Templates.GetTemplate(layout[0])
if err != nil {
return err
}
bind.Set(e.layout, func() {
_ = tmpl.Execute(out, bind, nil)
})
return lay.Execute(out, bind, nil)
}
I would send a pull request, but I'm not sure if it matters to you which way it is fixed. I would think it would be much clearer to put it in jetVarMap and get rid of the other calls to make
there, but I guess there was a reason to not do that in the first place.
The work around is for the caller of Render
to just specify an empty jet.VarMap
or fiber.Map
but that is not obvious and panic
ing from forgetting is not great.
Hi! I couldn't find an answer on google or documentation. I want pass template file via variable or function like this:
{% include "./Lumia/partials/primitives/{{Value.GetType()}}.html" with Value=Value only %}
but get error:
views: [Error (where: fromfile) in partials\primitives\{{Value.GetType()}}.html | Line 1 Col 12 near 'partials/primitives/{{Value.GetType()}}.html'] unable to resolve template
Is there any workaround?
When html engine has Reload(true), then rendering multiple times, it fails with 'html/template: cannot Parse after Execute'.
func Test_HTML_Render_Twice(t *testing.T) {
engine := New("./views", ".html")
engine.Reload(true)
engine.AddFunc("isAdmin", func(user string) bool {
return user == "admin"
})
if err := engine.Load(); err != nil {
t.Fatalf("load: %v\n", err)
}
var buf, buf2 bytes.Buffer
engine.Render(&buf, "index", map[string]interface{}{
"Title": "Hello, World!",
}, "layouts/main")
err := engine.Render(&buf2, "index", map[string]interface{}{
"Title": "Hello, World!",
}, "layouts/main")
if err != nil {
fmt.Println(err.Error())
}
expect := `<!DOCTYPE html><html><head><title>Main</title></head><body><h2>Header</h2><h1>Hello, World!</h1><h2>Footer</h2></body></html>`
result := trim(buf2.String())
if expect != result {
t.Fatalf("Expected:\n%s\nResult:\n%s\n", expect, result)
}
}
Example:
package main
import (
"log"
"github.com/gofiber/fiber"
"github.com/gofiber/template/html"
)
func Greeting(greeting string) string {
// set default values -- the proper way
if greeting == "" {
greeting = "<p><b>Rocks!</b></p>"
}
return greeting
}
func main() {
// Initialize standard Go html template engine
engine := html.New("./views", ".html")
app := fiber.New(&fiber.Settings{
Views: engine,
})
app.Get("/", func(c *fiber.Ctx) {
// Render index template
_ = c.Render("index", fiber.Map{
"Greetings": Greeting(""),
})
})
// 404 Handler
app.Use(func(c *fiber.Ctx) {
c.SendStatus(404) // => 404 "Not Found"
})
log.Fatal(app.Listen(3000))
}
index.html
<!DOCTYPE html>
<body>
<b>{{.Greetings}}</b>
</body>
</html>
Due to a small typo-bug the binding interface{}
passed to the Render
funtion is not used when rendering the layout.
I submitted #85 to fix this.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.