builder.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package web
  2. import (
  3. "bytes"
  4. "context"
  5. "net/http"
  6. "time"
  7. "github.com/NYTimes/gziphandler"
  8. h "github.com/theplant/htmlgo"
  9. )
  10. type Builder struct {
  11. EventsHub
  12. layoutFunc LayoutFunc
  13. }
  14. func New() (b *Builder) {
  15. b = new(Builder)
  16. b.layoutFunc = defaultLayoutFunc
  17. return
  18. }
  19. func (b *Builder) LayoutFunc(mf LayoutFunc) (r *Builder) {
  20. if mf == nil {
  21. panic("layout func is nil")
  22. }
  23. b.layoutFunc = mf
  24. return b
  25. }
  26. func (p *Builder) EventFuncs(vs ...interface{}) (r *Builder) {
  27. p.addMultipleEventFuncs(vs...)
  28. return p
  29. }
  30. type ComponentsPack string
  31. var startTime = time.Now()
  32. func PacksHandler(contentType string, packs ...ComponentsPack) http.Handler {
  33. return Default.PacksHandler(contentType, packs...)
  34. }
  35. func (b *Builder) PacksHandler(contentType string, packs ...ComponentsPack) http.Handler {
  36. var buf = bytes.NewBuffer(nil)
  37. for _, pk := range packs {
  38. // buf = append(buf, []byte(fmt.Sprintf("\n// pack %d\n", i+1))...)
  39. // buf = append(buf, []byte(fmt.Sprintf("\nconsole.log('pack %d, length %d');\n", i+1, len(pk)))...)
  40. buf.WriteString(string(pk))
  41. buf.WriteString("\n\n")
  42. }
  43. body := bytes.NewReader(buf.Bytes())
  44. return gziphandler.GzipHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  45. w.Header().Set("Content-Type", contentType)
  46. http.ServeContent(w, r, "", startTime, body)
  47. }))
  48. }
  49. func NoopLayoutFunc(r *http.Request, injector *PageInjector, body string) (output string, err error) {
  50. output = body
  51. return
  52. }
  53. func defaultLayoutFunc(r *http.Request, injector *PageInjector, body string) (output string, err error) {
  54. root := h.HTMLComponents{
  55. h.RawHTML("<!DOCTYPE html>\n"),
  56. h.Tag("html").Children(
  57. h.Head(
  58. injector.GetHeadHTMLComponent(),
  59. ),
  60. h.Body(
  61. h.Div(
  62. h.RawHTML(body),
  63. ).Id("app").Attr("v-cloak", true),
  64. injector.GetTailHTMLComponent(),
  65. ).Class("front"),
  66. ).AttrIf("lang", injector.GetHTMLLang(), injector.GetHTMLLang() != ""),
  67. }
  68. buf := bytes.NewBuffer(nil)
  69. ctx := new(EventContext)
  70. ctx.R = r
  71. err = h.Fprint(buf, root, WrapEventContext(context.TODO(), ctx))
  72. if err != nil {
  73. return
  74. }
  75. output = buf.String()
  76. return
  77. }