func BenchmarkComplexMustache(b *testing.B) { layoutTmpl, _ := mustache.ParseFile("mustache/base.mustache") tmpl, _ := mustache.ParseFile("mustache/index.mustache") b.ResetTimer() for i := 0; i < b.N; i++ { tmpl.RenderInLayout(layoutTmpl, testComplexData) } }
// Create a web handler using a mustache template with layout // Arguments: // fn is a file name // data is the data that will be used to render the template // Returns: Web handler func TemplateLayoutView(fn, layoutFn string, data func() interface{}) func(*web.Context) { base, err := mustache.ParseFile(root + layoutFn) if err != nil { log.Fatalf("Error parsing %s: %s", layoutFn, err.Error()) } t, err := mustache.ParseFile(root + fn) if err != nil { log.Fatalf("Error parsing %s: %s", fn, err.Error()) } return func(ctx *web.Context) { ctx.WriteString(t.RenderInLayout(base, data())) } }
func (t *ThemeEngine) loadTemplate(name string) { tmpl, err := mustache.ParseFile(name) if err != nil { return } t.templates[name] = tmpl }
/****************************************************************************** ** Mustache ******************************************************************************/ func TestComplexMustache(t *testing.T) { layoutTmpl, err := mustache.ParseFile("mustache/base.mustache") if err != nil { t.Error(err) } tmpl, err := mustache.ParseFile("mustache/index.mustache") if err != nil { t.Error(err) } result := tmpl.RenderInLayout(layoutTmpl, testComplexData) if msg, ok := linesEquals(result, expectedtComplexResult); !ok { t.Error(msg) } }
func main() { templateHtml, err := mustache.ParseFile("./report.html") if err != nil { log.Fatal("Parse Html failed, ", err) } var tmpfile = tmpDir + "test_report.html" tmpHtmlFile, err := os.Create(tmpfile) if err != nil { log.Fatal("Create tmp file failed, ", err) } var data Data data.Name = "!!! XXXX !!!!" mapping := structs.Map(data) var str = templateHtml.Render(mapping) filelength, err := tmpHtmlFile.WriteString(str) fmt.Printf("wrote %d bytes\n", filelength) tmpHtmlFile.Sync() cmd := "wkhtmltopdf" args := []string{"--print-media-type", "--page-size", "A4", "-T", "0mm", "-B", "0mm", "-L", "0mm", "-R", "0mm", "--dpi", "600", "test_report.html", "test_report.pdf"} if err := exec.Command(cmd, args...).Run(); err != nil { fmt.Println(err) os.Exit(1) } fmt.Println("Successfully Generates the report of PDF format") }
// renders / func index(ctx *web.Context) string { css, ok := ctx.Params["css"] if ok { SetCSS(ctx, css) ctx.Redirect(302, "/") return "ok" } //posts := postsForMonth(time.LocalTime()) //Db.GetLastNPosts(10) // posts := lastPosts(0xff) posts := postsForLastNDays(4) if len(posts) <= 0 { posts = lastPosts(23) } //fmt.Printf("posts: %#v\n", posts) //embedded struct - our mustache templates need a NumOfComments field to render //but we don't want to put that field into the BlogPost Struct so it won't get stored //into the DB type MyPost struct { BlogPost NumOfComments int } //posts ordered by date. this is ugly. TODO: look up if mustache hase something to handle this situation type Date struct { Date string Posts []MyPost } Db := DBGet() defer Db.Close() //loop through our posts and put them into the appropriate date structure dates := []Date{} var cur_date time.Time var date *Date for _, p := range posts { post_date := time.Unix(p.Timestamp, 0) if !(cur_date.Day == post_date.Day && cur_date.Month == post_date.Month && cur_date.Year == post_date.Year) { cur_date = *post_date dates = append(dates, Date{Date: cur_date.Format("Mon Jan _2 2006")}) date = &dates[len(dates)-1] } p.Comments, _ = Db.GetComments(p.Id) mp := MyPost{p, len(p.Comments)} date.Posts = append(date.Posts, mp) } m := map[string]interface{}{ "Dates": dates, } tmpl, _ := mustache.ParseFile("templ/index.mustache") s := tmpl.Render(&m, getCSS(ctx)) return s }
func (h *reqHandler) render(filename string, context interface{}, w http.ResponseWriter) { t, err := mustache.ParseFile(h.templateDir + "/" + filename) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) log.Println(err.Error()) return } result := t.Render(context) w.Write([]byte(result)) }
// Make sure all templates are good func TestTemplates(t *testing.T) { files := findFiles(templateRoot) for _, f := range files { _, err := mustache.ParseFile(f) // Assure there are no errors if err != nil { t.Error("Error parsing template!", f, err) } } }
func renderRSS(shares []Share) string { tpl, err := mustache.ParseFile("rss.mustache") if err != nil { panic(err) } context := make(map[string][]Share) context["shares"] = shares return tpl.Render(context) //return tpl.Render(shares) }
func (this *Mustache) Render(f string, o ...interface{}) (string, error) { t, ok := this.cache[f] if ok == false { tmpl, err := mustache.ParseFile(f) if err != nil { return "", err } if this.useCache { this.cache[f] = tmpl } t = tmpl } return t.Render(o...), nil }
func MustacheFileRender(filepath string, context ...interface{}) string { t, ok := templateCache[filepath] if ok == false { tmpl, err := mustache.ParseFile(filepath) if err != nil { return err.Error() } templateCache[filepath] = tmpl t = templateCache[filepath] } return t.Render(context...) }
func (self *MustacheTemplate) Load(key string) error { self.templateFilename = fmt.Sprintf("%s/%s.mustache", self.GetTemplateDir(), key) if _, err := os.Stat(self.templateFilename); err == nil { if tpl, err := mustache.ParseFile(self.templateFilename); err == nil { self.template = tpl } else { return err } } else { return err } return nil }
func (te *MustacheTemplateEngine) getTemplate(filepath string) *mustache.Template { var tmpl *mustache.Template if te.UseCache { tmpl = te.TemplateCache[filepath] } if tmpl == nil { var err error tmpl, err = mustache.ParseFile(filepath) if err != nil { panic("MustacheTemplateEngine.Render: parse template \"" + filepath + "\" error, " + err.Error()) } if te.UseCache { te.TemplateCache[filepath] = tmpl } } return tmpl }
func createTemplate(templateFileName string, templateData string) *mustache.Template { if templateFileName != "" { template, err := mustache.ParseFile(templateFileName) if err != nil { Fatalf("Failed to load a template file: ", err) } return template } else if templateData != "" { template, err := mustache.ParseString(templateData) if err != nil { Fatalf("Failed to parse a template data: ", err) } return template } else { Fatalf("No template file or template data") return nil } }
// renders /post?id= func post(ctx *web.Context) string { Db := DBGet() defer Db.Close() id_s := ctx.Params["id"] id, _ := strconv.ParseInt(id_s, 10, 64) post := postForId(id) post.Comments, _ = Db.GetComments(post.Id) type MyPost struct { BlogPost NumOfComments int } p := MyPost{post, len(post.Comments)} tmpl, _ := mustache.ParseFile("templ/postview.mustache") s := tmpl.Render(&p, getCSS(ctx)) return s }
func rss(ctx *web.Context) string { Db := DBGet() defer Db.Close() posts, _ := Db.GetLastNPosts(20) //postsForMonth(time.LocalTime())// tmpl, _ := mustache.ParseFile("templ/rss.mustache") type RssItem struct { Title string Description string Link string Guid string Date string } var items []RssItem for _, post := range posts { post_date := time.Unix(post.Timestamp, 0) date := post_date.Format("Mon, 02 Jan 2006 15:04:05 -0700") title := htmlstrip(post.Content) l := len(title) if l > 64 { l = 64 } item := RssItem{ Title: string(title[0:l]), Description: post.Content, Link: fmt.Sprintf("http://fettemama.org/post?id=%d", post.Id), Guid: fmt.Sprintf("http://fettemama.org/post?id=%d", post.Id), Date: date, } items = append(items, item) } m := map[string]interface{}{"Items": items} return tmpl.Render(&m) }
//Implements go-flags's Command interface func (lc *ListCommand) Execute(args []string) error { //ListTasks(){// if options.Verbose { fmt.Println("In List Command") } jc := libgojira.NewJiraClient(options) if len(args) == 1 && (!lc.Open && !lc.CurrentSprint && lc.JQL == "") { lc.JQL = fmt.Sprintf("key = %s or parent = %s order by rank", args[0], args[0]) } issues, err := jc.Search(&libgojira.SearchOptions{options.Projects, lc.CurrentSprint, lc.Open, lc.Issue, lc.JQL, lc.Type, lc.NotType, lc.Status, lc.NotStatus}) if err != nil { return err } if lc.Print { var tmpl *mustache.Template if lc.PrintTmpl != "" { tmpl, err = mustache.ParseFile(lc.PrintTmpl) fmt.Fprintln(out, tmpl.Render(map[string]interface{}{"Issues": issues})) } else { html, _ := libgojira.PrintHtml(issues) fmt.Fprintln(out, string(html)) } } else { if lc.TotalTime { fmt.Fprintln(out, "ID,Points,Type,Est.,Spent,Rem.,Desc.") for _, v := range issues { fmt.Fprintln(out, fmt.Sprintf("%s,%s,%s,%s,%s,%s,\"%s\"", v.Key, v.Points, v.Type, libgojira.PrettySeconds(int(v.OriginalEstimate)), libgojira.PrettySeconds(int(v.TimeSpent)), libgojira.PrettySeconds(int(v.RemainingEstimate)), v.Summary)) } } else { for _, v := range issues { fmt.Fprintln(out, v) } } } return nil }
//renders /month?m=<>&y= //if m and/or y are not filled the value of Today will be used func month(ctx *web.Context) string { Db := DBGet() defer Db.Close() mon := ctx.Params["m"] yr := ctx.Params["y"] d := time.Now() if len(mon) > 0 { d.Month, _ = strconv.Atoi(mon) } if len(yr) > 0 { d.Year, _ = strconv.ParseInt(yr, 10, 64) } posts := postsForMonth(d) //Db.GetLastNPosts(10) //fmt.Printf("posts: %#v\n", posts) //embedded struct - our mustache templates need a NumOfComments field to render //but we don't want to put that field into the BlogPost Struct so it won't get stored //into the DB type MyPost struct { BlogPost NumOfComments int } //posts ordered by date. this is ugly. TODO: look up if mustache hase something to handle this situation type Date struct { Date string Posts []MyPost } //loop through our posts and put them into the appropriate date structure dates := []Date{} var cur_date time.Time var date *Date for _, p := range posts { post_date := time.Unix(p.Timestamp, 0) if !(cur_date.Day == post_date.Day && cur_date.Month == post_date.Month && cur_date.Year == post_date.Year) { cur_date = *post_date dates = append(dates, Date{Date: cur_date.Format("Mon Jan _2 2006")}) date = &dates[len(dates)-1] } p.Comments, _ = Db.GetComments(p.Id) mp := MyPost{p, len(p.Comments)} date.Posts = append(date.Posts, mp) } //create PrevMonth pmon := *d pmon.Month-- if pmon.Month <= 0 { pmon.Year-- pmon.Month = 12 } //fill map m := map[string]interface{}{ "Dates": dates, "PrevMonth": pmon, } tmpl, _ := mustache.ParseFile("templ/month.mustache") s := tmpl.Render(&m, getCSS(ctx)) return s }
func ServeAction() error { m := martini.Classic() m.Use(martini.Static("resources/public")) mainView, err := mustache.ParseFile("resources/views/main.html.mustache") if err != nil { panic(err) } m.Get("/", func(res http.ResponseWriter) string { conn := models.CloneConnection() defer conn.Close() // get the latest pricing data price, err := models.GetLatestPrice(conn) if err != nil { webError(err, res) return "" } // get data for the graph averages, err := models.GetAverages(conn, 24) if err != nil { webError(err, res) return "" } parsedAverages := parseAverages(averages) // get the forum posts forum, err := models.GetLatestPosts(conn, "forum", 8) if err != nil { webError(err, res) return "" } // get reddit posts reddit, err := models.GetLatestPosts(conn, "reddit", 8) if err != nil { webError(err, res) return "" } // get the mining information network, err := models.GetLatestNetworkSnapshot(conn) if err != nil { webError(err, res) return "" } // generate the HTML valueMap := map[string]interface{}{"reddit": reddit, "forum": forum, "averages": parsedAverages} return mainView.Render(generateTplVars(price, network), valueMap) }) // returns basic information about the state of the service. If any hardcoded checks fail // the message is returned with a 500 status. We can then use pingdom or another service // to alert when data integrity may be off. m.Get("/health", func(res http.ResponseWriter) string { conn := models.CloneConnection() defer conn.Close() twoHoursAgo := time.Now().Add(time.Hour * -2).Unix() // make sure the price has been updated in the last 2 hours price, err := models.GetLatestPrice(conn) if err != nil { webError(err, res) return "" } if price.GeneratedAt.Unix() < twoHoursAgo { webError(errors.New("The latest price is old"), res) return "" } // make sure the network has been updated in the last two hours network, err := models.GetLatestNetworkSnapshot(conn) if err != nil { webError(err, res) return "" } if network.GeneratedAt.Unix() < twoHoursAgo { webError(errors.New("The latest network snapshot is old"), res) return "" } return "ok" }) m.Run() return nil }
func ServeAction() error { m := martini.Classic() m.Use(martini.Static("resources/public")) mainView, err := mustache.ParseFile("resources/views/main.html.mustache") if err != nil { panic(err) } homeWriter := func(useBtc bool, res http.ResponseWriter) string { conn := models.CloneConnection() defer conn.Close() // get the latest pricing data price, err := models.GetLatestPrice(conn) if err != nil { webError(err, res) return "" } // get data for the graph averages, err := models.GetAverages(conn, 24) if err != nil { webError(err, res) return "" } allAverages, err := addLatestPricesToAverages(conn, averages) if err != nil { webError(err, res) return "" } var graphAverages, graphValueType string if useBtc { graphValueType = "BTC" graphAverages = parseAverages(allAverages, true) } else { graphValueType = "USD" graphAverages = parseAverages(allAverages, false) } // get the forum posts forum, err := models.GetLatestPosts(conn, "forum", 8) if err != nil { webError(err, res) return "" } // /r/vertcoin posts redditBitBar, err := models.GetLatestPosts(conn, "/r/bitbar", 8) if err != nil { webError(err, res) return "" } // get the mining information network, err := models.GetLatestNetworkSnapshot(conn) if err != nil { webError(err, res) return "" } // generate the HTML valueMap := map[string]interface{}{ "redditBitBar": redditBitBar, "forum": forum, "averages": graphAverages, "graphValueType": graphValueType, "showBtcLink": !useBtc, "showUsdLink": useBtc, } return mainView.Render(generateTplVars(price, network), valueMap) } m.Get("/", func(res http.ResponseWriter) string { return homeWriter(false, res) }) m.Get("/:graphValue", func(params martini.Params, res http.ResponseWriter) string { var useBtc bool if params["graphValue"] == "usd" { useBtc = false } else { useBtc = true } return homeWriter(useBtc, res) }) // returns basic information about the state of the service. If any hardcoded checks fail // the message is returned with a 500 status. We can then use pingdom or another service // to alert when data integrity may be off. m.Get("/health", func(res http.ResponseWriter) string { conn := models.CloneConnection() defer conn.Close() twoHoursAgo := time.Now().Add(time.Hour * -2).Unix() // make sure the price has been updated in the last 2 hours price, err := models.GetLatestPrice(conn) if err != nil { webError(errors.New("Error getting latest price"), res) return "" } if price.GeneratedAt.Unix() < twoHoursAgo { webError(errors.New("The latest price is old"), res) return "" } // make sure the network has been updated in the last two hours network, err := models.GetLatestNetworkSnapshot(conn) if err != nil { webError(errors.New("Error getting latest network snapshot"), res) return "" } if network.GeneratedAt.Unix() < twoHoursAgo { webError(errors.New("The latest network snapshot is old"), res) return "" } return "ok" }) log.Printf("listening on port 4001") http.ListenAndServe(":4001", m) return nil }