package plugins import ( "fmt" "html" "io" "github.com/osteele/liquid" "github.com/osteele/liquid/render" ) type jekyllFeedPlugin struct { plugin site Site tpl *liquid.Template } func init() { register("jekyll-feed", &jekyllFeedPlugin{}) } func (p *jekyllFeedPlugin) Initialize(s Site) error { p.site = s return nil } func (p *jekyllFeedPlugin) ConfigureTemplateEngine(e *liquid.Engine) error { e.RegisterTag("feed_meta", p.feedMetaTag) tpl, err := e.ParseTemplate([]byte(feedTemplateSource)) if err != nil { panic(err) } p.tpl = tpl return nil } func (p *jekyllFeedPlugin) PostRead(s Site) error { path := "/feed.xml" if cfg, ok := s.Config().Variables["feed"].(map[string]interface{}); ok { if pp, ok := cfg["path"].(string); ok { path = "/" + pp } } d := feedDoc{s, p, path} s.AddDocument(&d, true) return nil } func (p *jekyllFeedPlugin) feedMetaTag(ctx render.Context) (string, error) { cfg := p.site.Config() name, _ := cfg.Variables["name"].(string) tag := fmt.Sprintf(``, html.EscapeString(cfg.AbsoluteURL), html.EscapeString(name)) return tag, nil } type feedDoc struct { site Site plugin *jekyllFeedPlugin path string } func (d *feedDoc) Permalink() string { return d.path } func (d *feedDoc) SourcePath() string { return "" } func (d *feedDoc) OutputExt() string { return ".xml" } func (d *feedDoc) Published() bool { return true } func (d *feedDoc) Static() bool { return false } // FIXME means different things to different callers func (d *feedDoc) Categories() []string { return []string{} } func (d *feedDoc) Tags() []string { return []string{} } func (d *feedDoc) Content() []byte { bindings := map[string]interface{}{"site": d.site} b, err := d.plugin.tpl.Render(bindings) if err != nil { panic(err) } return b } func (d *feedDoc) Write(w io.Writer) error { _, err := w.Write(d.Content()) return err } // Taken verbatim from https://github.com/jekyll/jekyll-feed/ const feedTemplateSource = ` {% if page.xsl %} {% endif %} Jekyll {{ site.time | date_to_xmlschema }} {{ '/' | absolute_url | xml_escape }} {% if site.title %} {{ site.title | smartify | xml_escape }} {% elsif site.name %} {{ site.name | smartify | xml_escape }} {% endif %} {% if site.description %} {{ site.description | xml_escape }} {% endif %} {% if site.author %} {{ site.author.name | default: site.author | xml_escape }} {% if site.author.email %} {{ site.author.email | xml_escape }} {% endif %} {% if site.author.uri %} {{ site.author.uri | xml_escape }} {% endif %} {% endif %} {% assign posts = site.posts | where_exp: "post", "post.draft != true" %} {% for post in posts limit: 10 %} {{ post.title | smartify | strip_html | normalize_whitespace | xml_escape }} {{ post.date | date_to_xmlschema }} {{ post.last_modified_at | default: post.date | date_to_xmlschema }} {{ post.id | absolute_url | xml_escape }} {{ post.content | strip | xml_escape }} {% assign post_author = post.author | default: post.authors[0] | default: site.author %} {% assign post_author = site.data.authors[post_author] | default: post_author %} {% assign post_author_email = post_author.email | default: nil %} {% assign post_author_uri = post_author.uri | default: nil %} {% assign post_author_name = post_author.name | default: post_author %} {{ post_author_name | default: "" | xml_escape }} {% if post_author_email %} {{ post_author_email | xml_escape }} {% endif %} {% if post_author_uri %} {{ post_author_uri | xml_escape }} {% endif %} {% if post.category %} {% endif %} {% for tag in post.tags %} {% endfor %} {% if post.excerpt and post.excerpt != empty %} {{ post.excerpt | strip_html | normalize_whitespace | xml_escape }} {% endif %} {% assign post_image = post.image.path | default: post.image %} {% if post_image %} {% unless post_image contains "://" %} {% assign post_image = post_image | absolute_url | xml_escape %} {% endunless %} {% endif %} {% endfor %} `