mirror of
https://github.com/danog/gojekyll.git
synced 2024-11-30 07:48:58 +01:00
Implement site.{pages,static_files,documents}
This commit is contained in:
parent
55ac57dcbe
commit
266c14c798
21
README.md
21
README.md
@ -40,15 +40,21 @@ gojekyll help build
|
||||
## Limitations
|
||||
|
||||
- Missing features:
|
||||
- themes, page tags, excerpts, plugins (except for a few listed below), pagination, math, warning mode.
|
||||
- Site variables: `pages`, `static_files`, `html_pages`, `html_files`, `documents`, and `tags`
|
||||
- Jekyll filters: `group_by_exp`, `pop`, `shift`, `cgi_escape`, `uri_escape`, `scssify`, and `smartify`.
|
||||
- See the [Liquid README](https://github.com/osteele/liquid/#status) for documentation of its limitations.
|
||||
- Data files must be YAML. CSV and JSON data files are not supported.
|
||||
- Themes
|
||||
- Excerpts
|
||||
- Pagination
|
||||
- Math
|
||||
- Warning mode
|
||||
- Plugins, except `jekyll-avatar` and `jekyll-gist`
|
||||
- Site variables: `html_pages`, `html_files`, and `tags`
|
||||
- Jekyll filters: `group_by_exp`, `pop`, `shift`, `cgi_escape`, `uri_escape`, `scssify`, and `smartify`
|
||||
- Some Liquid features. See [Go Liquid README](https://github.com/osteele/liquid/#status).
|
||||
- CSV and JSON data files.
|
||||
- `{% highlight %}` uses Pygments. There's no way to tell it to use Rouge. Also, I don't know what will happen if Pygments isn't installed.
|
||||
- `<div markdown=1>` doesn't work. I think this is a limitation of the Blackfriday Markdown processor.
|
||||
- This is a new code base. It probably panics or otherwise fails on a lot of legitimate constructs, and misbehaves on others.
|
||||
- This is a very new code base. It probably panics or otherwise fails on a lot of legitimate constructs, and misbehaves on others.
|
||||
- Liquid errors aren't reported very nicely.
|
||||
- `build` with no `-d` option resolves the destination relative to the source directory, not the current directory.
|
||||
|
||||
## Other Differences
|
||||
|
||||
@ -58,8 +64,7 @@ These will probably not change.
|
||||
- Files are cached to `/tmp/gojekyll-${USER}`, not `./.sass-cache`
|
||||
- Server live reload is always on.
|
||||
- The server reloads the `_config.yml` (and the rest of the site) when that file changes.
|
||||
- `build` with no `-d` option resolves the destination relative to the source directory, not the current directory.
|
||||
- Some plugins are built into the executable. Others may be added. There's no an extensible plugin mechanism in the near-to-medium future.
|
||||
- An extensible plugin mechanism. Emulations of commonly-used plugins can be added to the repo.
|
||||
|
||||
## Timings
|
||||
|
||||
|
@ -209,6 +209,7 @@ func sortFilter(array []interface{}, key interface{}, nilFirst interface{}) []in
|
||||
if key == nil {
|
||||
evaluator.Sort(out)
|
||||
} else {
|
||||
// TODO error if key is not a string
|
||||
evaluator.SortByProperty(out, key.(string), nf)
|
||||
}
|
||||
return out
|
||||
|
@ -8,8 +8,15 @@ import (
|
||||
"github.com/osteele/gojekyll/templates"
|
||||
)
|
||||
|
||||
// ToLiquid returns the attributes of the template page object.
|
||||
// See https://jekyllrb.com/docs/variables/#page-variables
|
||||
// ToLiquid is part of the liquid.Drop interface.
|
||||
func (d *StaticFile) ToLiquid() interface{} {
|
||||
return map[string]interface{}{
|
||||
"path": d.Path(), // TODO is this the absolute or relative path?
|
||||
"modified_time": d.fileModTime,
|
||||
"extname": d.OutputExt(),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *file) ToLiquid() interface{} {
|
||||
var (
|
||||
relpath = "/" + filepath.ToSlash(f.relpath)
|
||||
|
@ -29,10 +29,13 @@ func (s *Site) MarshalYAML() (interface{}, error) {
|
||||
|
||||
func (s *Site) initializeDrop() {
|
||||
vars := templates.MergeVariableMaps(s.config.Variables, map[string]interface{}{
|
||||
"data": s.data,
|
||||
"data": s.data,
|
||||
"documents": s.docs,
|
||||
// "collections": s.computeCollections(), // generics.MustConvert(s.config.Collections, reflect.TypeOf([]interface{}{})),
|
||||
// TODO read time from _config, if it's available
|
||||
"time": time.Now(),
|
||||
"time": time.Now(),
|
||||
"pages": s.Pages(),
|
||||
"static_files": s.StaticFiles(),
|
||||
// TODO pages, static_files, html_pages, html_files, documents, tags.TAG
|
||||
})
|
||||
collections := []interface{}{}
|
||||
|
69
site/drop_test.go
Normal file
69
site/drop_test.go
Normal file
@ -0,0 +1,69 @@
|
||||
package site
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/osteele/gojekyll/config"
|
||||
"github.com/osteele/gojekyll/pages"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func readTestSiteDrop(t *testing.T) map[string]interface{} {
|
||||
site, err := FromDirectory("testdata/site1", config.Flags{})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, site.Load())
|
||||
return site.ToLiquid().(map[string]interface{})
|
||||
}
|
||||
|
||||
// TODO test cases for collections, categories, tags, data
|
||||
|
||||
func TestSite_ToLiquid_documents(t *testing.T) {
|
||||
drop := readTestSiteDrop(t)
|
||||
docs, isTime := drop["documents"].([]pages.Document)
|
||||
require.True(t, isTime, fmt.Sprintf("documents has type %T", drop["documents"]))
|
||||
require.Len(t, docs, 4)
|
||||
}
|
||||
func TestSite_ToLiquid_time(t *testing.T) {
|
||||
drop := readTestSiteDrop(t)
|
||||
_, ok := drop["time"].(time.Time)
|
||||
require.True(t, ok)
|
||||
|
||||
// TODO read time from config if present
|
||||
}
|
||||
|
||||
func TestSite_ToLiquid_pages(t *testing.T) {
|
||||
drop := readTestSiteDrop(t)
|
||||
pages, ok := drop["pages"].([]pages.Page)
|
||||
require.True(t, ok, fmt.Sprintf("pages has type %T", drop["pages"]))
|
||||
require.Len(t, pages, 3)
|
||||
}
|
||||
|
||||
func TestSite_ToLiquid_posts(t *testing.T) {
|
||||
drop := readTestSiteDrop(t)
|
||||
posts, ok := drop["posts"].([]pages.Page)
|
||||
require.True(t, ok, fmt.Sprintf("posts has type %T", drop["posts"]))
|
||||
require.Len(t, posts, 1)
|
||||
}
|
||||
|
||||
func TestSite_ToLiquid_related_posts(t *testing.T) {
|
||||
drop := readTestSiteDrop(t)
|
||||
posts, ok := drop["related_posts"].([]pages.Page)
|
||||
require.True(t, ok, fmt.Sprintf("related_posts has type %T", drop["related_posts"]))
|
||||
require.Len(t, posts, 1)
|
||||
}
|
||||
|
||||
func TestSite_ToLiquid_static_files(t *testing.T) {
|
||||
drop := readTestSiteDrop(t)
|
||||
files, ok := drop["static_files"].([]*pages.StaticFile)
|
||||
require.True(t, ok, fmt.Sprintf("static_files has type %T", drop["static_files"]))
|
||||
require.Len(t, files, 1)
|
||||
|
||||
// TODO move this test to pages package
|
||||
f := files[0].ToLiquid().(map[string]interface{})
|
||||
require.Equal(t, "static.html", f["path"])
|
||||
_, isTime := f["modified_time"].(time.Time)
|
||||
require.True(t, isTime)
|
||||
require.Equal(t, ".html", f["extname"])
|
||||
}
|
23
site/site.go
23
site/site.go
@ -19,7 +19,7 @@ import (
|
||||
type Site struct {
|
||||
ConfigFile *string
|
||||
Collections []*collection.Collection
|
||||
Routes map[string]pages.Document // URL path -> Page, only for output pages
|
||||
Routes map[string]pages.Document // URL path -> Document, only for output pages
|
||||
|
||||
config config.Config
|
||||
data map[string]interface{}
|
||||
@ -27,7 +27,7 @@ type Site struct {
|
||||
pipeline *pipelines.Pipeline
|
||||
docs []pages.Document // all documents, whether or not they are output
|
||||
preparedToRender bool
|
||||
drop map[string]interface{} // cached drop value
|
||||
drop map[string]interface{} // cached drop value
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
@ -51,8 +51,25 @@ func (s *Site) OutputPages() []pages.Document {
|
||||
return out
|
||||
}
|
||||
|
||||
// StaticFiles returns a list of static files.
|
||||
func (s *Site) StaticFiles() (out []*pages.StaticFile) {
|
||||
for _, d := range s.docs {
|
||||
if sd, ok := d.(*pages.StaticFile); ok {
|
||||
out = append(out, sd)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Pages returns all the pages, output or not.
|
||||
func (s *Site) Pages() []pages.Document { return s.docs }
|
||||
func (s *Site) Pages() (out []pages.Page) {
|
||||
for _, d := range s.docs {
|
||||
if p, ok := d.(pages.Page); ok {
|
||||
out = append(out, p)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AbsDir is in the collection.Site interface.
|
||||
func (s *Site) AbsDir() string {
|
||||
|
2
site/testdata/site1/_coll1/coll1_page.md
vendored
Normal file
2
site/testdata/site1/_coll1/coll1_page.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
---
|
2
site/testdata/site1/_coll2/coll2_page.md
vendored
Normal file
2
site/testdata/site1/_coll2/coll2_page.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
---
|
5
site/testdata/site1/_config.yml
vendored
Normal file
5
site/testdata/site1/_config.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
collections:
|
||||
coll1:
|
||||
output: true
|
||||
coll2:
|
||||
output: false
|
2
site/testdata/site1/_posts/2017-07-05-post.md
vendored
Normal file
2
site/testdata/site1/_posts/2017-07-05-post.md
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
---
|
1
site/testdata/site1/static.html
vendored
Normal file
1
site/testdata/site1/static.html
vendored
Normal file
@ -0,0 +1 @@
|
||||
static file
|
Loading…
Reference in New Issue
Block a user