2021-12-12 19:09:13 -08:00
|
|
|
package controller
|
2021-12-03 03:11:01 -08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"html/template"
|
|
|
|
"net/http"
|
2021-12-06 11:53:28 -08:00
|
|
|
"time"
|
2021-12-03 03:11:01 -08:00
|
|
|
|
2021-12-15 06:29:43 -08:00
|
|
|
"goweb/context"
|
2021-12-27 07:09:46 -08:00
|
|
|
"goweb/ent"
|
2021-12-23 14:09:44 -08:00
|
|
|
"goweb/htmx"
|
2021-12-03 03:11:01 -08:00
|
|
|
"goweb/msg"
|
|
|
|
|
2021-12-06 18:51:21 -08:00
|
|
|
echomw "github.com/labstack/echo/v4/middleware"
|
2021-12-03 04:53:01 -08:00
|
|
|
|
2021-12-03 03:11:01 -08:00
|
|
|
"github.com/labstack/echo/v4"
|
|
|
|
)
|
|
|
|
|
2021-12-18 13:55:35 -08:00
|
|
|
// Page consists of all data that will be used to render a page response for a given controller.
|
|
|
|
// While it's not required for a controller to render a Page on a route, this is the common data
|
|
|
|
// object that will be passed to the templates, making it easy for all controllers to share
|
|
|
|
// functionality both on the back and frontend. The Page can be expanded to include anything else
|
|
|
|
// your app wants to support.
|
|
|
|
// Methods on this page also then become available in the templates, which can be more useful than
|
|
|
|
// the funcmap if your methods require data stored in the page, such as the context.
|
2021-12-03 03:11:01 -08:00
|
|
|
type Page struct {
|
2021-12-18 13:55:35 -08:00
|
|
|
// AppName stores the name of the application.
|
|
|
|
// If omitted, the configuration value will be used.
|
|
|
|
AppName string
|
|
|
|
|
|
|
|
// Title stores the title of the page
|
|
|
|
Title string
|
|
|
|
|
|
|
|
// Context stores the request context
|
|
|
|
Context echo.Context
|
|
|
|
|
|
|
|
// ToURL is a function to convert a route name and optional route parameters to a URL
|
|
|
|
ToURL func(name string, params ...interface{}) string
|
|
|
|
|
|
|
|
// Path stores the path of the current request
|
|
|
|
Path string
|
|
|
|
|
|
|
|
// URL stores the URL of the current request
|
|
|
|
URL string
|
|
|
|
|
|
|
|
// Data stores whatever additional data that needs to be passed to the templates.
|
|
|
|
// This is what the controller uses to pass the content of the page.
|
|
|
|
Data interface{}
|
|
|
|
|
2021-12-23 05:57:27 -08:00
|
|
|
// Form stores a struct that represents a form on the page.
|
|
|
|
// This should be a struct with fields for each form field, using both "form" and "validate" tags
|
|
|
|
// It should also contain a Submission field of type FormSubmission if you wish to have validation
|
|
|
|
// messagesa and markup presented to the user
|
|
|
|
Form interface{}
|
|
|
|
|
2021-12-18 13:55:35 -08:00
|
|
|
// Layout stores the name of the layout base template file which will be used when the page is rendered.
|
|
|
|
// This should match a template file located within the layouts directory inside the templates directory.
|
|
|
|
// The template extension should not be included in this value.
|
|
|
|
Layout string
|
|
|
|
|
|
|
|
// Name stores the name of the page as well as the name of the template file which will be used to render
|
|
|
|
// the content portion of the layout template.
|
|
|
|
// This should match a template file located within the pages directory inside the templates directory.
|
|
|
|
// The template extension should not be included in this value.
|
|
|
|
Name string
|
|
|
|
|
|
|
|
// IsHome stores whether the requested page is the home page or not
|
|
|
|
IsHome bool
|
|
|
|
|
|
|
|
// IsAuth stores whether or not the user is authenticated
|
|
|
|
IsAuth bool
|
|
|
|
|
2021-12-27 07:09:46 -08:00
|
|
|
// AuthUser stores the authenticated user
|
|
|
|
AuthUser *ent.User
|
|
|
|
|
2021-12-18 13:55:35 -08:00
|
|
|
// StatusCode stores the HTTP status code that will be returned
|
2021-12-03 03:11:01 -08:00
|
|
|
StatusCode int
|
2021-12-18 13:55:35 -08:00
|
|
|
|
|
|
|
// Metatags stores metatag values
|
|
|
|
Metatags struct {
|
|
|
|
// Description stores the description metatag value
|
2021-12-03 03:11:01 -08:00
|
|
|
Description string
|
2021-12-18 13:55:35 -08:00
|
|
|
|
|
|
|
// Keywords stores the keywords metatag values
|
|
|
|
Keywords []string
|
2021-12-03 03:11:01 -08:00
|
|
|
}
|
2021-12-18 13:55:35 -08:00
|
|
|
|
|
|
|
// Pager stores a pager which can be used to page lists of results
|
|
|
|
Pager Pager
|
|
|
|
|
|
|
|
// CSRF stores the CSRF token for the given request.
|
|
|
|
// This will only be populated if the CSRF middleware is in effect for the given request.
|
|
|
|
// If this is populated, all forms must include this value otherwise the requests will be rejected.
|
|
|
|
CSRF string
|
|
|
|
|
|
|
|
// Headers stores a list of HTTP headers and values to be set on the response
|
2021-12-07 18:36:57 -08:00
|
|
|
Headers map[string]string
|
2021-12-18 13:55:35 -08:00
|
|
|
|
|
|
|
// RequestID stores the ID of the given request.
|
|
|
|
// This will only be populated if the request ID middleware is in effect for the given request.
|
|
|
|
RequestID string
|
|
|
|
|
2021-12-23 14:09:44 -08:00
|
|
|
HTMX struct {
|
|
|
|
Request htmx.Request
|
|
|
|
Response *htmx.Response
|
|
|
|
}
|
|
|
|
|
2021-12-18 13:55:35 -08:00
|
|
|
// Cache stores values for caching the response of this page
|
|
|
|
Cache struct {
|
|
|
|
// Enabled dictates if the response of this page should be cached.
|
|
|
|
// Cached responses are served via middleware.
|
|
|
|
Enabled bool
|
|
|
|
|
|
|
|
// Expiration stores the amount of time that the cache entry should live for before expiring.
|
|
|
|
// If omitted, the configuration value will be used.
|
2021-12-11 16:32:34 -08:00
|
|
|
Expiration time.Duration
|
2021-12-18 13:55:35 -08:00
|
|
|
|
|
|
|
// Tags stores a list of tags to apply to the cache entry.
|
|
|
|
// These are useful when invalidating cache for dynamic events such as entity operations.
|
|
|
|
Tags []string
|
2021-12-05 18:56:57 -08:00
|
|
|
}
|
2021-12-03 03:11:01 -08:00
|
|
|
}
|
|
|
|
|
2021-12-18 15:08:04 -08:00
|
|
|
// NewPage creates and initiatizes a new Page for a given request context
|
|
|
|
func NewPage(ctx echo.Context) Page {
|
2021-12-03 03:11:01 -08:00
|
|
|
p := Page{
|
2021-12-18 15:08:04 -08:00
|
|
|
Context: ctx,
|
|
|
|
ToURL: ctx.Echo().Reverse,
|
|
|
|
Path: ctx.Request().URL.Path,
|
|
|
|
URL: ctx.Request().URL.String(),
|
2021-12-03 03:11:01 -08:00
|
|
|
StatusCode: http.StatusOK,
|
2021-12-18 15:08:04 -08:00
|
|
|
Pager: NewPager(ctx, DefaultItemsPerPage),
|
2021-12-07 18:36:57 -08:00
|
|
|
Headers: make(map[string]string),
|
2021-12-18 15:08:04 -08:00
|
|
|
RequestID: ctx.Response().Header().Get(echo.HeaderXRequestID),
|
2021-12-03 03:11:01 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
p.IsHome = p.Path == "/"
|
|
|
|
|
2021-12-18 15:08:04 -08:00
|
|
|
if csrf := ctx.Get(echomw.DefaultCSRFConfig.ContextKey); csrf != nil {
|
2021-12-03 04:53:01 -08:00
|
|
|
p.CSRF = csrf.(string)
|
|
|
|
}
|
|
|
|
|
2021-12-18 15:08:04 -08:00
|
|
|
if u := ctx.Get(context.AuthenticatedUserKey); u != nil {
|
2021-12-12 14:04:11 -08:00
|
|
|
p.IsAuth = true
|
2021-12-27 07:09:46 -08:00
|
|
|
p.AuthUser = u.(*ent.User)
|
2021-12-12 14:04:11 -08:00
|
|
|
}
|
|
|
|
|
2021-12-23 14:09:44 -08:00
|
|
|
p.HTMX.Request = htmx.GetRequest(ctx)
|
|
|
|
|
2021-12-03 03:11:01 -08:00
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2021-12-18 13:55:35 -08:00
|
|
|
// GetMessages gets all flash messages for a given type.
|
|
|
|
// This allows for easy access to flash messages from the templates.
|
2021-12-03 03:11:01 -08:00
|
|
|
func (p Page) GetMessages(typ msg.Type) []template.HTML {
|
|
|
|
strs := msg.Get(p.Context, typ)
|
|
|
|
ret := make([]template.HTML, len(strs))
|
|
|
|
for k, v := range strs {
|
|
|
|
ret[k] = template.HTML(v)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|