From f153f3afce9e79a0cd935ff4b7011668429b7a3f Mon Sep 17 00:00:00 2001 From: Oliver Steele Date: Fri, 1 Sep 2017 09:10:07 -0400 Subject: [PATCH] Emulate github-pages plugin --- config/config.go | 2 +- docs/plugins.md | 2 ++ plugins/github_pages.go | 38 ++++++++++++++++++++++++++++++ plugins/plugins.go | 7 ++++-- site/plugins.go | 51 +++++++++++++++++++++++++++++++++++++++++ site/read.go | 4 +++- site/site.go | 13 +---------- utils/strings.go | 4 ++-- 8 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 plugins/github_pages.go create mode 100644 site/plugins.go diff --git a/config/config.go b/config/config.go index 3a98d00..e9b5239 100644 --- a/config/config.go +++ b/config/config.go @@ -145,7 +145,7 @@ func (c *Config) RequiresFrontMatter(rel string) bool { return true case !c.IsMarkdown(rel): return true - case utils.StringContains(c.Include, rel): + case utils.StringArrayContains(c.Include, rel): return false case c.RequireFrontMatterExclude[strings.ToUpper(utils.TrimExt(filepath.Base(rel)))]: return true diff --git a/docs/plugins.md b/docs/plugins.md index c6d0bcb..405a0e7 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -24,6 +24,7 @@ The functionality of some plugins is built into the core program: | [jekyll-sitemap][jekyll-sitemap] | GitHub Pages | ✓ | file modified dates⁴ | | [jekyll-titles-from-headings][jekyll-titles-from-headings] | GitHub Pages | | | | [jemoji][jemoji] | GitHub Pages | ✓ | image tag fallback | +| [GitHub pages][github-pages] | GitHub Pages | ✓ | The plugins that github-pages *includes* are in various stages of implementation, listed above | ¹ (1) The code and internal APIs are too immature for this; and (2) the [natural way](https://golang.org/pkg/plugin/) of implementing this only works on Linux. @@ -53,3 +54,4 @@ The [Official Plugins](https://jekyllrb.com/docs/plugins/#available-plugins) sec [jekyll-sitemap]: https://github.com/jekyll/jekyll-sitemap [jekyll-titles-from-headings]: https://github.com/benbalter/jekyll-titles-from-headings [jemoji]: https://github.com/jekyll/jemoji +[github-pages]: https://github.com/github/pages-gem diff --git a/plugins/github_pages.go b/plugins/github_pages.go new file mode 100644 index 0000000..498f98e --- /dev/null +++ b/plugins/github_pages.go @@ -0,0 +1,38 @@ +package plugins + +import "github.com/osteele/gojekyll/utils" + +func init() { + register("github-pages", githubPagesPlugin{}) +} + +type githubPagesPlugin struct{ plugin } + +func (p githubPagesPlugin) ModifyPluginList(names []string) []string { + for _, name := range githubPagesPlugins { + if !utils.StringArrayContains(names, name) { + names = append(names, name) + } + } + return names +} + +var githubPagesPlugins = []string{ + "jekyll-avatar", + "jekyll-coffeescript", + "jekyll-default-layout", + "jekyll-feed", + "jekyll-gist", + "jekyll-github-metadata", + "jekyll-mentions", + "jekyll-optional-front-matter", + "jekyll-paginate", + "jekyll-readme-index", + "jekyll-redirect-from", + "jekyll-relative-links", + "jekyll-sass-converter", + "jekyll-seo-tag", + "jekyll-sitemap", + "jekyll-titles-from-headings", + "jemoji", +} diff --git a/plugins/plugins.go b/plugins/plugins.go index 4fd0150..21be345 100644 --- a/plugins/plugins.go +++ b/plugins/plugins.go @@ -21,6 +21,7 @@ import ( type Plugin interface { Initialize(Site) error ConfigureTemplateEngine(*liquid.Engine) error + ModifyPluginList([]string) []string ModifySiteDrop(Site, map[string]interface{}) error PostRead(Site) error PostRender([]byte) ([]byte, error) @@ -42,16 +43,17 @@ func Lookup(name string) (Plugin, bool) { } // Install installs a registered plugin. -func Install(names []string, site Site) { +func Install(names []string, site Site) error { for _, name := range names { if p, found := directory[name]; found { if err := p.Initialize(site); err != nil { - panic(err) + return err } } else { fmt.Printf("warning: gojekyll does not emulate the %s plugin.\n", name) } } + return nil } // Names returns a sorted list of names of registered plugins. @@ -71,6 +73,7 @@ type plugin struct{} func (p plugin) Initialize(Site) error { return nil } func (p plugin) ConfigureTemplateEngine(*liquid.Engine) error { return nil } +func (p plugin) ModifyPluginList(names []string) []string { return names } func (p plugin) ModifySiteDrop(Site, map[string]interface{}) error { return nil } func (p plugin) PostRead(Site) error { return nil } func (p plugin) PostRender(b []byte) ([]byte, error) { return b, nil } diff --git a/site/plugins.go b/site/plugins.go new file mode 100644 index 0000000..1d36af7 --- /dev/null +++ b/site/plugins.go @@ -0,0 +1,51 @@ +package site + +import ( + "github.com/osteele/gojekyll/plugins" + "github.com/osteele/gojekyll/utils" +) + +func (s *Site) installPlugins() error { + names := s.cfg.Plugins + installed := map[string]bool{} + // install plugins and call their ModifyPluginList lists + for { + pending := []string{} + for _, name := range names { + if !installed[name] { + pending = append(pending, name) + } + } + if len(pending) == 0 { + break + } + if err := plugins.Install(pending, s); err != nil { + return err + } + for _, name := range names { + if !installed[name] { + p, ok := plugins.Lookup(name) + if ok { + names = p.ModifyPluginList(names) + } + } + } + for _, name := range pending { + installed[name] = true + } + } + s.plugins = names + return nil +} + +func (s *Site) runHooks(h func(plugins.Plugin) error) error { + for _, name := range s.plugins { + p, ok := plugins.Lookup(name) + if ok { + if err := h(p); err != nil { + return utils.WrapError(err, "running plugin") + } + } + } + return nil +} diff --git a/site/read.go b/site/read.go index c0e740f..0ba0a8f 100644 --- a/site/read.go +++ b/site/read.go @@ -25,8 +25,10 @@ func FromDirectory(dir string, flags config.Flags) (*Site, error) { // Read loads the site data and files. func (s *Site) Read() error { + if err := s.installPlugins(); err != nil { + return utils.WrapError(err, "initializing plugins") + } s.Routes = make(map[string]pages.Document) - plugins.Install(s.cfg.Plugins, s) if err := s.findTheme(); err != nil { return utils.WrapError(err, "finding theme") } diff --git a/site/site.go b/site/site.go index 8764d9b..d52bfc6 100644 --- a/site/site.go +++ b/site/site.go @@ -22,6 +22,7 @@ type Site struct { cfg config.Config data map[string]interface{} // from _data files flags config.Flags // command-line flags, override config files + plugins []string // initially cfg.Plugins, but plugins can modify this this themeDir string // absolute path to theme directory docs []pages.Document // all documents, whether or not they are output @@ -88,18 +89,6 @@ func (s *Site) Config() *config.Config { return &s.cfg } -func (s *Site) runHooks(h func(plugins.Plugin) error) error { - for _, name := range s.cfg.Plugins { - p, ok := plugins.Lookup(name) - if ok { - if err := h(p); err != nil { - return utils.WrapError(err, "running plugin") - } - } - } - return nil -} - // Site is in the pages.RenderingContext interface. func (s *Site) Site() interface{} { return s diff --git a/utils/strings.go b/utils/strings.go index 4a1d08d..e5f71bc 100644 --- a/utils/strings.go +++ b/utils/strings.go @@ -58,8 +58,8 @@ func StringArrayToMap(a []string) map[string]bool { return m } -// StringContains returns a bool indicating whether the array contains the string. -func StringContains(a []string, s string) bool { +// StringArrayContains returns a bool indicating whether the array contains the string. +func StringArrayContains(a []string, s string) bool { for _, item := range a { if item == s { return true