Exemple #1
0
func PrapareWidgets(widgets []Widget, mapper Mapper, topCtx mustache.Context) mustache.Context {
	mappers := make([]interface{}, 0)
	for _, widget := range widgets {
		mr := widget.Prepare(mapper, topCtx)
		if mr != nil {
			mappers = append(mappers, mr)
		}
	}
	return mustache.MakeContexts(mappers...)
}
Exemple #2
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]
	//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
}
Exemple #3
0
func RenderInLayout(content string, layoutName string, layouts map[string]Mapper, ctx mustache.Context) (string, error) {
	Log(DEBUG, "Render layout %q >>\n%s\nEOF\n", layoutName, content)
	ctx2 := make(map[string]string)
	ctx2["content"] = content
	layout := layouts[layoutName]
	if layout == nil {
		errMsg := fmt.Sprintf("Not found %s layout", layoutName)
		return "", errors.New(errMsg)
	}
	if c, ok := layout["_content"].(string); ok {
		Log(DEBUG, "Layout %q >>\n%s\nEOF", layoutName, c)
	}
	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
}
Exemple #4
0
func renderPaginator(pgCnf Mapper, layouts map[string]Mapper, topCtx mustache.Context, widgets []Widget) {
	summary_lines := int(FromCtx(topCtx, "site.config.posts.summary_lines").(int64))
	per_page := pgCnf.Int("per_page")
	if per_page < 2 {
		per_page = 2
	} else if per_page > 100 {
		per_page = 100
	}
	namespace := pgCnf.String("namespace")
	if namespace == "" {
		namespace = "/posts/"
	}
	layout := pgCnf.String("layout")

	posts_ctx := make(Mapper)

	chronological, _ := FromCtx(topCtx, "db.posts.chronological").([]string)
	dictionary, _ := FromCtx(topCtx, "db.posts.dictionary").(map[string]Mapper)

	page_count := len(chronological)/per_page + 1
	if len(chronological)%per_page == 0 {
		page_count--
	}

	paginator_navigation := make([]Mapper, page_count)
	for i := 0; i < len(paginator_navigation); i++ {
		pn := make(Mapper)
		pn["page_number"] = i + 1
		pn["name"] = fmt.Sprintf("%d", i+1)
		pn["url"] = fmt.Sprintf("%s%d/", namespace, i+1)
		pn["is_active_page"] = false
		paginator_navigation[i] = pn
	}

	posts_ctx["paginator_navigation"] = paginator_navigation

	one_page := make([]Mapper, 0)
	current_page_number := 0
	log.Println("Total posts: ", len(chronological))
	for i, post_id := range chronological {
		if i != 0 && i%per_page == 0 {
			current_page_number++
			log.Printf("Rendering page #%d with %d posts", current_page_number, len(one_page))
			posts_ctx["current_page_number"] = current_page_number
			posts_ctx["paginator"] = one_page
			if current_page_number >= 2 {
				paginator_navigation[current_page_number-2]["is_active_page"] = false
			}
			paginator_navigation[current_page_number-1]["is_active_page"] = true
			widgetCtx := PrapareWidgets(widgets, make(Mapper), topCtx)
			renderOnePager(paginator_navigation[current_page_number-1].String("url"), layout, layouts,
				mustache.MakeContexts(map[string]interface{}{"posts": posts_ctx,
					"page": map[string]interface{}{}}, topCtx, widgetCtx))
			one_page = one_page[0:0]
		}
		post := dictionary[post_id]
		post["summary"] = MakeSummary(post, summary_lines, topCtx)
		one_page = append(one_page, post)
	}
	if len(one_page) > 0 {
		current_page_number++
		log.Printf("Rendering page #%d with %d post(s)", current_page_number, len(one_page))
		posts_ctx["current_page_number"] = current_page_number
		posts_ctx["paginator"] = one_page
		if current_page_number >= 2 {
			paginator_navigation[current_page_number-2]["is_active_page"] = false
		}
		paginator_navigation[current_page_number-1]["is_active_page"] = true
		m := make(Mapper)
		widgetCtx := PrapareWidgets(widgets, m, topCtx)
		renderOnePager(paginator_navigation[current_page_number-1].String("url"), layout, layouts,
			mustache.MakeContexts(map[string]interface{}{"posts": posts_ctx,
				"page": map[string]interface{}{}}, topCtx, widgetCtx))
	}
}
Exemple #5
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 #6
0
func BaiscHelpers(payload Mapper, helpers map[string]mustache.SectionRenderFunc, topCtx mustache.Context) {
	var err error
	chronological := FromCtx(topCtx, "db.posts.chronological").([]string)
	latest_size := FromCtx(topCtx, "site.config.posts.latest").(int)
	dict := FromCtx(topCtx, "db.posts.dictionary").(map[string]Mapper)
	summary_lines := int(FromCtx(topCtx, "site.config.posts.summary_lines").(int64))
	latest_posts := make([]Mapper, 0)
	for _, id := range chronological {
		latest_posts = append(latest_posts, dict[id])
		if len(latest_posts) >= latest_size {
			break
		}
	}
	//-------------------------------
	helpers["posts_latest"] = func(nodes []mustache.Node, inverted bool, ctx mustache.Context, w io.Writer) error {
		if inverted {
			return nil
		}

		for _, post := range latest_posts {
			top := map[string]interface{}{}
			top["summary"] = MakeSummary(post, summary_lines, topCtx)
			//log.Println(top["summary"])
			top["content"] = post["_content"].(*DocContent).Main
			for _, node := range nodes {
				err = node.Render(mustache.MakeContexts(post, top, ctx), w)
				if err != nil {
					return err
				}
			}
		}
		return nil
	}

	pages := FromCtx(topCtx, "db.pages").(map[string]Mapper)

	helpers["pages"] = func(nodes []mustache.Node, inverted bool, ctx mustache.Context, w io.Writer) error {
		if inverted {
			return nil
		}

		current_page_id := FromCtx(ctx, "current_page_id")
		for id, page := range pages {
			top := map[string]interface{}{}
			if current_page_id != nil {
				top["is_active_page"] = id == current_page_id.(string)
			}
			for _, node := range nodes {
				err = node.Render(mustache.MakeContexts(page, top, ctx), w)
				if err != nil {
					return err
				}
			}
		}
		return nil
	}

	helpers["posts"] = func(nodes []mustache.Node, inverted bool, ctx mustache.Context, w io.Writer) error {
		if inverted {
			return nil
		}
		for _, post := range dict {
			for _, node := range nodes {
				err = node.Render(mustache.MakeContexts(post, ctx), w)
				if err != nil {
					return err
				}
			}
		}
		return nil
	}

	categories := FromCtx(topCtx, "db.posts.categories").(map[string]*Catalog)
	helpers["categories"] = func(nodes []mustache.Node, inverted bool, ctx mustache.Context, w io.Writer) error {
		if inverted {
			return nil
		}
		//log.Println("Using #categories")
		for _, categorie := range categories {
			for _, node := range nodes {
				err = node.Render(mustache.MakeContexts(categorie, ctx), w)
				if err != nil {
					return err
				}
			}
		}
		return nil
	}

	tags := FromCtx(topCtx, "db.posts.tags").(map[string]*Tag)
	helpers["tags"] = func(nodes []mustache.Node, inverted bool, ctx mustache.Context, w io.Writer) error {
		if inverted {
			return nil
		}
		for _, tag := range tags {
			for _, node := range nodes {
				err = node.Render(mustache.MakeContexts(tag, ctx), w)
				if err != nil {
					return err
				}
			}
		}
		return nil
	}
	return
}
Exemple #7
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, "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)
	}
	themeName := FromCtx(payload_ctx, "site.config.theme").(string)

	//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, 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)

	widget_assets := ""
	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 #8
