2017-07-01 05:10:58 +02:00
|
|
|
// Package plugins holds emulated Jekyll plugins.
|
|
|
|
//
|
|
|
|
// Unlike Jekyll, these are baked into the executable -- both because as of 2017.07 package "plugin' currently
|
|
|
|
// works only on Linux, but also because the gojekyll implementation is immature and any possible interfaces
|
|
|
|
// are far from baked.
|
2017-06-30 18:53:34 +02:00
|
|
|
package plugins
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
2017-07-09 03:41:35 +02:00
|
|
|
"github.com/osteele/gojekyll/config"
|
|
|
|
"github.com/osteele/gojekyll/pages"
|
2017-07-01 01:37:31 +02:00
|
|
|
"github.com/osteele/liquid"
|
2017-07-04 23:13:47 +02:00
|
|
|
"github.com/osteele/liquid/render"
|
2017-06-30 18:53:34 +02:00
|
|
|
)
|
|
|
|
|
2017-07-01 05:10:58 +02:00
|
|
|
// PluginContext is the context for plugin initialization.
|
|
|
|
// Currently, the only thing a plugin can do is add filters and tags.
|
2017-06-30 18:53:34 +02:00
|
|
|
type PluginContext interface {
|
|
|
|
TemplateEngine() liquid.Engine
|
|
|
|
}
|
|
|
|
|
2017-07-09 03:41:35 +02:00
|
|
|
// Site is the site interface that is available to a plugin.
|
|
|
|
type Site interface {
|
|
|
|
AddDocument(pages.Document, bool)
|
|
|
|
Config() *config.Config
|
|
|
|
Pages() []pages.Page
|
|
|
|
}
|
|
|
|
|
|
|
|
// Plugin describes the hooks that a plugin can override.
|
|
|
|
type Plugin interface {
|
|
|
|
PostRead(site Site) error
|
|
|
|
}
|
|
|
|
|
|
|
|
type plugin struct{}
|
|
|
|
|
|
|
|
func (p plugin) PostRead(site Site) error { return nil }
|
|
|
|
|
|
|
|
// Find looks up a plugin by name
|
|
|
|
func Find(name string) (Plugin, bool) {
|
|
|
|
switch name {
|
|
|
|
case "jekyll-redirect-from":
|
|
|
|
return jekyllFeedPlugin{}, true
|
|
|
|
default:
|
|
|
|
return nil, false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-01 05:10:58 +02:00
|
|
|
// Install installs a plugin from the plugin directory.
|
2017-06-30 18:53:34 +02:00
|
|
|
func Install(name string, ctx PluginContext) bool {
|
2017-07-09 01:57:41 +02:00
|
|
|
p, found := directory[name]
|
2017-06-30 18:53:34 +02:00
|
|
|
if p != nil {
|
2017-07-04 23:13:47 +02:00
|
|
|
if err := p(ctx, pluginHelper{ctx, name}); err != nil {
|
2017-06-30 18:53:34 +02:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return found
|
|
|
|
}
|
|
|
|
|
2017-07-09 01:57:41 +02:00
|
|
|
var directory = map[string]func(PluginContext, pluginHelper) error{}
|
2017-06-30 18:53:34 +02:00
|
|
|
|
2017-07-09 01:57:41 +02:00
|
|
|
// register installs a plugin in the plugin directory.
|
|
|
|
func register(name string, fn func(PluginContext, pluginHelper) error) {
|
|
|
|
directory[name] = fn
|
2017-06-30 18:53:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2017-07-09 01:57:41 +02:00
|
|
|
register("jekyll-feed", func(ctx PluginContext, h pluginHelper) error {
|
2017-07-01 16:37:11 +02:00
|
|
|
h.stubbed()
|
2017-07-02 05:06:47 +02:00
|
|
|
h.tag("feed_meta", h.makeUnimplementedTag())
|
2017-06-30 18:53:34 +02:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
2017-07-09 01:57:41 +02:00
|
|
|
register("jekyll-seo-tag", func(ctx PluginContext, h pluginHelper) error {
|
2017-07-05 22:54:48 +02:00
|
|
|
h.stubbed()
|
|
|
|
h.tag("seo", h.makeUnimplementedTag())
|
|
|
|
return nil
|
|
|
|
})
|
|
|
|
|
|
|
|
// the following plugins are always active
|
2017-07-02 05:06:47 +02:00
|
|
|
// no warning but effect; the server runs in this mode anyway
|
2017-07-09 01:57:41 +02:00
|
|
|
register("jekyll-live-reload", func(ctx PluginContext, h pluginHelper) error {
|
2017-07-01 19:34:32 +02:00
|
|
|
return nil
|
|
|
|
})
|
2017-07-09 01:57:41 +02:00
|
|
|
register("jekyll-sass-converter", func(ctx PluginContext, h pluginHelper) error {
|
2017-06-30 18:53:34 +02:00
|
|
|
return nil
|
|
|
|
})
|
|
|
|
}
|
2017-07-01 16:37:11 +02:00
|
|
|
|
2017-07-02 05:06:47 +02:00
|
|
|
type pluginHelper struct {
|
2017-07-04 23:13:47 +02:00
|
|
|
PluginContext
|
2017-07-02 05:06:47 +02:00
|
|
|
name string
|
|
|
|
}
|
2017-07-01 16:37:11 +02:00
|
|
|
|
|
|
|
func (h pluginHelper) stubbed() {
|
|
|
|
fmt.Printf("warning: gojekyll does not emulate the %s plugin. Some tags have been stubbed to prevent errors.\n", h.name)
|
|
|
|
}
|
|
|
|
|
2017-07-04 14:06:34 +02:00
|
|
|
func (h pluginHelper) tag(name string, r liquid.Renderer) {
|
2017-07-04 23:13:47 +02:00
|
|
|
h.TemplateEngine().RegisterTag(name, r)
|
2017-07-02 05:06:47 +02:00
|
|
|
}
|
|
|
|
|
2017-07-04 14:06:34 +02:00
|
|
|
func (h pluginHelper) makeUnimplementedTag() liquid.Renderer {
|
2017-07-01 16:37:11 +02:00
|
|
|
warned := false
|
2017-07-04 23:13:47 +02:00
|
|
|
return func(ctx render.Context) (string, error) {
|
2017-07-01 16:37:11 +02:00
|
|
|
if !warned {
|
|
|
|
fmt.Printf("The %q tag in the %q plugin has not been implemented.\n", ctx.TagName(), h.name)
|
|
|
|
warned = true
|
|
|
|
}
|
2017-07-09 03:41:35 +02:00
|
|
|
return fmt.Sprintf(`<!-- unimplemented tag: %q -->`, ctx.TagName()), nil
|
2017-07-01 16:37:11 +02:00
|
|
|
}
|
|
|
|
}
|