Example #1
0
// ReadPosts read posts files in srcDir/post
func ReadPosts(ctx *Context) ([]*model.Post, error) {
	srcDir := ctx.SrcPostDir()
	if !com.IsDir(srcDir) {
		return nil, fmt.Errorf("posts directory '%s' is missing", srcDir)
	}
	log15.Info("Read|Posts|%s", srcDir)

	// try load post.toml or post.ini to read total meta file
	var (
		err      error
		postMeta = make(map[string]*model.Post)
	)
	for t, f := range model.ShouldPostMetaFiles() {
		file := filepath.Join(ctx.SrcDir(), f)
		if !com.IsFile(file) {
			continue
		}
		postMeta, err = model.NewPostsFrontMatter(file, t)
		if err != nil {
			return nil, err
		}
		log15.Debug("Read|PostMeta|%s", file)
		break
	}

	var posts []*model.Post
	err = filepath.Walk(srcDir, func(p string, fi os.FileInfo, err error) error {
		if err != nil {
			return err
		}
		if fi.IsDir() {
			return nil
		}
		p = filepath.ToSlash(p)
		if filepath.Ext(p) == ".md" {
			metaKey := strings.TrimPrefix(p, filepath.ToSlash(srcDir+"/"))
			log15.Debug("Read|%s|%v", p, postMeta[metaKey] != nil)
			post, err := model.NewPostOfMarkdown(p, postMeta[metaKey])
			if err != nil {
				log15.Warn("Read|Post|%s|%v", p, err)
				return nil
			} else if post != nil && !post.Draft {
				posts = append(posts, post)
			}
			if post.Draft == true {
				log15.Warn("Draft|%s", p)
			}
		}
		return nil
	})
	sort.Sort(model.Posts(posts))
	return posts, err
}
Example #2
0
// AssembleSource assemble some extra data in Source,
// such as page nodes, i18n status.
// it need be used after posts and pages are loaded
func AssembleSource(ctx *Context) {
	if ctx.Source == nil || ctx.Theme == nil {
		ctx.Err = fmt.Errorf("need sources data and theme to assemble")
		return
	}

	ctx.Source.Nav.SetPrefix(ctx.Source.Meta.Path)
	ctx.Source.Tags = make(map[string]*model.Tag)
	ctx.Source.TagPosts = make(map[string]*model.TagPosts)
	ctx.Source.PagePosts = make(map[int]*model.PagerPosts)

	r, hr := newReplacer(ctx.Source.Meta.Path), newReplacerInHTML(ctx.Source.Meta.Path)
	ctx.Source.Meta.Cover = r.Replace(ctx.Source.Meta.Cover)
	for _, a := range ctx.Source.Authors {
		a.Avatar = r.Replace(a.Avatar)
	}

	// fill post data
	for _, p := range ctx.Source.Posts {
		if ctx.Source.Meta.Path != "" && ctx.Source.Meta.Path != "/" {
			p.SetURL(path.Join(ctx.Source.Meta.Path, p.URL()))
		}
		p.SetDestURL(filepath.Join(ctx.DstDir(), p.URL()))
		p.SetPlaceholder(r, hr)
		ctx.Tree.Add(p.DestURL(), p.Title, model.TreePost, 0)
		if p.Author == nil {
			p.Author = ctx.Source.Authors[p.AuthorName]
		}
		for _, t := range p.Tags {
			ctx.Source.Tags[t.Name] = t
			if ctx.Source.TagPosts[t.Name] == nil {
				ctx.Source.TagPosts[t.Name] = &model.TagPosts{
					Posts: []*model.Post{p},
					Tag:   t,
				}
			} else {
				ctx.Source.TagPosts[t.Name].Posts = append(ctx.Source.TagPosts[t.Name].Posts, p)
			}
		}
	}

	// fill page data
	for _, p := range ctx.Source.Pages {
		if ctx.Source.Meta.Path != "" && ctx.Source.Meta.Path != "/" {
			p.SetURL(path.Join(ctx.Source.Meta.Path, p.URL()))
		}
		p.SetDestURL(filepath.Join(ctx.DstDir(), p.URL()))
		p.SetPlaceholder(hr)
		treeType := model.TreePage
		if p.Node {
			treeType = model.TreePageNode
		}
		ctx.Tree.Add(p.DestURL(), p.Title, treeType, p.Sort)
		if p.Author == nil {
			p.Author = ctx.Source.Authors[p.AuthorName]
		}
	}

	// prepare tag posts
	for _, tp := range ctx.Source.TagPosts {
		sort.Sort(model.Posts(tp.Posts))
		tp.SetDestURL(path.Join(ctx.DstDir(),
			ctx.Source.Meta.Path, tp.Tag.URL))
		ctx.Tree.Add(tp.DestURL(), "", model.TreePostTag, 0)
	}

	// prepare archives
	archives := model.NewArchive(ctx.Source.Posts)
	archives.SetDestURL(filepath.Join(ctx.DstDir(), archives.DestURL()))
	ctx.Source.Archive = archives
	ctx.Tree.Add(archives.DestURL(), "Archive", model.TreeArchive, 0)

	// prepare paged posts
	var (
		cursor = helper.NewPagerCursor(4, len(ctx.Source.Posts))
		page   = 1
		layout = "posts/%d"
	)
	for {
		pager := cursor.Page(page)
		if pager == nil {
			ctx.Source.PostPage = page - 1
			break
		}
		currentPosts := ctx.Source.Posts[pager.Begin:pager.End]
		pager.SetLayout(path.Join(ctx.Source.Meta.Path, "/"+layout+".html"))
		pageURL := path.Join(ctx.Source.Meta.Path, fmt.Sprintf(layout+".html", pager.Current))
		pp := &model.PagerPosts{
			Posts: currentPosts,
			Pager: pager,
			URL:   pageURL,
		}
		pp.SetDestURL(path.Join(ctx.DstDir(), pageURL))
		ctx.Source.PagePosts[pager.Current] = pp
		ctx.Tree.Add(pp.DestURL(), "", model.TreePostList, 0)
		if pager.Current == 1 {
			// use new object, not pp
			pp2 := model.PagerPosts{
				Posts: currentPosts,
				Pager: pager,
			}
			pp2.SetDestURL(path.Join(ctx.DstDir(), "index.html"))
			ctx.Source.IndexPosts = pp2
			ctx.Tree.Add(path.Join(ctx.DstDir(), "index.html"), "Home", model.TreeIndex, 0)
		}
		page++
	}

	ctx.Tree.Add(path.Join(ctx.DstDir(), ctx.Source.Meta.Path, "feed.xml"), "Feed", model.TreeXML, 0)
	ctx.Tree.Add(path.Join(ctx.DstDir(), ctx.Source.Meta.Path, "sitemap.xml"), "Sitemap", model.TreeXML, 0)

	if ctx.Err = ctx.Theme.Load(); ctx.Err != nil {
		return
	}

	log15.Info("Assemble|Done")
}