tpls

Extendable, Fast Template Engine for Go
git clone git://git.lair.cx/tpls
Log | Files | Refs | README | LICENSE

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 }