builtin_module.go (1809B)
1 package tplc 2 3 import ( 4 "bytes" 5 "fmt" 6 7 "github.com/pkg/errors" 8 9 "go.lair.cx/go-core/net/htmlx" 10 ) 11 12 func TagModule(b *Builder, _ *Writer, t *htmlx.Tokenizer) error { 13 attrs := getAttrs(t) 14 className, ok := attrs["class"] 15 if !ok { 16 return errors.New("class name is required for module tag") 17 } 18 19 var moduleContent []byte 20 21 t.SetRawTag("module") 22 23 loop: 24 for { 25 switch t.Next() { 26 case htmlx.TextToken: 27 content := t.Text() 28 moduleContent = make([]byte, len(content)) 29 copy(moduleContent, content) 30 31 case htmlx.EndTagToken: 32 if err := checkTagName(t, "module"); err != nil { 33 return err 34 } 35 break loop 36 37 default: 38 return errors.New("invalid module tag syntax") 39 } 40 } 41 42 b.AddTag(className, func(b *Builder, w *Writer, t *htmlx.Tokenizer) error { 43 t.SetRawTag(className) 44 45 var moduleBody []byte 46 47 loop: 48 for { 49 kind := t.Next() 50 switch kind { 51 case htmlx.TextToken: 52 content := t.Text() 53 moduleBody = make([]byte, len(content)) 54 copy(moduleBody, content) 55 56 case htmlx.EndTagToken: 57 if err := checkTagName(t, className); err != nil { 58 return err 59 } 60 break loop 61 62 default: 63 return fmt.Errorf( 64 "invalid module tag syntax: unexpected token: %s", 65 kind.String(), 66 ) 67 } 68 } 69 70 handleBodyTag := func(b *Builder, w *Writer, t *htmlx.Tokenizer) error { 71 if len(moduleBody) > 0 { 72 err := TagFallback("body")(b, w, t) 73 if err != nil { 74 return err 75 } 76 mbt := htmlx.NewTokenizer(bytes.NewReader(moduleBody)) 77 return RenderTag(b, w, mbt, "", false) 78 } else { 79 return RenderTag(b, w, t, "body", false) 80 } 81 } 82 83 mct := htmlx.NewTokenizer(bytes.NewReader(moduleContent)) 84 return RenderTagWithCustomTags( 85 b, w, mct, "", 86 map[string]TagHandler{ 87 "body": handleBodyTag, 88 }, 89 false, 90 false, 91 ) 92 }) 93 94 return nil 95 }