func GetBaseFunctions() map[string]pongo2.FilterFunction { return map[string]pongo2.FilterFunction{ `autosize`: func(input *pongo2.Value, fixTo *pongo2.Value) (*pongo2.Value, *pongo2.Error) { check := input.Float() i := 1 for i = 1; i < 9; i++ { if check < 1024.0 { break } else { check = (check / 1024.0) } } return pongo2.AsValue((strconv.FormatFloat(check, 'f', fixTo.Integer(), 64) + ` ` + util.SiSuffixes[i-1])), nil }, `less`: func(first *pongo2.Value, second *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue(first.Float() - second.Float()), nil }, `str`: func(input *pongo2.Value, _ *pongo2.Value) (*pongo2.Value, *pongo2.Error) { if input.Len() > 0 { if v, err := stringutil.ToString(input.Interface()); err == nil { return pongo2.AsValue(v), nil } } return pongo2.AsValue(``), nil }, } }
func getBranchIcon(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { str := in.String() s := strings.Split(str, "-") if len(s) < 2 { return nil, &pongo2.Error{ Sender: "filter:branchicon", ErrorMsg: "Field did not contain a valid GoBuilder filename", } } s = strings.Split(s[len(s)-2], "_") // Map the architectures used by golang to fontawesome icon names switch s[len(s)-1] { case "darwin": return pongo2.AsValue("apple"), nil case "linux": return pongo2.AsValue("linux"), nil case "windows": return pongo2.AsValue("windows"), nil case "android": return pongo2.AsValue("android"), nil } // Not all archs have icons, use a generic file icon return pongo2.AsValue("file"), nil }
func filterBool(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { if in.IsNil() { return pongo2.AsValue(false), nil } switch t := in.Interface().(type) { case string: if t == "" { return pongo2.AsValue(false), nil } v, err := strconv.ParseBool(t) if err != nil { return nil, &pongo2.Error{ Sender: "filter:bool", ErrorMsg: "Filter input value invalid.", } } return pongo2.AsValue(v), nil case bool: return pongo2.AsValue(t), nil } return nil, &pongo2.Error{ Sender: "filter:bool", ErrorMsg: "Filter input value must be of type 'bool' or 'string'.", } }
func filterTruncatesentences(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { count := param.Integer() if count <= 0 { return pongo2.AsValue(""), nil } sentencens := filterTruncatesentencesRe.FindAllString(strings.TrimSpace(in.String()), -1) return pongo2.AsValue(strings.TrimSpace(strings.Join(sentencens[:min(count, len(sentencens))], ""))), nil }
func jsonPrettyFilter(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, e *pongo2.Error) { body, err := json.MarshalIndent(in.Interface(), "", " ") if err != nil { return nil, &pongo2.Error{ErrorMsg: err.Error()} } return pongo2.AsValue(string(body)), nil }
func main() { var config Config config.Input = flag.String("input", "input", "Directory where blog posts are stored (in markdown format)") config.Output = flag.String("output", "output", "Directory where generated html should be stored (IT WILL REMOVE ALL FILES INSIDE THAT DIR)") config.Theme = flag.String("theme", "theme", "Directory containing theme files (templates)") config.Title = flag.String("title", "Blag.", "Blag title") config.DateFormat = flag.String("dateformat", "2006-01-02 15:04:05", "Time layout, as used in Golang's time.Time.Format()") config.BaseURL = flag.String("baseurl", "/", "URL that will be used in <base href=\"\"> element.") config.DisqusShortname = flag.String("disqus", "", "Your Disqus shortname. If empty, comments will be disabled.") config.PostsPerPage = flag.Int("pps", 10, "Post count per page") config.StoryShortLength = flag.Int("short", 250, "Length of shortened versions of stories (-1 disables shortening)") flag.Parse() pongo2.RegisterFilter("trim", func(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, err *pongo2.Error) { out = pongo2.AsValue(strings.Trim(in.String(), "\r\n")) err = nil return out, err }) var theme Theme theme = LoadTheme(*config.Theme) var posts []BlagPost posts = LoadPosts(config) GenerateHTML(config, theme, posts) }
func (s *TestSuite) TestMisc(c *C) { // Must // TODO: Add better error message (see issue #18) c.Check( func() { pongo2.Must(testSuite2.FromFile("template_tests/inheritance/base2.tpl")) }, PanicMatches, `\[Error \(where: fromfile\) in .*template_tests/inheritance/doesnotexist.tpl | Line 1 Col 12 near 'doesnotexist.tpl'\] open .*template_tests/inheritance/doesnotexist.tpl: no such file or directory`, ) // Context c.Check(parseTemplateFn("", pongo2.Context{"'illegal": nil}), PanicMatches, ".*not a valid identifier.*") // Registers c.Check(func() { pongo2.RegisterFilter("escape", nil) }, PanicMatches, ".*is already registered.*") c.Check(func() { pongo2.RegisterTag("for", nil) }, PanicMatches, ".*is already registered.*") // ApplyFilter v, err := pongo2.ApplyFilter("title", pongo2.AsValue("this is a title"), nil) if err != nil { c.Fatal(err) } c.Check(v.String(), Equals, "This Is A Title") c.Check(func() { _, err := pongo2.ApplyFilter("doesnotexist", nil, nil) if err != nil { panic(err) } }, PanicMatches, `\[Error \(where: applyfilter\)\] Filter with name 'doesnotexist' not found.`) }
func toSwagger(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { i := in.Interface() m := i.(map[string]interface{}) fixPropertyTree(m) data, _ := json.MarshalIndent(i, param.String(), " ") return pongo2.AsValue(string(data)), nil }
func checkMainArch(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { str := in.String() s := strings.Split(str, "-") if len(s) < 2 { return nil, &pongo2.Error{ Sender: "filter:branchicon", ErrorMsg: "Field did not contain a valid GoBuilder filename", } } s = strings.Split(s[len(s)-2], "_") for _, v := range []string{"linux", "darwin", "windows"} { if s[len(s)-1] == v { return pongo2.AsValue(true), nil } } return pongo2.AsValue(false), nil }
func filterAfterNow(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { t, isTime := in.Interface().(time.Time) if !isTime { return nil, &pongo2.Error{ Sender: "filter:past_now", ErrorMsg: "Filter input argument must be of type 'time.Time'.", } } return pongo2.AsValue(time.Now().Before(t)), nil }
func filterHumanizeTime(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { t, isTime := in.Interface().(time.Time) if !isTime { return nil, &pongo2.Error{ Sender: "filter:humanize_time", ErrorMsg: "Filter input argument must be of type: 'time.Time'.", } } return pongo2.AsValue(humanize.Time(t)), nil }
func filterTruncatesentencesHtml(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { count := param.Integer() if count <= 0 { return pongo2.AsValue(""), nil } value := in.String() newLen := max(param.Integer(), 0) new_output := bytes.NewBuffer(nil) sentencefilter := 0 filterTruncateHtmlHelper(value, new_output, func() bool { return sentencefilter >= newLen }, func(_ rune, _ int, idx int) int { // Get next word word_found := false for idx < len(value) { c2, size2 := utf8.DecodeRuneInString(value[idx:]) if c2 == utf8.RuneError { idx += size2 continue } if c2 == '<' { // HTML tag start, don't consume it return idx } new_output.WriteRune(c2) idx += size2 if (c2 == '.' && !(idx+1 < len(value) && value[idx+1] >= '0' && value[idx+1] <= '9')) || c2 == '!' || c2 == '?' || c2 == '\n' { // Sentence ends here, stop capturing it now break } else { word_found = true } } if word_found { sentencefilter++ } return idx }, func() {}) return pongo2.AsSafeValue(new_output.String()), nil }
func filterNaturalday(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { basetime, is_time := in.Interface().(time.Time) if !is_time { return nil, &pongo2.Error{ Sender: "filter:naturalday", ErrorMsg: "naturalday-value is not a time.Time-instance.", } } var reference_time time.Time if !param.IsNil() { reference_time, is_time = param.Interface().(time.Time) if !is_time { return nil, &pongo2.Error{ Sender: "filter:naturalday", ErrorMsg: "naturalday-parameter is not a time.Time-instance.", } } } else { reference_time = time.Now() } d := reference_time.Sub(basetime) / time.Hour switch { case d >= 0 && d < 24: // Today return pongo2.AsValue("today"), nil case d >= 24: return pongo2.AsValue("yesterday"), nil case d < 0 && d >= -24: return pongo2.AsValue("tomorrow"), nil } // Default behaviour return pongo2.ApplyFilter("naturaltime", in, param) }
func main() { // setup tables db, err := genmai.New(&genmai.SQLite3Dialect{}, "./wiki.db") if err != nil { log.Fatalln(err) } if err := db.CreateTableIfNotExists(&Page{}); err != nil { log.Fatalln(err) } // setup pongo pongo2.DefaultSet.SetBaseDirectory("view") wiki := &Wiki{ URL: "/", DB: db, } pongo2.Globals["wiki"] = wiki pongo2.RegisterFilter("to_localdate", func(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, err *pongo2.Error) { date, ok := in.Interface().(time.Time) if !ok { return nil, &pongo2.Error{ Sender: "to_localdate", ErrorMsg: fmt.Sprintf("Date must be of type time.Time not %T ('%v')", in, in), } } return pongo2.AsValue(date.Local()), nil }) goji.Use(middleware.Recoverer) goji.Use(middleware.NoCache) goji.Use(func(c *web.C, h http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { c.Env["Wiki"] = wiki h.ServeHTTP(w, r) } return http.HandlerFunc(fn) }) goji.Get("/assets/*", http.FileServer(http.Dir("."))) goji.Get("/", showPages) goji.Get("/wiki/:title", showPage) goji.Get("/wiki/:title/edit", editPage) goji.Post("/wiki/:title", postPage) goji.Serve() }
func timeSince(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { errMsg := &pongo2.Error{ Sender: "filter:timeuntil/timesince", ErrorMsg: "time-value is not a time.Time string.", } dateStr, ok := in.Interface().(string) if !ok { return nil, errMsg } basetime, err := time.Parse(time.RFC3339, dateStr) if err != nil { return nil, errMsg } return pongo2.AsValue(util.FormatTime(basetime)), nil }
func filterJson(in *pongo2.Value, param *pongo2.Value) (out *pongo2.Value, err *pongo2.Error) { var value []byte mapValue, ok := in.Interface().(map[string]interface{}) if ok { value, _ = json.Marshal(mapValue) } else { var arrMapValue []map[string]interface{} in.Iterate(func(idx int, count int, key *pongo2.Value, value *pongo2.Value) bool { mapItem, ok := key.Interface().(map[string]interface{}) if ok { arrMapValue = append(arrMapValue, mapItem) } else { panic("[gin_pongo2.filterJson] Unknow format #1") } return true }, func() {}) value, _ = json.Marshal(arrMapValue) } return pongo2.AsValue(string(value)), nil }
func toUnderScoreCase(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { s := in.String() if len(s) == 0 { return nil, nil } parts := []string{} chars := []rune(s) var buffer bytes.Buffer for i := 0; i < len(chars)-1; i++ { if unicode.IsUpper(chars[i]) && unicode.IsLower(chars[i+1]) && buffer.String() != "" { parts = append(parts, buffer.String()) buffer.Reset() } buffer.WriteRune(unicode.ToLower(chars[i])) if unicode.IsLower(chars[i]) && unicode.IsUpper(chars[i+1]) { parts = append(parts, buffer.String()) buffer.Reset() } } buffer.WriteRune(unicode.ToLower(chars[len(chars)-1])) parts = append(parts, buffer.String()) return pongo2.AsValue(strings.Join(parts, "_")), nil }
func filterTimeuntilTimesince(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { basetime, is_time := in.Interface().(time.Time) if !is_time { return nil, &pongo2.Error{ Sender: "filter:timeuntil/timesince", ErrorMsg: "time-value is not a time.Time-instance.", } } var paramtime time.Time if !param.IsNil() { paramtime, is_time = param.Interface().(time.Time) if !is_time { return nil, &pongo2.Error{ Sender: "filter:timeuntil/timesince", ErrorMsg: "time-parameter is not a time.Time-instance.", } } } else { paramtime = time.Now() } return pongo2.AsValue(humanize.TimeDuration(basetime.Sub(paramtime))), nil }
func toSwagger(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { i := in.Interface() m := i.(map[string]interface{}) switch properties := m["properties"].(type) { case map[string]interface{}: for _, value := range properties { deleteGohanExtendedProperties(value.(map[string]interface{})) } delete(properties, "propertiesOrder") case map[string]map[string]interface{}: for _, value := range properties { deleteGohanExtendedProperties(value) } delete(properties, "propertiesOrder") } if list, ok := m["required"].([]string); ok { if len(list) == 0 { delete(m, "required") } } delete(m, "propertiesOrder") data, _ := json.MarshalIndent(i, param.String(), " ") return pongo2.AsValue(string(data)), nil }
func (u *user) Is_admin() *pongo2.Value { return pongo2.AsValue(isAdmin(u)) }
}, "func_variadic_sum_int": func(args ...int) int { // Create a sum s := 0 for _, i := range args { s += i } return s }, "func_variadic_sum_int2": func(args ...*pongo2.Value) *pongo2.Value { // Create a sum s := 0 for _, i := range args { s += i.Integer() } return pongo2.AsValue(s) }, }, "complex": map[string]interface{}{ "is_admin": isAdmin, "post": post{ Text: "<h2>Hello!</h2><p>Welcome to my new blog page. I'm using pongo2 which supports {{ variables }} and {% tags %}.</p>", Created: time2, }, "comments": []*comment{ &comment{ Author: &user{ Name: "user1", Validated: true, }, Date: time1,
func filterFailure(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue(in.String() == "failure"), nil }
func filterReset(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue(in.String() == "reset"), nil }
func filterIgnored(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue(in.String() == "ignored"), nil }
func filterSuccess(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { return pongo2.AsValue(in.String() == "success"), nil }
func reflectType(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { i := in.Interface() v := reflect.ValueOf(i) t := v.Type() return pongo2.AsValue(t), nil }
func hasIdParam(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { i := in.String() return pongo2.AsValue(strings.Contains(i, ":id")), nil }
func astType(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { i := in.Interface() return pongo2.AsValue(exprToString(i)), nil }
// filterAddquote pongo2 filter for adding an extra quote func filterAddquote(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { output := strings.Replace(in.String(), "'", "''", -1) return pongo2.AsValue(output), nil }
func toSwaggerPath(in *pongo2.Value, param *pongo2.Value) (*pongo2.Value, *pongo2.Error) { i := in.String() r := regexp.MustCompile(":([^/]+)") return pongo2.AsValue(r.ReplaceAllString(i, "{$1}")), nil }