mirror of
https://github.com/facundoolano/jorge.git
synced 2024-12-25 21:58:28 +01:00
Add drafts support (#17)
* add src and target ext as template methods * add include drafts config * default to draft on jorge post * skip drafts from site indexes and rendering * fix stat usage for file detection * add site.Build test * test build site with and without drafts * add templ IsPost helper * document drafts in readme * document drafts in tutorial
This commit is contained in:
parent
e1280f07d5
commit
6f27afacf7
8 changed files with 240 additions and 40 deletions
|
@ -66,6 +66,7 @@ date: 2024-02-21 13:39:59
|
||||||
layout: post
|
layout: post
|
||||||
lang: en
|
lang: en
|
||||||
tags: []
|
tags: []
|
||||||
|
draft: true
|
||||||
---
|
---
|
||||||
#+OPTIONS: toc:nil num:nil
|
#+OPTIONS: toc:nil num:nil
|
||||||
#+LANGUAGE: en
|
#+LANGUAGE: en
|
||||||
|
@ -83,6 +84,12 @@ this is my *first* post.
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Posts created with `jorge post` are drafts by default. Remove the `draft: true` to mark it ready for publication:
|
||||||
|
|
||||||
|
``` bash
|
||||||
|
$ sed -i '' '/^draft: true$/d' src/blog/my-first-post.org
|
||||||
|
```
|
||||||
|
|
||||||
Finally, you can render a minified version of your site with `jorge build`:
|
Finally, you can render a minified version of your site with `jorge build`:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -19,6 +19,7 @@ date: %s
|
||||||
layout: post
|
layout: post
|
||||||
lang: %s
|
lang: %s
|
||||||
tags: []
|
tags: []
|
||||||
|
draft: true
|
||||||
---
|
---
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ func (cmd *Post) Run(ctx *kong.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if file already exists, prompt user for a different one
|
// if file already exists, prompt user for a different one
|
||||||
if _, err := os.Stat(path); os.IsExist(err) {
|
if _, err := os.Stat(path); err == nil {
|
||||||
fmt.Printf("%s already exists\n", path)
|
fmt.Printf("%s already exists\n", path)
|
||||||
filename = Prompt("filename")
|
filename = Prompt("filename")
|
||||||
path = filepath.Join(config.SrcDir, filename)
|
path = filepath.Join(config.SrcDir, filename)
|
||||||
|
|
|
@ -31,9 +31,10 @@ type Config struct {
|
||||||
Lang string
|
Lang string
|
||||||
HighlightTheme string
|
HighlightTheme string
|
||||||
|
|
||||||
Minify bool
|
Minify bool
|
||||||
LiveReload bool
|
LiveReload bool
|
||||||
LinkStatic bool
|
LinkStatic bool
|
||||||
|
IncludeDrafts bool
|
||||||
|
|
||||||
ServerHost string
|
ServerHost string
|
||||||
ServerPort int
|
ServerPort int
|
||||||
|
@ -61,6 +62,7 @@ func Load(rootDir string) (*Config, error) {
|
||||||
Minify: true,
|
Minify: true,
|
||||||
LiveReload: false,
|
LiveReload: false,
|
||||||
LinkStatic: false,
|
LinkStatic: false,
|
||||||
|
IncludeDrafts: false,
|
||||||
pageDefaults: map[string]interface{}{},
|
pageDefaults: map[string]interface{}{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +115,7 @@ func LoadDev(rootDir string, host string, port int, reload bool) (*Config, error
|
||||||
config.LiveReload = reload
|
config.LiveReload = reload
|
||||||
config.Minify = false
|
config.Minify = false
|
||||||
config.LinkStatic = true
|
config.LinkStatic = true
|
||||||
|
config.IncludeDrafts = true
|
||||||
config.SiteUrl = fmt.Sprintf("http://%s:%d", config.ServerHost, config.ServerPort)
|
config.SiteUrl = fmt.Sprintf("http://%s:%d", config.ServerHost, config.ServerPort)
|
||||||
|
|
||||||
return config, nil
|
return config, nil
|
||||||
|
|
|
@ -13,6 +13,7 @@ So far you've seen how to [[file:jorge-init][start a project]], [[file:jorge-ser
|
||||||
|
|
||||||
#+begin_src console
|
#+begin_src console
|
||||||
$ jorge build
|
$ jorge build
|
||||||
|
skipping draft target/blog/my-own-blog-post.org
|
||||||
wrote target/2024-02-23-another-kind-of-post.html
|
wrote target/2024-02-23-another-kind-of-post.html
|
||||||
wrote target/blog/my-own-blog-post.html
|
wrote target/blog/my-own-blog-post.html
|
||||||
wrote target/blog/goodbye-markdown.html
|
wrote target/blog/goodbye-markdown.html
|
||||||
|
@ -26,6 +27,7 @@ wrote target/blog/index.html
|
||||||
|
|
||||||
Just like ~jorge serve~ did before, ~jorge build~ scans your ~src/~ directory and renders its files into ~target/~, but with a few differences:
|
Just like ~jorge serve~ did before, ~jorge build~ scans your ~src/~ directory and renders its files into ~target/~, but with a few differences:
|
||||||
|
|
||||||
|
- Templates flagged as drafts in their front matter are excluded.
|
||||||
- Static files are copied over to ~target/~ instead of just linked.
|
- Static files are copied over to ~target/~ instead of just linked.
|
||||||
- The ~url~ from your ~config.yml~ is used as the root when rendering absolute urls (instead of the ~http://localhost:4001~ used when serving locally).
|
- The ~url~ from your ~config.yml~ is used as the root when rendering absolute urls (instead of the ~http://localhost:4001~ used when serving locally).
|
||||||
- The HTML, XML, CSS and JavaScript files are minified.
|
- The HTML, XML, CSS and JavaScript files are minified.
|
||||||
|
|
|
@ -44,6 +44,7 @@ date: 2024-02-23 11:45:30
|
||||||
layout: post
|
layout: post
|
||||||
lang: en
|
lang: en
|
||||||
tags: []
|
tags: []
|
||||||
|
draft: true
|
||||||
---
|
---
|
||||||
#+OPTIONS: toc:nil num:nil
|
#+OPTIONS: toc:nil num:nil
|
||||||
#+LANGUAGE: en
|
#+LANGUAGE: en
|
||||||
|
@ -51,13 +52,14 @@ tags: []
|
||||||
|
|
||||||
Let's look at what the command did for us:
|
Let's look at what the command did for us:
|
||||||
{% raw %}
|
{% raw %}
|
||||||
| ~src/blog/my-own-blog-post.org~ | The filename, a URL-friendly version of the post title (a "slug"), such that the post will be served at ~/blog/my-own-blog-post~ |
|
| ~src/blog/my-own-blog-post.org~ | The filename, a URL-friendly version of the post title (a "slug"), such that the post will be served at ~/blog/my-own-blog-post~ |
|
||||||
| ~title: My own blog post~ | The title we passed to jorge. This will be available to templates as ~{{page.title}}~ and will be used by the default post layout to render the header of the page. |
|
| ~title: My own blog post~ | The title we passed to jorge. This will be available to templates as ~{{page.title}}~ and will be used by the default post layout to render the header of the page. |
|
||||||
| ~date: 2024-02-23 11:45:30~ | The date this post was created. It will affect the position it shows up in in ~{{site.posts}}~ |
|
| ~date: 2024-02-23 11:45:30~ | The date this post was created. It will affect the position it shows up in in ~{{site.posts}}~ |
|
||||||
| ~layout: post~ | The rendered HTML of this template will be embedded as the ~{{contents}}~ of the layout defined in ~layouts/post.html~. |
|
| ~layout: post~ | The rendered HTML of this template will be embedded as the ~{{contents}}~ of the layout defined in ~layouts/post.html~. |
|
||||||
| ~lang: en~ | The language code for the post. This is used by some of the default templates, for instance, to determine how to hyphenate the post content. |
|
| ~lang: en~ | The language code for the post. This is used by some of the default templates, for instance, to determine how to hyphenate the post content. |
|
||||||
| ~tags: []~ | The post tags, initially empty. The keywords in this list will determine which keys of the ~{{site.tags}}~ map this post will be associated with.
|
| ~tags: []~ | The post tags, initially empty. The keywords in this list will determine which keys of the ~{{site.tags}}~ map this post will be associated with. |
|
||||||
| ~#+OPTIONS: toc:nil num:nil~, ~#+LANGUAGE: en~ | Some default org mode options, to skip the table of contents and define the post language. |
|
| ~draft: true~ | By default, posts created with ~jorge post~ are marked as drafts. Drafts are included in the site served locally but excluded from the production build. Remove this flag once your post is ready.
|
||||||
|
| ~#+OPTIONS: toc:nil num:nil~, ~#+LANGUAGE: en~ | Some default org mode options, to skip the table of contents and define the post language. |
|
||||||
{% endraw %}
|
{% endraw %}
|
||||||
|
|
||||||
With ~jorge serve~ running, you can start filling in some content on this new post and see it show up in the browser at http://localhost:4001/blog/my-own-blog-post.
|
With ~jorge serve~ running, you can start filling in some content on this new post and see it show up in the browser at http://localhost:4001/blog/my-own-blog-post.
|
||||||
|
|
|
@ -99,8 +99,13 @@ func Parse(engine *Engine, path string) (*Template, error) {
|
||||||
return &templ, nil
|
return &templ, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the extension of this template's source file.
|
||||||
|
func (templ Template) SrcExt() string {
|
||||||
|
return filepath.Ext(templ.SrcPath)
|
||||||
|
}
|
||||||
|
|
||||||
// Return the extension for the output format of this template
|
// Return the extension for the output format of this template
|
||||||
func (templ Template) Ext() string {
|
func (templ Template) TargetExt() string {
|
||||||
ext := filepath.Ext(templ.SrcPath)
|
ext := filepath.Ext(templ.SrcPath)
|
||||||
if ext == ".org" || ext == ".md" {
|
if ext == ".org" || ext == ".md" {
|
||||||
return ".html"
|
return ".html"
|
||||||
|
@ -108,6 +113,18 @@ func (templ Template) Ext() string {
|
||||||
return ext
|
return ext
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (templ Template) IsDraft() bool {
|
||||||
|
if draft, ok := templ.Metadata["draft"]; ok {
|
||||||
|
return draft.(bool)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (templ Template) IsPost() bool {
|
||||||
|
_, ok := templ.Metadata["date"]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
// Renders the liquid template with the given context as bindings.
|
// Renders the liquid template with the given context as bindings.
|
||||||
// If the template source is org or md, convert them to html after the
|
// If the template source is org or md, convert them to html after the
|
||||||
// liquid rendering.
|
// liquid rendering.
|
||||||
|
@ -118,9 +135,7 @@ func (templ Template) Render(context map[string]interface{}, hlTheme string) ([]
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ext := filepath.Ext(templ.SrcPath)
|
if templ.SrcExt() == ".org" {
|
||||||
|
|
||||||
if ext == ".org" {
|
|
||||||
// org-mode rendering
|
// org-mode rendering
|
||||||
doc := org.New().Parse(bytes.NewReader(content), templ.SrcPath)
|
doc := org.New().Parse(bytes.NewReader(content), templ.SrcPath)
|
||||||
htmlWriter := org.NewHTMLWriter()
|
htmlWriter := org.NewHTMLWriter()
|
||||||
|
@ -134,7 +149,7 @@ func (templ Template) Render(context map[string]interface{}, hlTheme string) ([]
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
content = []byte(contentStr)
|
content = []byte(contentStr)
|
||||||
} else if ext == ".md" {
|
} else if templ.SrcExt() == ".md" {
|
||||||
// markdown rendering
|
// markdown rendering
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
md := goldmark.New(goldmark.WithExtensions(
|
md := goldmark.New(goldmark.WithExtensions(
|
||||||
|
|
58
site/site.go
58
site/site.go
|
@ -120,7 +120,7 @@ func (site *Site) loadDataFiles() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (site *Site) loadTemplates() error {
|
func (site *Site) loadTemplates() error {
|
||||||
if _, err := os.Stat(site.Config.SrcDir); os.IsNotExist(err) {
|
if _, err := os.Stat(site.Config.SrcDir); err != nil {
|
||||||
return fmt.Errorf("missing src directory")
|
return fmt.Errorf("missing src directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,37 +135,42 @@ func (site *Site) loadTemplates() error {
|
||||||
// set site related (?) metadata. Not sure if this should go elsewhere
|
// set site related (?) metadata. Not sure if this should go elsewhere
|
||||||
relPath, _ := filepath.Rel(site.Config.SrcDir, path)
|
relPath, _ := filepath.Rel(site.Config.SrcDir, path)
|
||||||
srcPath, _ := filepath.Rel(site.Config.RootDir, path)
|
srcPath, _ := filepath.Rel(site.Config.RootDir, path)
|
||||||
relPath = strings.TrimSuffix(relPath, filepath.Ext(relPath)) + templ.Ext()
|
relPath = strings.TrimSuffix(relPath, filepath.Ext(relPath)) + templ.TargetExt()
|
||||||
templ.Metadata["src_path"] = srcPath
|
templ.Metadata["src_path"] = srcPath
|
||||||
templ.Metadata["path"] = relPath
|
templ.Metadata["path"] = relPath
|
||||||
templ.Metadata["url"] = "/" + strings.TrimSuffix(strings.TrimSuffix(relPath, "index.html"), ".html")
|
templ.Metadata["url"] = "/" + strings.TrimSuffix(strings.TrimSuffix(relPath, "index.html"), ".html")
|
||||||
templ.Metadata["dir"] = "/" + filepath.Dir(relPath)
|
templ.Metadata["dir"] = "/" + filepath.Dir(relPath)
|
||||||
|
|
||||||
// posts are templates that can be chronologically sorted --that have a date.
|
// if drafts are disabled, exclude from posts, page and tags indexes, but not from site.templates
|
||||||
// the rest are pages.
|
// we want to explicitly exclude the template from the target, rather than treating it as a non template file
|
||||||
if _, ok := templ.Metadata["date"]; ok {
|
if !templ.IsDraft() || site.Config.IncludeDrafts {
|
||||||
|
// posts are templates that can be chronologically sorted --that have a date.
|
||||||
|
// the rest are pages.
|
||||||
|
if templ.IsPost() {
|
||||||
|
|
||||||
// NOTE: getting the excerpt if not set at the front matter requires rendering the template
|
// NOTE: getting the excerpt if not set at the front matter requires rendering the template
|
||||||
// which could be too onerous for this stage. Consider postponing setting this and/or caching the
|
// which could be too onerous for this stage. Consider postponing setting this and/or caching the
|
||||||
// template render result
|
// template render result
|
||||||
templ.Metadata["excerpt"] = getExcerpt(templ)
|
templ.Metadata["excerpt"] = getExcerpt(templ)
|
||||||
site.posts = append(site.posts, templ.Metadata)
|
site.posts = append(site.posts, templ.Metadata)
|
||||||
|
|
||||||
// also add to tags index
|
// also add to tags index
|
||||||
if tags, ok := templ.Metadata["tags"]; ok {
|
if tags, ok := templ.Metadata["tags"]; ok {
|
||||||
for _, tag := range tags.([]interface{}) {
|
for _, tag := range tags.([]interface{}) {
|
||||||
tag := tag.(string)
|
tag := tag.(string)
|
||||||
site.tags[tag] = append(site.tags[tag], templ.Metadata)
|
site.tags[tag] = append(site.tags[tag], templ.Metadata)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// the index pages should be skipped from the page directory
|
||||||
|
filename := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
|
||||||
|
if filename != "index" {
|
||||||
|
site.pages = append(site.pages, templ.Metadata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
// the index pages should be skipped from the page directory
|
|
||||||
filename := strings.TrimSuffix(entry.Name(), filepath.Ext(entry.Name()))
|
|
||||||
if filename != "index" {
|
|
||||||
site.pages = append(site.pages, templ.Metadata)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
site.templates[path] = templ
|
site.templates[path] = templ
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -256,12 +261,17 @@ func (site *Site) buildFile(path string) error {
|
||||||
defer srcFile.Close()
|
defer srcFile.Close()
|
||||||
contentReader = srcFile
|
contentReader = srcFile
|
||||||
} else {
|
} else {
|
||||||
|
if templ.IsDraft() && !site.Config.IncludeDrafts {
|
||||||
|
fmt.Println("skipping draft", targetPath)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
content, err := site.render(templ)
|
content, err := site.render(templ)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
targetPath = strings.TrimSuffix(targetPath, filepath.Ext(targetPath)) + templ.Ext()
|
targetPath = strings.TrimSuffix(targetPath, filepath.Ext(targetPath)) + templ.TargetExt()
|
||||||
contentReader = bytes.NewReader(content)
|
contentReader = bytes.NewReader(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +367,7 @@ func getExcerpt(templ *markup.Template) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we don't expect this to render to html don't bother parsing it
|
// if we don't expect this to render to html don't bother parsing it
|
||||||
if templ.Ext() != ".html" {
|
if templ.TargetExt() != ".html" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -356,6 +356,166 @@ func TestRenderDataFile(t *testing.T) {
|
||||||
</ul>`)
|
</ul>`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBuildTarget(t *testing.T) {
|
||||||
|
config := newProject()
|
||||||
|
defer os.RemoveAll(config.RootDir)
|
||||||
|
|
||||||
|
// add base layout
|
||||||
|
content := `---
|
||||||
|
---
|
||||||
|
<html>
|
||||||
|
<head><title>{{page.title}}</title></head>
|
||||||
|
<body>
|
||||||
|
{{content}}
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
newFile(config.LayoutsDir, "base.html", content)
|
||||||
|
|
||||||
|
// add org post
|
||||||
|
content = `---
|
||||||
|
layout: base
|
||||||
|
title: p1 - hello world!
|
||||||
|
date: 2024-01-01
|
||||||
|
---
|
||||||
|
* Hello world!`
|
||||||
|
newFile(config.SrcDir, "p1.org", content)
|
||||||
|
|
||||||
|
// add markdown post
|
||||||
|
content = `---
|
||||||
|
layout: base
|
||||||
|
title: p2 - goodbye world!
|
||||||
|
date: 2024-01-02
|
||||||
|
---
|
||||||
|
# Goodbye world!`
|
||||||
|
newFile(config.SrcDir, "p2.md", content)
|
||||||
|
|
||||||
|
// add index page
|
||||||
|
content = `---
|
||||||
|
layout: base
|
||||||
|
---
|
||||||
|
<ul>{% for post in site.posts %}
|
||||||
|
<li>{{post.title}}</li>{%endfor%}
|
||||||
|
</ul>`
|
||||||
|
newFile(config.SrcDir, "index.html", content)
|
||||||
|
|
||||||
|
// build site
|
||||||
|
site, err := Load(*config)
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
err = site.Build()
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
|
||||||
|
// test target files generated
|
||||||
|
_, err = os.Stat(filepath.Join(config.TargetDir, "p1.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
_, err = os.Stat(filepath.Join(config.TargetDir, "p2.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
|
||||||
|
// test index includes p1 and p2
|
||||||
|
output, err := os.ReadFile(filepath.Join(config.TargetDir, "index.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
assertEqual(t, string(output), `<html><head><title></title></head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>p2 - goodbye world!</li>
|
||||||
|
<li>p1 - hello world!</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</body></html>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBuildWithDrafts(t *testing.T) {
|
||||||
|
config := newProject()
|
||||||
|
defer os.RemoveAll(config.RootDir)
|
||||||
|
|
||||||
|
// add base layout
|
||||||
|
content := `---
|
||||||
|
---
|
||||||
|
<html>
|
||||||
|
<head><title>{{page.title}}</title></head>
|
||||||
|
<body>
|
||||||
|
{{content}}
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
newFile(config.LayoutsDir, "base.html", content)
|
||||||
|
|
||||||
|
// add org post
|
||||||
|
content = `---
|
||||||
|
layout: base
|
||||||
|
title: p1 - hello world!
|
||||||
|
date: 2024-01-01
|
||||||
|
---
|
||||||
|
* Hello world!`
|
||||||
|
newFile(config.SrcDir, "p1.org", content)
|
||||||
|
|
||||||
|
// add markdown post, make it draft
|
||||||
|
content = `---
|
||||||
|
layout: base
|
||||||
|
title: p2 - goodbye world!
|
||||||
|
date: 2024-01-02
|
||||||
|
draft: true
|
||||||
|
---
|
||||||
|
# Goodbye world!`
|
||||||
|
newFile(config.SrcDir, "p2.md", content)
|
||||||
|
|
||||||
|
// add index page
|
||||||
|
content = `---
|
||||||
|
layout: base
|
||||||
|
---
|
||||||
|
<ul>{% for post in site.posts %}
|
||||||
|
<li>{{post.title}}</li>{%endfor%}
|
||||||
|
</ul>`
|
||||||
|
newFile(config.SrcDir, "index.html", content)
|
||||||
|
|
||||||
|
// build site with drafts
|
||||||
|
config.IncludeDrafts = true
|
||||||
|
site, err := Load(*config)
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
err = site.Build()
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
|
||||||
|
// test target files generated
|
||||||
|
_, err = os.Stat(filepath.Join(config.TargetDir, "p1.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
_, err = os.Stat(filepath.Join(config.TargetDir, "p2.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
|
||||||
|
// test index includes p1 and p2
|
||||||
|
output, err := os.ReadFile(filepath.Join(config.TargetDir, "index.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
assertEqual(t, string(output), `<html><head><title></title></head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>p2 - goodbye world!</li>
|
||||||
|
<li>p1 - hello world!</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</body></html>`)
|
||||||
|
|
||||||
|
// build site WITHOUT drafts
|
||||||
|
config.IncludeDrafts = false
|
||||||
|
site, err = Load(*config)
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
err = site.Build()
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
|
||||||
|
// test only non drafts generated
|
||||||
|
_, err = os.Stat(filepath.Join(config.TargetDir, "p1.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
_, err = os.Stat(filepath.Join(config.TargetDir, "p2.html"))
|
||||||
|
assert(t, os.IsNotExist(err))
|
||||||
|
|
||||||
|
// test index includes p1 but NOT p2
|
||||||
|
output, err = os.ReadFile(filepath.Join(config.TargetDir, "index.html"))
|
||||||
|
assertEqual(t, err, nil)
|
||||||
|
assertEqual(t, string(output), `<html><head><title></title></head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>p1 - hello world!</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</body></html>`)
|
||||||
|
}
|
||||||
|
|
||||||
// ------ HELPERS --------
|
// ------ HELPERS --------
|
||||||
|
|
||||||
func newProject() *config.Config {
|
func newProject() *config.Config {
|
||||||
|
|
Loading…
Reference in a new issue