1
0
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:
Oliver Steele 2017-07-05 12:44:38 -04:00
parent 55ac57dcbe
commit 266c14c798
11 changed files with 129 additions and 15 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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
View 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"])
}

View File

@ -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 {

View File

@ -0,0 +1,2 @@
---
---

View File

@ -0,0 +1,2 @@
---
---

5
site/testdata/site1/_config.yml vendored Normal file
View File

@ -0,0 +1,5 @@
collections:
coll1:
output: true
coll2:
output: false

View File

@ -0,0 +1,2 @@
---
---

1
site/testdata/site1/static.html vendored Normal file
View File

@ -0,0 +1 @@
static file