Cleaned up conditional rendering.
This commit is contained in:
parent
02236266f1
commit
c8db468292
5 changed files with 71 additions and 56 deletions
|
|
@ -27,17 +27,13 @@ func JS(r *ui.Request) Node {
|
||||||
})
|
})
|
||||||
`
|
`
|
||||||
|
|
||||||
var csrf Node
|
|
||||||
|
|
||||||
if len(r.CSRF) > 0 {
|
|
||||||
csrf = Script(Raw(fmt.Sprintf(htmxCSRF, r.CSRF)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return Group{
|
return Group{
|
||||||
Script(Src("https://unpkg.com/htmx.org@2.0.0/dist/htmx.min.js")),
|
Script(Src("https://unpkg.com/htmx.org@2.0.0/dist/htmx.min.js")),
|
||||||
Script(Src("https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"), Defer()),
|
Script(Src("https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"), Defer()),
|
||||||
Script(Raw(htmxErr)),
|
Script(Raw(htmxErr)),
|
||||||
csrf,
|
Iff(len(r.CSRF) > 0, func() Node {
|
||||||
|
return Script(Raw(fmt.Sprintf(htmxCSRF, r.CSRF)))
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,10 @@ func About(ctx echo.Context) error {
|
||||||
Title: "Ent",
|
Title: "Ent",
|
||||||
Body: "Simple, yet powerful ORM for modeling and querying data. Visit <a href=\"https://entgo.io/\">entgo.io</a> to learn more.",
|
Body: "Simple, yet powerful ORM for modeling and querying data. Visit <a href=\"https://entgo.io/\">entgo.io</a> to learn more.",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Title: "Gomponents",
|
||||||
|
Body: "HTML components written in pure Go. They render to HTML 5, and make it easy for you to build reusable components. Visit <a href=\"https://gomponents.com/\">gomponents.com</a> to learn more.",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,26 +15,27 @@ func ContactUs(ctx echo.Context, form *forms.Contact) error {
|
||||||
r.Title = "Contact us"
|
r.Title = "Contact us"
|
||||||
r.Metatags.Description = "Get in touch with us."
|
r.Metatags.Description = "Get in touch with us."
|
||||||
|
|
||||||
g := make(Group, 0)
|
g := Group{
|
||||||
|
Iff(r.Htmx.Target != "contact", func() Node {
|
||||||
if r.Htmx.Target != "contact" {
|
return components.Message(
|
||||||
g = append(g, components.Message(
|
"is-link",
|
||||||
"is-link",
|
"",
|
||||||
"",
|
Group{
|
||||||
Group{
|
P(Text("This is an example of a form with inline, server-side validation and HTMX-powered AJAX submissions without writing a single line of JavaScript.")),
|
||||||
P(Text("This is an example of a form with inline, server-side validation and HTMX-powered AJAX submissions without writing a single line of JavaScript.")),
|
P(Text("Only the form below will update async upon submission.")),
|
||||||
P(Text("Only the form below will update async upon submission.")),
|
},
|
||||||
}))
|
)
|
||||||
}
|
}),
|
||||||
|
Iff(form.IsDone(), func() Node {
|
||||||
if form.IsDone() {
|
return components.Message(
|
||||||
g = append(g, components.Message(
|
"is-large is-success",
|
||||||
"is-large is-success",
|
"Thank you!",
|
||||||
"Thank you!",
|
Text("No email was actually sent but this entire operation was handled server-side and degrades without JavaScript enabled."),
|
||||||
Text("No email was actually sent but this entire operation was handled server-side and degrades without JavaScript enabled."),
|
)
|
||||||
))
|
}),
|
||||||
} else {
|
Iff(!form.IsDone(), func() Node {
|
||||||
g = append(g, form.Render(r))
|
return form.Render(r)
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.Render(layouts.Primary, g)
|
return r.Render(layouts.Primary, g)
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,25 @@ func Home(ctx echo.Context, posts *models.Posts) error {
|
||||||
r.Metatags.Description = "This is the home page."
|
r.Metatags.Description = "This is the home page."
|
||||||
r.Metatags.Keywords = []string{"Software", "Coding", "Go"}
|
r.Metatags.Keywords = []string{"Software", "Coding", "Go"}
|
||||||
|
|
||||||
g := make(Group, 0)
|
// This pages helps to illustrate the different options you can take when using HTMX to introduce interactivity
|
||||||
|
// to your web application. The following three options are available, but here, we're opting for the first one.
|
||||||
|
// 1) Highly-optimized and progressive enhancement:
|
||||||
|
// This is highly-optimized because the server is doing the least amount of work possible, only rendering
|
||||||
|
// the least amount possible based on the incoming request. It's possible that even your route handler would
|
||||||
|
// want to check the HTMX request in order to limit what it does. With HTMX, it's possible to still return a
|
||||||
|
// normal, full page, but use hx-select to pluck out only the part you want to re-render. It requires some extra
|
||||||
|
// condition checks and code but performance is improved. Progressive enhancement refers to having a fully
|
||||||
|
// functional web app, even if JS was disabled, but providing the enhancement if JS is enabled. All of these
|
||||||
|
// examples should continue to work fine without JS.
|
||||||
|
// 2) Not optimized and progressive enhancement:
|
||||||
|
// As mentioned previously, you can remove all of these conditions, re-render the entire page for every request,
|
||||||
|
// and rely on HTMX's hx-select to only replace what you want to (ie, the posts).
|
||||||
|
// 3) Optimized and partial renderings:
|
||||||
|
// You could have a separate route that is only for fetching posts while paging, and that would render only
|
||||||
|
// that partial HTML, which HTMX would then use to inject in to this page.
|
||||||
|
|
||||||
if r.Htmx.Target != "posts" {
|
headerMsg := func() Node {
|
||||||
var hello string
|
return Group{
|
||||||
if r.IsAuth {
|
|
||||||
hello = fmt.Sprintf("Hello, %s", r.AuthUser.Name)
|
|
||||||
} else {
|
|
||||||
hello = "Hello"
|
|
||||||
}
|
|
||||||
|
|
||||||
g = append(g,
|
|
||||||
Section(
|
Section(
|
||||||
Class("hero is-info welcome is-small mb-5"),
|
Class("hero is-info welcome is-small mb-5"),
|
||||||
Div(
|
Div(
|
||||||
|
|
@ -37,7 +45,10 @@ func Home(ctx echo.Context, posts *models.Posts) error {
|
||||||
Class("container"),
|
Class("container"),
|
||||||
H1(
|
H1(
|
||||||
Class("title"),
|
Class("title"),
|
||||||
Text(hello),
|
Iff(r.IsAuth, func() Node {
|
||||||
|
return Text(fmt.Sprintf("Hello, %s", r.AuthUser.Name))
|
||||||
|
}),
|
||||||
|
If(!r.IsAuth, Text("Hello")),
|
||||||
),
|
),
|
||||||
H2(
|
H2(
|
||||||
Class("subtitle"),
|
Class("subtitle"),
|
||||||
|
|
@ -49,20 +60,24 @@ func Home(ctx echo.Context, posts *models.Posts) error {
|
||||||
),
|
),
|
||||||
H2(Class("title"), Text("Recent posts")),
|
H2(Class("title"), Text("Recent posts")),
|
||||||
H3(Class("subtitle"), Text("Below is an example of both paging and AJAX fetching using HTMX")),
|
H3(Class("subtitle"), Text("Below is an example of both paging and AJAX fetching using HTMX")),
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g = append(g, posts.Render(r.Path(routenames.Home)))
|
filesMsg := func() Node {
|
||||||
|
return Message(
|
||||||
if r.Htmx.Target != "posts" {
|
|
||||||
g = append(g, Message(
|
|
||||||
"is-small is-warning mt-5",
|
"is-small is-warning mt-5",
|
||||||
"Serving files",
|
"Serving files",
|
||||||
Group{
|
Group{
|
||||||
Text("In the example posts above, check how the file URL contains a cache-buster query parameter which changes only when the app is restarted. "),
|
Text("In the example posts above, check how the file URL contains a cache-buster query parameter which changes only when the app is restarted. "),
|
||||||
Text("Static files also contain cache-control headers which are configured via middleware."),
|
Text("Static files also contain cache-control headers which are configured via middleware."),
|
||||||
},
|
},
|
||||||
))
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
g := Group{
|
||||||
|
Iff(r.Htmx.Target != "posts", headerMsg),
|
||||||
|
posts.Render(r.Path(routenames.Home)),
|
||||||
|
Iff(r.Htmx.Target != "posts", filesMsg),
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.Render(layouts.Primary, g)
|
return r.Render(layouts.Primary, g)
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,18 @@ func AddTask(ctx echo.Context, form *forms.Task) error {
|
||||||
r.Title = "Create a task"
|
r.Title = "Create a task"
|
||||||
r.Metatags.Description = "Test creating a task to see how it works."
|
r.Metatags.Description = "Test creating a task to see how it works."
|
||||||
|
|
||||||
g := make(Group, 0)
|
g := Group{
|
||||||
|
Iff(r.Htmx.Target != "task", func() Node {
|
||||||
if r.Htmx.Target != "task" {
|
return components.Message(
|
||||||
g = append(g, components.Message(
|
"is-link",
|
||||||
"is-link",
|
"",
|
||||||
"",
|
Group{
|
||||||
Group{
|
P(Raw("Submitting this form will create an <i>ExampleTask</i> in the task queue. After the specified delay, the message will be logged by the queue processor.")),
|
||||||
P(Raw("Submitting this form will create an <i>ExampleTask</i> in the task queue. After the specified delay, the message will be logged by the queue processor.")),
|
P(Text("See pkg/tasks and the README for more information.")),
|
||||||
P(Text("See pkg/tasks and the README for more information.")),
|
})
|
||||||
}))
|
}),
|
||||||
|
form.Render(r),
|
||||||
}
|
}
|
||||||
|
|
||||||
g = append(g, form.Render(r))
|
|
||||||
|
|
||||||
return r.Render(layouts.Primary, g)
|
return r.Render(layouts.Primary, g)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue