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 %}
`