Example #1
0
File: exec.go Project: dms0/stick
// walkChild only executes a subset of nodes, intended to be used on child templates.
func (s *state) walkChild(node parse.Node) error {
	s.enter(node)
	defer s.leave(node)
	switch node := node.(type) {
	case *parse.BodyNode:
		for _, c := range node.Children() {
			err := s.walkChild(c)
			if err != nil {
				return err
			}
		}
	case *parse.UseNode:
		return s.walkUseNode(node)
	}
	return nil
}
Example #2
0
File: exec.go Project: dms0/stick
// Method walk is the main entry-point into template execution.
func (s *state) walk(node parse.Node) error {
	s.enter(node)
	defer s.leave(node)
	switch node := node.(type) {
	case *parse.ModuleNode:
		if p := node.Parent(); p != nil {
			tplName, err := s.evalExpr(p.TemplateRef())
			if err != nil {
				return err
			}
			tree, err := s.load(CoerceString(tplName))
			if err != nil {
				return err
			}
			s.blocks = append(s.blocks, tree.Blocks())
			err = s.walkChild(node.BodyNode)
			if err != nil {
				return err
			}
			return s.walk(tree.Root())
		}
		return s.walk(node.BodyNode)
	case *parse.BodyNode:
		for _, c := range node.Children() {
			err := s.walk(c)
			if err != nil {
				return err
			}
		}
	case *parse.TextNode:
		io.WriteString(s.out, node.Text())
	case *parse.PrintNode:
		v, err := s.evalExpr(node.Expr())
		if err != nil {
			return err
		}
		io.WriteString(s.out, CoerceString(v))
	case *parse.BlockNode:
		name := node.Name()
		if block := s.getBlock(name); block != nil {
			return s.walk(block.Body())
		}
		// TODO: It seems this should never occur.
		return errors.New("Unable to locate block " + name)
	case *parse.IfNode:
		v, err := s.evalExpr(node.Cond())
		if err != nil {
			return err
		}
		if CoerceBool(v) {
			s.walk(node.Body())
		} else {
			s.walk(node.Else())
		}
	case *parse.IncludeNode:
		tpl, ctx, err := s.walkIncludeNode(node)
		if err != nil {
			return err
		}
		err = execute(tpl, s.out, ctx, s.env)
		if err != nil {
			return err
		}
	case *parse.EmbedNode:
		tpl, ctx, err := s.walkIncludeNode(node.IncludeNode)
		if err != nil {
			return err
		}
		// TODO: We duplicate most of the "execute" function here.
		si := newState(s.out, ctx, s.env)
		tree, err := s.load(tpl)
		if err != nil {
			return err
		}
		si.blocks = append(s.blocks, node.Blocks(), tree.Blocks())
		err = si.walk(tree.Root())
		if err != nil {
			return err
		}
	case *parse.UseNode:
		return s.walkUseNode(node)
	case *parse.ForNode:
		return s.walkForNode(node)
	default:
		return errors.New("Unknown node " + node.String())
	}
	return nil
}