Fiber: 馃挕 Changing the Template system

Created on 30 Apr 2020  路  6Comments  路  Source: gofiber/fiber

I'm writing this issue publicly so that everyone using Fiber can share their opinion regarding this matter. The way it currently works is very limited, outdated and not stable (https://github.com/gofiber/fiber/issues/277, https://github.com/gofiber/fiber/issues/330, https://github.com/gofiber/fiber/pull/320, https://github.com/gofiber/fiber/issues/190, https://github.com/gofiber/fiber/issues/182)

Fiber currently has one render function that parses a template file and executes the given bind values.

app.Get("/", func(c *fiber.Ctx) {
  c.Render("./views/index.tmpl", fiber.Map{
    "title":   "Homepage",
    "counter": 9000,
  })
})

With some simple app settings you can suger-coat the syntax by pre-defining the template folder, extension and parser (if you are using the gofiber/template middleware).

app := fiber.New(&fiber.Settings{
    TemplateEngine:    template.Mustache(),
    TemplateFolder:    "./views",
    TemplateExtension: ".tmpl",
})
app.Get("/", func(c *fiber.Ctx) {
  c.Render("index", fiber.Map{
    "title":   "Homepage",
    "counter": 9000,
  })
})

You can see that this is a limited template system that doesn't have support for custom functions or partials to include multiple files for one template which is a must have for front-end developers.

I would like to re-think the way we handle/register templates/views and code a better, solid and a more flexible system that supports custom template functions, partials and caching but still support different template engines like amber, handlebars, mustache or pug.

Here is a bundled list of other Go frameworks and their template logic for inspiration.

I would love to hear your ideas on how our next template/view syntax should look like and bring it into production 馃挭

馃毃 High Priority

Most helpful comment

v1.10.0 contains the new Templates interface, see https://github.com/gofiber/template for examples.

All 6 comments

I really much like the way Laravel implemented their Laravel Blade templating system. It allows code executing in a template, as well as escaping HTML characters to reduce injection attack-surface and has zero overhead to the application.
It's written in PHP, but I like their approach to templating. Personally, I do use Mustache for templating but also miss some features Laravel Blade offers. I'll get back to you about the templating logic implemented by other Go Web Frameworks.

EDIT: Some examples as requested: https://laravel.com/docs/7.x/blade

Hey,

About me : I am not a guru in golang, but a php developer. I have played a bit with Beego building website. Also tried buffallo. ie my background.

In expressive now mezzio it tries to bring multiple template engines. The way you mentioned in the fiber template is what it also does behind the scenes. But it also add another feature like namespace and adding multiple paths.

So if you add a path $renderer->addPath('templates/error/', 'error'); then error namespace get preference if you try $content = $renderer->render('error::404'); .

Else it will try looking at multiple locations.

Source : https://github.com/mezzio/mezzio-template

You can see that this is a limited template system that doesn't have support for custom functions or partials to include multiple files for one template which is a must have for front-end developers.

I think we cannot provide a generic way to create custom functions. To my believe this part depends on the templating system the user choose.

May be if we can expose the templating systems object it may help to add custom functions on initialization ?

Mainly, in-line functions using templating in Go is a difficult job to do just right. Therefore, just like Node, templating commonly has the ability to add Template Functions to a specific template.
I like you approach on having a seperate template directory for server-side errors, I also do this when creating applications as well as a seperate directory for a back-end or commonly nested imports like headers and footers.
However, I don't see the point in having to specify this sub-directory; instead I'd rather see something like this:

$renderer->path('views/', "views");
$content = $renderer->render("views/errors/404.extension", $data);

I also know that @Fenny was working on improving our current templating API, so maybe he has some ideas about Nested templates as well.

I would think that the renderer should be an interface, take a look at the way Echo and Ship do it for instance.

This would mean that the fiber team can implement out-of-the-box template systems which match the interface, and end users can implement other more esoteric template systems if required.

a simple interface copied from Echo :

// Renderer is the interface that wraps the Render function.
Renderer interface {
    Render(io.Writer, string, interface{}, fiber.Ctx) error
}

A naive implementation for Unrolled/render would look something like:

type Urender struct{
    r *render.Render
}

func (u *Urender) Render(w io.Write, name string, data interface{}, ctx *fiber.Ctx) error{
    i:=ctx.Locals("__template")
    if i != nil{
        return u.HTML(w, name, data, render.HTMLOptions{Layout: i.(string)}) // allow for template overrides
    }

    return u.HTML(w, name, data)
}

Creating an instance of the renderer would look like:

renderer:=&Urender{
    r: render.New(render.Options{
        IsDevelopment: os.Getenv("RUNMODE")=="DEV",
        Directory: "views",
        Layout: "layouts/master",
        Extensions:[]string{".html"},
        Funcs:[]template.FuncMap{
            template.FuncMap:{
                "html": func(s string) template.HTML {
            return template.HTML(s)
        },
            },
        },
    },
}

In think if fiber use twig, it will be great.I am new in fiber,I want to render a template without mustache and with native go "html/template" package is there any example , how to do that?

v1.10.0 contains the new Templates interface, see https://github.com/gofiber/template for examples.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Aguezz picture Aguezz  路  4Comments

GrigoriyMikhalkin picture GrigoriyMikhalkin  路  4Comments

jeyraj picture jeyraj  路  4Comments

renatojf picture renatojf  路  3Comments

Terisback picture Terisback  路  3Comments