Example #1
1
func namespacedTree(tree *parse.Tree, ns []string) *parse.Tree {
	tree = tree.Copy()
	if len(ns) > 0 {
		prefix := strings.Join(ns, nsSep) + nsMark
		templateutil.WalkTree(tree, func(n, p parse.Node) {
			if n.Type() == parse.NodeTemplate {
				tmpl := n.(*parse.TemplateNode)
				tmpl.Name = prefix + tmpl.Name
			}
		})
	}
	return tree
}
Example #2
0
func (app *App) rewriteAssets(t *template.Template, included *includedApp) error {
	if !app.shouldImportAssets() {
		return nil
	}
	for _, group := range t.Assets() {
		for _, a := range group.Assets {
			if a.IsRemote() || a.IsHTML() {
				continue
			}
			orig := a.Name
			if a.IsTemplate() {
				orig = a.TemplateName()
			}
			name := included.renames[orig]
			if name == "" {
				return fmt.Errorf("asset %q referenced from template %q does not exist", a.Name, t.Name())
			}
			a.Rename(name)
		}
		group.Manager = app.assetsManager
	}
	fname := included.assetFuncName()
	for _, v := range t.Trees() {
		templateutil.WalkTree(v, func(n, p parse.Node) {
			if n.Type() == parse.NodeIdentifier {
				id := n.(*parse.IdentifierNode)
				if id.Ident == template.AssetFuncName {
					id.Ident = fname
				}
			}
		})
	}
	return nil
}
Example #3
0
func (t *Template) replaceExtendTag(name string, treeMap map[string]*parse.Tree, from string) error {
	var err error
	hasExtend := false
	var loc string
	for _, v := range treeMap {
		templateutil.WalkTree(v, func(n, p parse.Node) {
			if err != nil {
				return
			}
			if templateutil.IsPseudoFunction(n, "extend") {
				if hasExtend {
					loc2, _ := v.ErrorContext(n)
					err = fmt.Errorf("multiple {{ extend }} tags in %q, %s and %s", name, loc, loc2)
					return
				}
				hasExtend = true
				loc, _ = v.ErrorContext(n)
				var repl parse.Node
				if from == "" {
					// empty
					log.Debugf("removing {{ extend }} from %q", name)
					repl = &parse.TextNode{
						NodeType: parse.NodeText,
						Pos:      n.Position(),
					}
				} else {
					log.Debugf("extending %q at %s with %q", name, loc, from)
					repl = templateutil.TemplateNode(from, n.Position())
				}
				err = templateutil.ReplaceNode(n, p, repl)
			}
		})
	}
	return err
}
Example #4
0
func (t *Template) walkTrees(nt parse.NodeType, f func(parse.Node)) {
	for _, v := range t.trees {
		templateutil.WalkTree(v, func(n, p parse.Node) {
			if n.Type() == nt {
				f(n)
			}
		})
	}
}
Example #5
0
func (app *App) loadContainerTemplate(included *includedApp) (*Template, string, error) {
	container, err := app.loadTemplate(app.templatesFS, app.assetsManager, included.container)
	if err != nil {
		return nil, "", err
	}
	name := template.NamespacedName([]string{included.name}, "~")
	found := false
	var loc string
	for _, v := range container.tmpl.Trees() {
		if err != nil {
			return nil, "", err
		}
		templateutil.WalkTree(v, func(n, p parse.Node) {
			if err != nil {
				return
			}
			if templateutil.IsPseudoFunction(n, "app") {
				if found {
					dloc, _ := v.ErrorContext(n)
					err = fmt.Errorf("duplicate {{ app }} node in container template %q: %s and %s",
						included.container, loc, dloc)
					return
				}
				// Used for error message if duplicate is found
				loc, _ = v.ErrorContext(n)
				found = true
				tmpl := templateutil.TemplateNode(name, n.Position())
				err = templateutil.ReplaceNode(n, p, tmpl)
			}
		})
	}
	if err != nil {
		return nil, "", err
	}
	if !found {
		return nil, "", fmt.Errorf("container template %q does not contain an {{ app }} node", included.container)
	}
	return container, name, nil
}
Example #6
0
func extractTemplateMessages(messages messageMap, path string, opts *ExtractOptions) error {
	log.Debugf("Extracting messages from template file %s", path)
	b, err := ioutil.ReadFile(path)
	if err != nil {
		return err
	}
	funcs := make(map[string]*Function)
	if opts != nil {
		for _, v := range opts.Functions {
			if v.Template {
				funcs[v.Name] = v
			}
		}
	}
	text := string(b)
	treeSet, err := templateutil.Parse(path, text)
	if err != nil {
		return err
	}
	for _, v := range treeSet {
		if err := templateutil.ReplaceTranslatableBlocks(v, "t"); err != nil {
			return err
		}
		templateutil.WalkTree(v, func(n, p parse.Node) {
			var fname string
			switch n.Type() {
			case parse.NodeIdentifier:
				fname = n.(*parse.IdentifierNode).Ident
			case parse.NodeField:
				ident := n.(*parse.FieldNode).Ident
				if len(ident) > 1 {
					fname = ident[len(ident)-1]
				}
			case parse.NodeVariable:
				ident := n.(*parse.VariableNode).Ident
				if len(ident) > 1 {
					fname = ident[len(ident)-1]
				}
			}
			if fname != "" {
				f := funcs[fname]
				if f != nil {
					count := 1
					if f.Context {
						count++
					}
					if f.Plural {
						count++
					}
					cmd := p.(*parse.CommandNode)
					// First argument is the function name
					if c := len(cmd.Args) - 1; c != count {
						log.Debugf("Skipping function %s (%v) - want %d arguments, got %d", f.Name, n.Position(), count, c)
						return
					}
					var s []string
					for ii := 1; ii < len(cmd.Args); ii++ {
						if sn, ok := cmd.Args[ii].(*parse.StringNode); ok {
							s = append(s, sn.Text)
						} else {
							log.Debugf("Skipping function %s (%v) - non-string argument at position %d", f.Name, n.Position(), ii)
							return
						}
					}
					message := &Message{}
					switch len(s) {
					case 1:
						message.Singular = s[0]
					case 2:
						if f.Context {
							message.Context = s[0]
							message.Singular = s[1]
						} else {
							message.Singular = s[0]
							message.Plural = s[1]
						}
					case 3:
						message.Context = s[0]
						message.Singular = s[1]
						message.Plural = s[2]
					}
					// TODO: The line number doesn't match exactly because of the
					// prepended variables
					pos := templatePosition(path, text, n)
					if err = messages.Add(message, pos, ""); err != nil {
						return
					}
				}
			}
		})
	}
	return err
}