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 }
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 }
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 }
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) } }) } }
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 }
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 }