Exemple #1
0
func BuildCommentsWidget(cnf Mapper, topCtx mustache.Context) (Widget, error) {
	log.Println("Comments >>", cnf.Layout())
	switch cnf.Layout() {
	case "disqus":
		disqus := cnf[cnf.Layout()].(map[string]interface{})
		short_name := disqus["short_name"]
		if short_name == nil {
			return nil, errors.New("CommentsWidget Of disqus need short_name")
		}
		self := make(CommentsWidget)
		self["comments"] = fmt.Sprintf(Comments_disqus, short_name)
		return self, nil
	case "uyan":
		uyan := cnf[cnf.Layout()].(map[string]interface{})
		uid := uyan["uid"]
		self := make(CommentsWidget)
		self["comments"] = fmt.Sprintf(tpl_uyan, uid)
		return self, nil
	case "duoshuo":
		duoshuo := cnf[cnf.Layout()].(map[string]interface{})
		short_name := duoshuo["short_name"]
		if short_name == nil {
			return nil, errors.New("CommentsWidget Of duoshuo need short_name")
		}
		self := make(CommentsWidget)
		self["comments"] = fmt.Sprintf(Comments_duoshuo, short_name)
		return self, nil
	}
	// 其他的,想不到还有啥,哈哈,需要其他的就报个issue吧
	return nil, errors.New("CommentsWidget Only for disqus yet")
}
Exemple #2
0
func BuildAnalyticsWidget(cnf Mapper, topCtx mustache.Context) (Widget, error) {
	switch cnf.Layout() {
	case "google": // 鼎鼎大名的免费,但有点拖慢加载速度,原因你懂的
		google := cnf[cnf.Layout()].(map[string]interface{})
		tracking_id := google["tracking_id"]
		if tracking_id == nil {
			return nil, errors.New("AnalyticsWidget Of Google need tracking_id")
		}
		self := make(AnalyticsWidget)
		self["analytics"] = fmt.Sprintf(Analytics_google, tracking_id)
		return self, nil
	case "cnzz": //免费,而且很快,但强制嵌入一个反向链接,靠!
		cnzz := cnf[cnf.Layout()].(map[string]interface{})
		tracking_id := cnzz["tracking_id"]
		if tracking_id == nil {
			return nil, errors.New("AnalyticsWidget Of CNZZ need tracking_id")
		}
		self := make(AnalyticsWidget)
		self["analytics"] = fmt.Sprintf(tpl_cnzz, tracking_id, tracking_id)
		return self, nil
	}
	// 其他的尚不支持, 如果需要,请报个issue吧
	return nil, errors.New("AnalyticsWidget Only for Goolge/CNZZ yet")

}
Exemple #3
0
func BuildCustomWidget(name string, dir string, cnf Mapper) (Widget, []string, error) {
	layoutName, ok := cnf["layout"]
	if !ok || layoutName == "" {
		log.Println("Skip Widget : " + dir)
		return nil, nil, nil
	}

	layoutFilePath := dir + "/layouts/" + layoutName.(string) + ".html"
	f, err := os.Open(layoutFilePath)
	if err != nil {
		return nil, nil, errors.New("Fail to load Widget Layout" + dir + "\n" + err.Error())
	}
	defer f.Close()
	cont, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, nil, errors.New("Fail to load Widget Layout" + dir + "\n" + err.Error())
	}

	assets := []string{}
	for _, js := range cnf.GetStrings("javascripts") {
		path := "/assets/" + dir + "/javascripts/" + js
		assets = append(assets, fmt.Sprintf("<script type=\"text/javascript\" src=\"%s\"></script>", path))
	}
	for _, css := range cnf.GetStrings("stylesheets") {
		path2 := "/assets/" + dir + "/stylesheets/" + css
		assets = append(assets, fmt.Sprintf("<link href=\"%s\" type=\"text/css\" rel=\"stylesheet\" media=\"all\">", path2))
	}

	return &CustomWidget{name, &DocContent{string(cont), string(cont), nil}, cnf}, assets, nil

}
Exemple #4
0
func parseLanguageAbility(req *http.Request) ([]db.LanguageAbility, error) {
	var languages []db.LanguageAbility

	rawJson := req.FormValue("langAbilities")
	if len(rawJson) == 0 {
		return languages, errors.New("No argument")
	}

	decoder := json.NewDecoder(strings.NewReader(rawJson))
	if _, e := decoder.Token(); e != nil { //The first array bracket
		return languages, errors.New("Wrong json format")
	}

	element := RawLang{}
	for decoder.More() {
		if e := decoder.Decode(&element); e != nil {
			continue
		}

		if len(element.Abilities) < 4 {
			continue
		}
		lang := db.LanguageAbility{
			Name:      element.LangName,
			Listening: uint(element.Abilities[0].Value),
			Speaking:  uint(element.Abilities[1].Value),
			Reading:   uint(element.Abilities[2].Value),
			Writing:   uint(element.Abilities[3].Value),
		}
		languages = append(languages, lang)
	}

	decoder.Token() //The last array bracket
	return languages, nil
}
func GetSessionUserPermission(req *http.Request) (UserPermission, error) {
	if v, err := GetUserSessionValue(req, USER_PERMISSION_SESSION_KEY); err != nil || v == nil {
		return UserPermission(0), errors.New("Invalid session key")
	} else {
		if perm, found := v.(UserPermission); found {
			return perm, nil
		} else {
			return UserPermission(0), errors.New("Invalid session permission format")
		}
	}
}
Exemple #6
0
func BuildCommentsWidget(cnf Mapper, topCtx mustache.Context) (Widget, error) {
	if cnf.Layout() != "disqus" {
		return nil, errors.New("CommentsWidget Only for disqus yet")
	}
	disqus := cnf[cnf.Layout()].(map[string]interface{})
	short_name := disqus["short_name"]
	if short_name == nil {
		return nil, errors.New("CommentsWidget Of disqus need short_name")
	}
	self := make(CommentsWidget)
	self["comments"] = fmt.Sprintf(Comments_disqus, short_name)
	return self, nil
}
Exemple #7
0
func BuildAnalyticsWidget(cnf Mapper, topCtx mustache.Context) (Widget, error) {
	if cnf.Layout() != "google" {
		return nil, errors.New("AnalyticsWidget Only for Goolge yet")
	}
	google := cnf[cnf.Layout()].(map[string]interface{})
	tracking_id := google["tracking_id"]
	if tracking_id == nil {
		return nil, errors.New("AnalyticsWidget Of Google need tracking_id")
	}
	self := make(AnalyticsWidget)
	self["analytics"] = fmt.Sprintf(Analytics_google, tracking_id)
	return self, nil
}
func GetSessionGMId(req *http.Request) (bson.ObjectId, error) {
	if v, err := GetGMSessionValue(req, GM_ID_SESSION_KEY); err != nil || v == nil {
		return bson.ObjectId(""), errors.New("Invalid session id format")
	} else {
		if str, found := v.(string); found {
			if bson.IsObjectIdHex(str) {
				return bson.ObjectIdHex(str), nil
			} else {
				return bson.ObjectId(""), errors.New("Invalid session id format")
			}
		} else {
			return bson.ObjectId(""), errors.New("Invalid session id format")
		}
	}
}
Exemple #9
0
func parseTopic(req *http.Request) (uint, error) {
	for i, v := range TOPICS {
		if len(req.FormValue(v)) == 0 {
			continue
		}
		return uint(i), nil
	}
	return 1, errors.New("Not Found")
}
Exemple #10
0
func parseSchoolGrade(req *http.Request) (string, error) {
	gradeType := req.FormValue("gradeType")
	schoolGrade := req.FormValue("schoolGrade")

	var numGrade int
	if n, _ := fmt.Sscanf(schoolGrade, "%d", &numGrade); n < 1 || numGrade < 0 {
		return "", errors.New("Invalid Grade")
	}

	return fmt.Sprintf("%s@%d", gradeType, numGrade), nil
}
func SetGMSessionValue(req *http.Request, resp http.ResponseWriter, key, value interface{}) error {
	//Ignore the error since sometimes the browser side coolie storage is broken
	//But we still can assign new cookies
	s, _ := SessionStorage.Get(req, GM_AUTH_SESSION)
	if s == nil {
		return errors.New("Session " + GM_AUTH_SESSION + " not available")
	}

	s.Values[key] = value
	return s.Save(req, resp)
}
func initStorage() {
	if !Config.IsSet("storage.serviceAccountEmail") || !Config.IsSet("storage.privateKeyPath") {
		panic(errors.New("storage.serviceAccountEmail or storage.privateKeyPath not set"))
	}

	StorageServiceAccountEmail = Config.GetString("storage.serviceAccountEmail")
	//LogD.Println("Service account: " + StorageServiceAccountEmail)

	privateKeyPath := Config.GetString("storage.privateKeyPath")
	if file, err := os.Open(privateKeyPath); err != nil {
		panic(errors.New("storage.privateKeyPath not exist"))
	} else {
		defer file.Close()
		if StoragePrivateKey, err = ioutil.ReadAll(file); err != nil {
			panic(errors.New("storage.privateKeyPath read file error"))
		} else {
			//LogD.Printf("Private key length: %d\n", len(StoragePrivateKey))
		}
	}
}
Exemple #13
0
// 遍历目录,加载挂件
func LoadWidgets(topCtx mustache.Context) ([]Widget, string, error) {
	widgets := make([]Widget, 0)
	assets := ""

	err := filepath.Walk("widgets", func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}
		if !info.IsDir() {
			return nil
		}
		cnf_path := path + "/config.yml"
		fst, err := os.Stat(cnf_path)
		if err != nil || fst.IsDir() {
			return nil //ignore
		}
		cnf, err := ReadYml(cnf_path)
		if err != nil {
			return errors.New(cnf_path + ":" + err.Error())
		}
		if cnf["layout"] != nil {
			widget_enable, ok := cnf["layout"].(bool)
			if ok && !widget_enable {
				log.Println("Disable >", cnf_path)
			}
		}
		builderFunc := WidgetBuilders[info.Name()]
		if builderFunc == nil { // 看看是否符合自定义挂件的格式
			_widget, _assets, _err := BuildCustomWidget(info.Name(), path, cnf)
			if _err != nil {
				log.Println("NO WidgetBuilder >>", cnf_path, _err)
			}
			if _widget != nil {
				widgets = append(widgets, _widget)
				if _assets != nil {
					for _, asset := range _assets {
						assets += asset + "\n"
					}
				}
			}
			return nil
		}
		widget, err := builderFunc(cnf, topCtx)
		if err != nil {
			return err
		}
		widgets = append(widgets, widget)
		log.Println("Load widget from ", cnf_path)
		return nil
	})
	return widgets, assets, err
}
func GetSessionUserId(req *http.Request) (bson.ObjectId, error) {

	if data := req.Header.Get(GM_PERMITTED_HEADER_KEY); len(data) != 0 && bson.IsObjectIdHex(data) {
		//Controlled user id
		user_id := bson.ObjectIdHex(data)
		return user_id, nil
	}

	if v, err := GetUserSessionValue(req, USER_ID_SESSION_KEY); err != nil || v == nil {
		return bson.ObjectId(""), errors.New("Invalid session id format")
	} else {
		if str, found := v.(string); found {
			if bson.IsObjectIdHex(str) {
				return bson.ObjectIdHex(str), nil
			} else {
				return bson.ObjectId(""), errors.New("Invalid session id format")
			}
		} else {
			return bson.ObjectId(""), errors.New("Invalid session id format")
		}
	}
}
Exemple #15
0
func parseRecommendationLetters(req *http.Request) ([]public.BasicUser, error) {
	var letters []public.BasicUser

	rawJson := req.FormValue("recommendationLetters")
	if len(rawJson) == 0 {
		return letters, errors.New("No argument")
	}

	decoder := json.NewDecoder(strings.NewReader(rawJson))
	if _, e := decoder.Token(); e != nil { //The first array bracket
		return letters, errors.New("Wrong json format")
	}

	element := public.BasicUser{}
	for decoder.More() {
		if e := decoder.Decode(&element); e != nil {
			continue
		}
		letters = append(letters, element)
	}

	decoder.Token() //The last array bracket
	return letters, nil
}
Exemple #16
0
func parseStudiedClasses(req *http.Request) ([]db.StudiedClass, error) {
	var classes []db.StudiedClass

	rawJson := req.FormValue("classHistory")
	if len(rawJson) == 0 {
		return classes, errors.New("No argument")
	}

	decoder := json.NewDecoder(strings.NewReader(rawJson))
	if _, e := decoder.Token(); e != nil { //The first array bracket
		return classes, errors.New("Wrong json format")
	}

	element := db.StudiedClass{}
	for decoder.More() {
		if e := decoder.Decode(&element); e != nil {
			continue
		}
		classes = append(classes, element)
	}

	decoder.Token() //The last array bracket
	return classes, nil
}
Exemple #17
0
func RenderInLayout(content string, layoutName string, layouts map[string]Mapper, ctx mustache.Context) (string, error) {
	//log.Println("Render Layout", layoutName, ">>", content, "<<END")
	ctx2 := make(map[string]string)
	ctx2["content"] = content
	layout := layouts[layoutName]
	if layout == nil {
		return "", errors.New("Not such Layout : " + layoutName)
	}
	//log.Println(layoutName, layout["_content"])
	buf := &bytes.Buffer{}
	err := layout["_content"].(*DocContent).TPL.Render(mustache.MakeContexts(ctx2, ctx), buf)
	if err != nil {
		return content, err
	}
	if layout.Layout() != "" {
		return RenderInLayout(buf.String(), layout.Layout(), layouts, ctx)
	}
	return buf.String(), nil
}
func initRecommLetter() {
	RecommLetterSubject = `NTHU A+ Recommendation Request`
	recommLetterContentTmpl := `
		Hi,
		This is NTHU A+ management team.
		{{.ApplyUser.Name}}({{.ApplyUser.Email}}) wanted to request for your recommendation in his/her application.
		If you know about this, please visit {{.RecommUrl}} to leave your recommendation.

		Best Regards,

		NTHU A+ management team
		http://www.nthuaplus.org
	`

	var err error
	RecommLetterTmpl, err = template.New("recommLetter").Parse(recommLetterContentTmpl)
	if err != nil {
		panic(errors.New("Error parsing recommendation letter template: " + err.Error()))
	}
}
Exemple #19
0
func (y *yamlReader) ReadMap(minIndent int) (map[string]interface{}, error) {
	_map := map[string]interface{}{}
	//log.Println("ReadMap", minIndent)
OUT:
	for {
		line, err := y.NextLine()
		if err != nil {
			return _map, err
		}
		indent, str := getIndent(line)
		//log.Printf("Indent : %d, str = %s", indent, str)
		switch {
		case indent < minIndent:
			y.lastLine = line
			if len(_map) == 0 {
				return nil, nil
			}
			return _map, nil
		case indent == minIndent:
			key, value, err := y.asMapKeyValue(str)
			if err != nil {
				return nil, err
			}
			//log.Println("Key=", key, "value=", value)
			switch value {
			case nil:
				return nil, y.Error("Unexpect", nil)
			case MAP_KEY_ONLY:
				//log.Println("KeyOnly, read inner Map", key)

				//--------------------------------------
				_line, err := y.NextLine()
				if err != nil {
					if err == io.EOF {
						if _line == "" {
							// Emtry map item?
							_map[key.(string)] = nil
							return _map, err
						}
					} else {
						return nil, y.Error("ERR?", err)
					}
				}
				y.lastLine = _line
				_indent, _str := getIndent(_line)
				if _indent < minIndent {
					return _map, nil
				}
				////log.Println("##>>", _indent, _str)
				if _indent == minIndent {
					if _str[0] == '-' {
						//log.Println("Read Same-Indent ListItem for Map")
						_list, err := y.ReadList(minIndent)
						if _list != nil {
							_map[key.(string)] = _list
						}
						if err != nil {
							return _map, nil
						}
						continue OUT
					} else {
						// Emtry map item?
						_map[key.(string)] = nil
						continue OUT
					}
				}
				//--------------------------------------
				//log.Println("Read Map Item", _indent, _str)

				obj, err := y.ReadObject(_indent)
				if obj != nil {
					_map[key.(string)] = obj
				}
				if err != nil {
					return _map, err
				}
			default:
				_map[key.(string)] = value
			}
		default:
			//log.Println("Bad", indent, str)
			return nil, y.Error("Bad Indent\n"+line, nil)
		}
	}
	panic("ERROR")
	return nil, errors.New("Impossible")

}
Exemple #20
0
func (y *yamlReader) Error(msg string, err error) error {
	if err != nil {
		return errors.New(fmt.Sprintf("line %d : %s : %v", y.lineNum, msg, err.Error()))
	}
	return errors.New(fmt.Sprintf("line %d >> %s", y.lineNum, msg))
}
Exemple #21
0
func (y *yamlReader) ReadList(minIndent int) ([]interface{}, error) {
	list := []interface{}{}
	for {
		line, err := y.NextLine()
		if err != nil {
			return list, err
		}
		indent, str := getIndent(line)
		switch {
		case indent < minIndent:
			y.lastLine = line
			if len(list) == 0 {
				return nil, nil
			}
			return list, nil
		case indent == minIndent:
			if str[0] != '-' {
				y.lastLine = line
				return list, nil
			}
			if len(str) < 2 {
				return nil, y.Error("ListItem is Emtry", nil)
			}
			key, value, err := y.asMapKeyValue(str[1:])
			if err != nil {
				return nil, err
			}
			switch value {
			case nil:
				list = append(list, key)
			case MAP_KEY_ONLY:
				return nil, y.Error("Not support List-Map yet", nil)
			default:
				_map := map[string]interface{}{key.(string): value}
				list = append(list, _map)

				_line, _err := y.NextLine()
				if _err != nil && _err != io.EOF {
					return nil, err
				}
				if _line == "" {
					return list, nil
				}
				y.lastLine = _line
				_indent, _str := getIndent(line)
				if _indent >= minIndent+2 {
					switch _str[0] {
					case '-':
						return nil, y.Error("Unexpect", nil)
					case '[':
						return nil, y.Error("Unexpect", nil)
					case '{':
						return nil, y.Error("Unexpect", nil)
					}
					// look like a map
					_map2, _err := y.ReadMap(_indent)
					if _map2 != nil {
						_map2[key.(string)] = value
					}
					if err != nil {
						return list, _err
					}
				}
			}
			continue
		default:
			return nil, y.Error("Bad Indent\n"+line, nil)
		}
	}
	panic("ERROR")
	return nil, errors.New("Impossible")
}
Exemple #22
0
func Compile() error {
	var payload Mapper
	var ctx mustache.Context
	var docCont *DocContent
	//var tpl *mustache.Template
	var str string
	var err error
	//var mdParser *markdown.Parser
	//var buf *bytes.Buffer
	var layouts map[string]Mapper
	payload, err = BuildPlayload()
	if err != nil {
		return err
	}

	payload_ctx := mustache.MakeContextDir(payload, ".tmp_partials/")
	themeName := FromCtx(payload_ctx, "site.config.theme").(string)

	os.Remove(".tmp_partials")
	copyDir("partials", ".tmp_partials")
	copyDir("themes/"+themeName+"/partials", ".tmp_partials")

	db_posts_dict, _ := payload_ctx.Get("db.posts.dictionary")
	//log.Println(">>>>>>>>>>>>", len(db_posts_dict.Val.Interface().(map[string]Mapper)))
	for id, post := range db_posts_dict.Val.Interface().(map[string]Mapper) {
		_tmp, err := PrapreMainContent(id, post["_content"].(*DocContent).Source, payload_ctx)
		if err != nil {
			return err
		}
		post["_content"].(*DocContent).Main = _tmp
		//log.Fatal(_tmp)
	}

	//mdParser = markdown.NewParser(&markdown.Extensions{Smart: true})
	helpers := make(map[string]mustache.SectionRenderFunc)
	ctxHelpers := make(map[string]func(interface{}) interface{})

	dynamicCtx := make(Mapper)
	topCtx := mustache.MakeContexts(payload_ctx, helpers, ctxHelpers, map[string]Mapper{"dynamic": dynamicCtx})

	widgets, widget_assets, err := LoadWidgets(topCtx)
	if err != nil {
		return err
	}

	//log.Println(">>>", payload_ctx.Dir(), "?>", topCtx.Dir())

	BaiscHelpers(payload, helpers, topCtx)
	CtxHelpers(payload, ctxHelpers, topCtx)
	layouts = payload["layouts"].(map[string]Mapper)

	if len(widgets) > 0 {
		widget_assets += PrapareAssets(themeName, "widgets", topCtx)
	}

	CopyResources(themeName)

	// Render Pages
	pages := payload["db"].(map[string]interface{})["pages"].(map[string]Mapper)
	for id, page := range pages {
		docCont = page["_content"].(*DocContent)
		top := make(map[string]interface{})
		top["current_page_id"] = id
		top["page"] = page
		top["assets"] = PrapareAssets(themeName, page.Layout(), topCtx) + widget_assets
		widgetCtx := PrapareWidgets(widgets, page, topCtx)
		ctx = mustache.MakeContexts(page, top, topCtx, widgetCtx)
		//log.Println(">>", ctx.Dir(), topCtx.Dir())
		_tmp, err := PrapreMainContent(id, docCont.Source, ctx)
		if err != nil {
			return err
		}
		page["_content"].(*DocContent).Main = _tmp

		str, err = RenderInLayout(docCont.Main, page.Layout(), layouts, ctx)
		if err != nil {
			return errors.New(id + ">" + err.Error())
		}
		WriteTo(page.Url(), str)
	}

	// Render Posts
	for id, post := range db_posts_dict.Val.Interface().(map[string]Mapper) {
		top := make(map[string]interface{})
		top["current_page_id"] = id
		top["page"] = post
		top["assets"] = PrapareAssets(themeName, post.Layout(), topCtx) + widget_assets
		docCont = post["_content"].(*DocContent)
		widgetCtx := PrapareWidgets(widgets, post, topCtx)
		ctx = mustache.MakeContexts(post, top, topCtx, widgetCtx)

		str, err = RenderInLayout(docCont.Main, post.Layout(), layouts, ctx)
		if err != nil {
			return errors.New(id + ">" + err.Error())
		}

		WriteTo(post.Url(), str)
	}

	if Plugins != nil {
		for _, plugin := range Plugins {
			plugin.Exec(topCtx)
		}
	}

	log.Println("Done")
	return nil
}
Exemple #23
0
// 编译整个网站
func Compile() error {
	var ctx mustache.Context // 渲染上下文
	var docCont *DocContent  // 文档内容,仅作为变量声明
	var str string           // 仅声明,以减少不一样的编译错误
	var err error            // 仅声明

	var layouts map[string]Mapper

	payload, err := BuildPlayload("./") // payload,核心上下文的主要部分,不可变
	if err != nil {
		log.Println("Build PayLoad FAIL!!")
		return err
	}

	payload_ctx := mustache.MakeContextDir(payload, ".tmp_partials/")
	themeName := FromCtx(payload_ctx, "site.config.theme").(string)

	if FromCtx(payload_ctx, "site.config.markdown.toc_title") != nil {
		TOC_TITLE = FromCtx(payload_ctx, "site.config.markdown.toc_title").(string)
	}

	os.Remove(".tmp_partials")
	copyDir("partials", ".tmp_partials")
	copyDir("themes/"+themeName+"/partials", ".tmp_partials")

	db_posts_dict, _ := payload_ctx.Get("db.posts.dictionary")
	//log.Println(">>>>>>>>>>>>", len(db_posts_dict.Val.Interface().(map[string]Mapper)))
	for id, post := range db_posts_dict.Val.Interface().(map[string]Mapper) {
		_tmp, err := PrapreMainContent(id, post["_content"].(*DocContent).Source, payload_ctx)
		if err != nil {
			return err
		}
		post["_content"].(*DocContent).Main = _tmp
		//log.Fatal(_tmp)
	}

	//mdParser = markdown.NewParser(&markdown.Extensions{Smart: true})
	helpers := make(map[string]mustache.SectionRenderFunc)
	ctxHelpers := make(map[string]func(interface{}) interface{})

	dynamicMapper := make(Mapper)
	topCtx := mustache.MakeContexts(payload_ctx, helpers, ctxHelpers, dynamicMapper)

	widgets, widget_assets, err := LoadWidgets(topCtx)
	if err != nil {
		return err
	}

	//log.Println(">>>", payload_ctx.Dir(), "?>", topCtx.Dir())

	BaiscHelpers(payload, helpers, topCtx)
	CtxHelpers(payload, ctxHelpers, topCtx)
	layouts = payload["layouts"].(map[string]Mapper)

	if len(widgets) > 0 {
		widget_assets += PrapareAssets(themeName, "widgets", topCtx)
	}

	CopyResources(themeName)

	// Render Pages
	pages := payload["db"].(map[string]interface{})["pages"].(map[string]Mapper)
	for id, page := range pages {
		docCont = page["_content"].(*DocContent)
		//top := make(map[string]interface{})
		dynamicMapper["current_page_id"] = id
		dynamicMapper["page"] = page
		dynamicMapper["assets"] = PrapareAssets(themeName, page.Layout(), topCtx) + widget_assets
		widgetCtx := PrapareWidgets(widgets, page, topCtx)
		ctx = mustache.MakeContexts(page, dynamicMapper, topCtx, widgetCtx)
		//log.Println(">>", ctx.Dir(), topCtx.Dir())
		_tmp, err := PrapreMainContent(id, docCont.Source, ctx)
		if err != nil {
			return err
		}
		page["_content"].(*DocContent).Main = _tmp

		str, err = RenderInLayout(docCont.Main, page.Layout(), layouts, ctx)
		if err != nil {
			return errors.New(id + ">" + err.Error())
		}
		WriteTo(page.Url(), str)
	}

	// Render Posts
	for id, post := range db_posts_dict.Val.Interface().(map[string]Mapper) {
		//top := make(map[string]interface{})
		dynamicMapper["current_page_id"] = id
		dynamicMapper["page"] = post
		dynamicMapper["assets"] = PrapareAssets(themeName, post.Layout(), topCtx) + widget_assets
		docCont = post["_content"].(*DocContent)
		widgetCtx := PrapareWidgets(widgets, post, topCtx)
		ctx = mustache.MakeContexts(post, dynamicMapper, topCtx, widgetCtx)

		str, err = RenderInLayout(docCont.Main, post.Layout(), layouts, ctx)
		if err != nil {
			return errors.New(id + ">" + err.Error())
		}

		WriteTo(post.Url(), str)
	}

	//我们还得把分页给解决了哦
	if paginatorCnf := FromCtx(topCtx, "site.config.paginator"); paginatorCnf != nil {
		var pgCnf Mapper
		pgCnf = paginatorCnf.(map[string]interface{})
		if _, ok := layouts[pgCnf.String("layout")]; ok {
			log.Println("Enable paginator")
			renderPaginator(pgCnf, layouts, topCtx, widgets)
		} else {
			log.Println("Layout Not Found", pgCnf.String("layout"))
		}
	}

	if Plugins != nil {
		for _, plugin := range Plugins {
			plugin.Exec(topCtx)
		}
	}

	log.Println("Done")
	return nil
}
Exemple #24
0
func Parse(r io.Reader) (*Template, error) {
	tpl := &Template{}
	tpl.Tree = make([]Node, 0)
	//var err error

	rd := bufio.NewReaderSize(r, 8192)
	lineNumber := -1
	flag := true
	sections := make([]*SectionNode, 0)
	for flag {
		lineNumber++
		line, err := rd.ReadString('\n')
		if err != nil {
			if err != io.EOF {
				return nil, err
			}
			flag = false
		}

		tags, err := parseLine(line, lineNumber)
		if err != nil {
			return nil, err
		}

		for _, _tag := range tags {
			//log.Printf(">>> %v", _tag)
			_ = log.Ldate
			if _tag.Type != T_CONS {
				_tag.Value = strings.Trim(_tag.Value, "\t\n ")
			}

			switch _tag.Type {
			case T_Comment:
				continue
			case T_Section:
				//log.Printf(">Section [%v] %v", _tag.Value, _tag.Flag)
				sec := &SectionNode{_tag.Value, _tag.Flag, make([]Node, 0)}
				if len(sections) == 0 {
					tpl.Tree = append(tpl.Tree, sec)
					//log.Printf("Tree Len=%v", len(tpl.Tree))
				} else {
					sections[len(sections)-1].Clildren = append(sections[len(sections)-1].Clildren, sec)
				}
				sections = append(sections, sec)
			case T_End:
				if len(sections) == 0 || sections[len(sections)-1].name != _tag.Value {
					//log.Printf(">> %v", sections)
					return nil, errors.New("End TAG  Invaild >>" + _tag.Value)
				}
				//log.Printf(">Section End [%v]", _tag.Value)
				sections = sections[:len(sections)-1]
			default:
				var node Node
				switch _tag.Type {
				case T_CONS:
					//log.Println("Cons ? --> " + _tag.Value)
					node = &ConstantNode{_tag.Value}
				case T_Val:
					node = &ValNode{_tag.Value, _tag.Flag}
				case T_Partial:
					node = &PartialNode{_tag.Value}
				}
				if len(sections) == 0 {
					tpl.Tree = append(tpl.Tree, node)
				} else {
					sections[len(sections)-1].Clildren = append(sections[len(sections)-1].Clildren, node)
				}
			}

		}
	}
	return tpl, nil
}