Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to change layout Title #31

Closed
suntong opened this issue Aug 8, 2020 · 17 comments
Closed

How to change layout Title #31

suntong opened this issue Aug 8, 2020 · 17 comments
Labels
🤔 Question Further information is requested

Comments

@suntong
Copy link

suntong commented Aug 8, 2020

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.

@suntong
Copy link
Author

suntong commented Aug 8, 2020

I first drafted this question here, but asked in fiber eventually.

However, having closed it on fiber, and thinking back, I think this is still an valid question/issue -- people need their layout to be a template for all their pages, and they need to change the HTML Title for every page.

So, would be OK that I change the default html template to satisfy this, so that the next people won't need to wonder again? If I did so, would you accept the PR?

@belliel
Copy link

belliel commented Aug 14, 2020

I have same problem.
So, do u know how to set variables in several places?

How to change layout in several places

@suntong
Copy link
Author

suntong commented Aug 15, 2020

Hi @Fenny,

Please advice -- now it is more than me facing the same problem. (I kind of solve it a hacky way, but don't want to miss-lead people).

@thomasvvugt
Copy link

May I ask what template engine you are using? From my previous experience, I can tell that handlebars was replacing variables in any part of the view.

@belliel
Copy link

belliel commented Aug 15, 2020

May I ask what template engine you are using? From my previous experience, I can tell that handlebars was replacing variables in any part of the view.

django

@thomasvvugt
Copy link

Hi @suntong and @BellZaph, rendering templates using the django engine seems to work fine on my end.
Can you provide a minimal code example to reproduce this issue? See my code examples below.

main.go

package main

import (
	"github.com/gofiber/fiber"
	"github.com/gofiber/template/django"
)

func main() {
	engine := django.New("./views", ".django")

	// Pass the engine to the Views
	app := fiber.New(&fiber.Settings{
		Views: engine,
	})

	app.Get("/", func(c *fiber.Ctx) {
		// Render index
		_ = c.Render("index", fiber.Map{
			"Title": "Index!",
		})
	})

	_ = app.Listen(8080)
}

views/index.django

<!DOCTYPE html>
<html>

<head>
  <title>{{ Title }}</title>
</head>

<body>
  <h1>{{ Title }}</h1>
</body>

</html>

Thanks for bringing up the issue! 🚀

@suntong
Copy link
Author

suntong commented Aug 15, 2020

Thanks for the working demo for @BellZaph, @thomasvvugt.

My question was for html template, to be specifically, about these lines

<head>
<title>Main</title>
</head>

I.e., how to change the Title for the layout file. Thx.

@fuadarradhi
Copy link

for global, use function engine

engine.AddFunc("title", func() string {
    return "this is title"
})
<head> 
   <title>{{ title() }}</title> 
 </head>

@suntong
Copy link
Author

suntong commented Aug 16, 2020

Thanks!

If that's the only solution, then I think my hacky one is better, :)
But still, because it is really hacky, I want to make sure there is no more better options first.

@thomasvvugt
Copy link

Hi @suntong, the html package can also context with provided data, see; https://golang.org/pkg/html/template/

The example @fuadarradhi showed can be simplified by using the {{.}} parameters;

main.go

package main

import (
	"github.com/gofiber/fiber"
	"github.com/gofiber/template/html"
)

func main() {
	engine := html.New("./views", ".html")

	app := fiber.New(&fiber.Settings{
		Views: engine,
	})

	app.Get("/", func(c *fiber.Ctx) {
		// Render index
		c.Render("index", fiber.Map{
			"Title": "Index!",
		})
	})

	app.Listen(8080)
}

views/index.html

<!DOCTYPE html>
<html>

<head>
    <title>{{ .Title }}</title>
</head>

<body>
<h1>{{ .Title }}</h1>
</body>

</html>

Keep in mind: HTML templates treat data values as plain text which should be encoded so they can be safely embedded in an HTML document. The escaping is contextual, so actions can appear within JavaScript, CSS, and URI contexts.

You should always escape your data if not already sanitized, the HTML templates provides several functions for this; https://golang.org/pkg/html/template/#hdr-Contexts

Once again, thanks for bringing up the issue. Let me know if my example helps you out or leaves you with additional questions! 🔥

@belliel
Copy link

belliel commented Aug 16, 2020

Hey guys
Thanks for answer
I thought it works different than original Django/template
Now all fine

@suntong
Copy link
Author

suntong commented Aug 16, 2020

Thanks for the working demo for @BellZaph, @thomasvvugt.

My question was for html template, to be specifically, about these lines

<head>
<title>Main</title>
</head>

I.e., how to change the Title for the layout file. Thx.

Hmm... let me stress again that my question is

how to change the Title for the layout file

yet, @thomasvvugt, both of your demo code are not using the layout file. So let me be specific

./views/index.html

{{template "partials/header" .}}

<h1>{{.Title}}</h1>

{{template "partials/footer" .}}

./views/partials/header.html

<h2>Header</h2>

./views/partials/footer.html

<h2>Footer</h2>

./views/layouts/main.html

<!DOCTYPE html>
<html>

<head>
  <title>Main</title>
</head>

<body>
  {{embed}}
</body>

</html>
package main

import (
	"github.com/gofiber/fiber"
	"github.com/gofiber/template/html"
)

func main() {
	// Create a new engine
	engine := html.New("./views", ".html")

	// Pass the engine to the Views
	app := fiber.New(&fiber.Settings{
		Views: engine,
	})

	app.Get("/", func(c *fiber.Ctx) {
		// Render index
		c.Render("index", fiber.Map{
			"Title": "Hello, World!",
		})
	})

	app.Get("/layout", func(c *fiber.Ctx) {
		// Render index within layouts/main
		c.Render("index", fiber.Map{
			"Title": "Hello, World!",
		}, "layouts/main")
	})

	app.Listen(3000)
}

The two app.Get above, one is using layout file and one is not. my question is how to change the Title for the layout file. I.e., the piece called with

	app.Get("/layout", func(c *fiber.Ctx) {
		// Render index within layouts/main
		c.Render("index", fiber.Map{
			"Title": "Hello, World!",
		}, "layouts/main")

thx

@ReneWerner87 ReneWerner87 added the 🤔 Question Further information is requested label Aug 16, 2020
@fuadarradhi
Copy link

@suntong
for single route, changing the layout file is the same as changing the body,
my previous example is for global route, if you not want pass title for every route

<!DOCTYPE html>
<html>

<head>
  <title>{{.Title}}</title>
</head>

<body>
  {{embed}}
</body>

</html>

@suntong
Copy link
Author

suntong commented Aug 17, 2020

wow, I should have tried -- I thought it is not possible, and now I'm embarrassed, :).

@suntong suntong closed this as completed Aug 17, 2020
@edimoldovan
Copy link

edimoldovan commented Apr 17, 2022

Is this above still a valid solution? I am passing PageTitle but my render fails with this error

views: Parse error on line 7:
Expecting ID, got: 'Sep{"."}'

or

views: Parse error on line 7:
Expecting ID, got: 'Sep{"."}'

Relevant hbs code

<title>{{.Title}}</title>

and the corresponding route

app.Get("/", func(c *fiber.Ctx) error {
    return c.Render("index", fiber.Map{
        "PageTitle": "blog",
    }, "layouts/main")
})

@suntong
Copy link
Author

suntong commented Apr 18, 2022

What's your views file of line 7?

@edimoldovan
Copy link

edimoldovan commented Apr 21, 2022

@suntong This is my view

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>{{ .Title }}</title>
  <meta name="description" content="Writing about releasing. Among other things.">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="/public/favicon.png">
  <link rel="stylesheet" href="/public/style.min.css">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet"> 
</head>
<body>
  <div id="wrapper" class="wrapper">
    {{embed}}
  </div>
</body>
</html>

On line 7 I have

<title>{{ .Title }}</title>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤔 Question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants