Repository: gofiber/fiber
File: ctx.go (Go)

Code before:
	c.setCanonical(HeaderLocation, location)
	if len(status) > 0 {
		c.Status(status[0])
	} else {
		c.Status(StatusFound)
	}
	return nil
}

// Render a template with data and sends a text/html response.
// We support the following engines: html, amber, handlebars, mustache, pug
func (c *Ctx) Render(name string, bind interface{}, layouts ...string) error {
	var err error
	// Get new buffer from pool
	buf := bytebufferpool.Get()
	defer bytebufferpool.Put(buf)

	// Check if the PassLocalsToViews option is enabled (By default it is disabled)
	if c.app.config.PassLocalsToViews {
		// Safely cast the bind interface to a map
		bindMap, ok := bind.(Map)
		// Check if the bind is a map
		if ok {
			// Loop through each local and set it in the map
			c.fasthttp.VisitUserValues(func(key []byte, val interface{}) {
				bindMap[string(key)] = val
			})
			// set the original bind to the map
			bind = bindMap
		}

	}

	if c.app.config.Views != nil {
		// Render template based on global layout if exists
		if len(layouts) == 0 && c.app.config.ViewsLayout != "" {
			layouts = []string{
				c.app.config.ViewsLayout,
			}
		}
		// Render template from Views
		if err := c.app.config.Views.Render(buf, name, bind, layouts...); err != nil {
			return err
		}
	} else {
		// Render raw template using 'name' as filepath if no engine is set
		var tmpl *template.Template
		if _, err = readContent(buf, name); err != nil {
			return err
		}
		// Parse template

Review comment (suggestion):
the map that is being handed in should only be expanded, not completely replaced

furthermore the values which are given directly to the render function should have more value

i.e. a value which is in the locals with key "abc" and one which is directly passed to the render function, the one which is passed to the render function should win

Code after:
	c.setCanonical(HeaderLocation, location)
	if len(status) > 0 {
		c.Status(status[0])
	} else {
		c.Status(StatusFound)
	}
	return nil
}

// Render a template with data and sends a text/html response.
// We support the following engines: html, amber, handlebars, mustache, pug
func (c *Ctx) Render(name string, bind interface{}, layouts ...string) error {
	var err error
	// Get new buffer from pool
	buf := bytebufferpool.Get()
	defer bytebufferpool.Put(buf)

	// Check if the PassLocalsToViews option is enabled (By default it is disabled)
	if c.app.config.PassLocalsToViews {
		// Safely cast the bind interface to a map
		bindMap, ok := bind.(Map)
		// Check if the bind is a map
		if ok {
			// Loop through each local and set it in the map
			c.fasthttp.VisitUserValues(func(key []byte, val interface{}) {
				// check if bindMap doesn't contain the key
				if _, ok := bindMap[string(key)]; !ok {
					// Set the key and value in the bindMap
					bindMap[string(key)] = val
				}
			})
			// set the original bind to the map
			bind = bindMap
		}

	}

	if c.app.config.Views != nil {
		// Render template based on global layout if exists
		if len(layouts) == 0 && c.app.config.ViewsLayout != "" {
			layouts = []string{
				c.app.config.ViewsLayout,
			}
		}
		// Render template from Views
		if err := c.app.config.Views.Render(buf, name, bind, layouts...); err != nil {
			return err
		}
	} else {
		// Render raw template using 'name' as filepath if no engine is set
		var tmpl *template.Template