0
// 编译整个网站
func Compile(public string) error {
	var ctx mustache.Context // 渲染上下文
	var docCont *DocContent  // 文档内容,仅作为变量声明
	var str string           // 仅声明,以减少不一样的编译错误
	var err error            // 仅声明

	var layouts map[string]Mapper

	payload, err := BuildPayload("./") // payload,核心上下文的主要部分,不可变
	if err != nil {
		Log(INFO, "Build payload fail, %s!!", err)
		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")

	theme_partials := filepath.Join("themes/", themeName, "/partials")
	if fi, err := os.Stat(theme_partials); err == nil && fi.IsDir() {
		copyDir(theme_partials, ".tmp_partials")
	}

	defer os.Remove(".tmp_partials")

	db_posts_dict, _ := payload_ctx.Get("db.posts.dictionary")
	Log(DEBUG, "Total of db posts dictionary: %d", 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(DEBUG, "Markdown to HTML: \n%s\n", _tmp)
	}

	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(DEBUG, 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(public, 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(DEBUG, "%s %s", 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(fmt.Sprintf("Page %d > %s", id, err.Error()))
		}
		WriteTo(public, 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(fmt.Sprintf("Post %d > %s", id, err.Error()))
		}

		WriteTo(public, 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(INFO, "Enable paginator")
			renderPaginator(public, pgCnf, layouts, topCtx, widgets)
		} else {
			Log(INFO, "Layout Not Found", pgCnf.String("layout"))
		}
	}

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

	Log(INFO, "Done")
	return nil
}