func ArticleHandler(ctx *app.Context) { slug := ctx.IndexValue(0) var art *article.Article articles := getArticles(ctx) for _, v := range articles { if v.Slug() == slug { art = v break } } if art == nil { for _, v := range articles { for _, s := range v.AllSlugs() { if s == slug { ctx.MustRedirectReverse(true, ctx.HandlerName(), s) return } } } ctx.NotFound("article not found") return } fs := vfs.Memory() filename := path.Base(art.Filename) if filename == "" { filename = "article.html" } if err := vfs.WriteFile(fs, filename, art.Text, 0644); err != nil { panic(err) } log.Debugf("loading article %s", articleId(art)) tmpl, err := app.LoadTemplate(ctx.App(), fs, nil, filename) if err != nil { panic(err) } var buf bytes.Buffer if err := tmpl.ExecuteTo(&buf, ctx, nil); err != nil { panic(err) } body := buf.String() data := map[string]interface{}{ "Article": art, "Title": art.Title(), "Body": template.HTML(body), } ctx.MustExecute("article.html", data) }
func main() { pkg, err := genutil.NewPackage("gnd.la/template") if err != nil { panic(err) } var art *article.Article if len(os.Args) > 1 { art, err = article.OpenFile(os.Args[1]) if err != nil { panic(fmt.Errorf("error loading previous article from %s: %s", os.Args[1], err)) } } else { art = &article.Article{} } abs, err := filepath.Abs("funcs.go") if err != nil { panic(err) } f := pkg.ASTFiles()[abs] var inMap bool var lastPos token.Pos docs := make(map[string]*funcDoc) ast.Inspect(f, func(n ast.Node) bool { if !inMap { if vs, ok := n.(*ast.ValueSpec); ok { for _, n := range vs.Names { if n.Name == "templateFuncs" { inMap = true lastPos = vs.Pos() break } } } } if inMap { if kv, ok := n.(*ast.KeyValueExpr); ok { if k := literalString(kv.Key); k != "" { if doc := documentFunction(f, pkg, kv.Value, lastPos, kv.Pos()); doc != nil { docs[k] = doc } } lastPos = kv.Pos() } } return true }) // Write the markdown var buf bytes.Buffer chrs := make(map[string]byte) names := make([]string, 0, len(docs)) for k := range docs { if k[0] == '#' || k[0] == '!' || k[0] == '@' { chr := k[0] k = k[1:] chrs[k] = chr } names = append(names, k) } sort.Strings(names) for _, n := range names { chr := chrs[n] lookup := n if chr != 0 { lookup = string(chr) + n } doc := docs[lookup] fmt.Fprintf(&buf, "- **%s** *%s*", n, doc.decl) buf.WriteString("\n\n\t") if doc.alias != "" { fmt.Fprintf(&buf, "%s is an alias for [%s](/doc/pkg/%s)", n, doc.alias, linkFunc(doc.alias)) } else { buf.WriteString(doc.doc) } buf.WriteString("\n\n") } art.Text = buf.Bytes() art.Set("updated", "now") var out bytes.Buffer if _, err := art.WriteTo(&out); err != nil { panic(err) } if art.Filename != "" { if err := ioutil.WriteFile(art.Filename, out.Bytes(), 0644); err != nil { panic(err) } } else { io.Copy(os.Stdout, &out) } }