This is a part of #257
Attributes from a page are now under the `page` object
- `path` -> `page.permalink` to make it clear this is the equivelant of `permalink` in the frontmatter
- `source` -> `page.file.permalink`
- Under `file` to make room for `page.file.parent`
- `permalink for consitency with `page.permalink`
- `date` -> `page.published_date`
- Consistency with the new `published_date` in the front matter
- Both are renamed to make it clear the role of the date (versus a future `modified_date` that might exist)
- `draft` -> `page.is_draft`
- `previous` -> `page.previous`
- `next` -> `page.next`
- Custom fields have moved from `<field>` to `page.data.<field>`.
BREAKING CHANGE: Liquid `{{ variables }}` have been renamed.
`cobalt migrate` will fix some. `cobalt build` will most likely fail on
variables missed by `cobalt migrate`.
The original jekyll-inspired format is not well defined. The only way
to parse a variable is to match it against all know variables because
there is no end-token. This can also lead to ambiguity if one variable
name is a subset of another.
This switches the format to use liquid. No filters, tags, or blocks are
made available at this time but that can be re-evaluated in the future.
Part of the fix for #198
BREAKING CHANGE: permalink substitutions like `:path:output_ext` need to
be changed to `{{path}}{{output_ext}}`.
`cobalt migrate` will take care of this. It might include too much text
in the variable but this will be caught by `cobalt build` failing.
The primary motivation was to make it possible to create a liquid parser
that has no tags, blocks, or filters which we'll want when switching
permalinks to using liquid.
In micro-benchmarks, rendering speed has improved.
BREAKING CHANGES:
- liquid will now error on non-existent variables
- `for_loop` (duplicate of `forloop` variable) has been removed
Two main aspects
- Collections are now slugified
- Custom variables are now accessed as `:data.<VAR>` to avoid collisions
with future built-in variables
The challenge with writing the conversion is we don't know where a
`:data.<VAR>` field ends. Originally, it was written to ignore
`:data.<VAR>` variables. Instead it consumes everything until the next
`:variable` as part of `:data.<VAR>`. This isn't noticed in this change
but will become obvious when changing the format.
Part of the work for #198
BREAKING CHANGE:
- permalinks with `:collection` might move due to slugification
- Custom variables need to be switched to `:data.<VAR>`. `cobalt
migrate` is unsufficient for this, instead it will remove the troubled
permalink
To be clear, this was tested on 10 sites and broke none of them.
The frontmatter is now a strictly defined format
- Custom data goes in the `data` field to avoid conflicts between user
data and future cobalt data.
- `date` has been renamed to `published_date` to make it clear what role
it plays and room for possibly adding a `modified_date`
- Error rather than ignore poorly formed fields
- `path` was a bit ambiguous. The hope is that `permalink` will be more
clear.
To help reduce noise when diffing an old site against a new site,
frontmatter fields that are default values are not written out to the
file.
Fixes#257
BREAKING CHANGES
frontmatter
- `date` renamed to `published_date` and will error on bad formatting
- `extends` renamted to `layout`
- `draft` renamed to `is_draft`
- `ext` now exposed as `format`
- `path` renamed to `permalink` and a leading `/` is needed unless a
path alias is being used.
`cobalt migrate` has support to make these changes for you.
The `.cobalt.yml` format should be more forward looking now, not
breaking users in the face of new featurs being added.
Features this uncovers
- Default the frontmatter for pages and posts
Fixes#199
BREAKING CHANGE: `.cobalt.yml` format change. Run `cobalt migrate` to
convert your site to the new format. Please backup first in case there
is an issue.
Originally, I hid the conversions as a hack. This is making the
conversions to non-legacy harder, so removing it.
I temporarily disabled tests until #334
A previous commit make the `dest` config flag relative to the config
file. This also impacted `--destination`. This would be unexpected, so
we now track separately the config's dest and the overridden dest so we
can properly track what they should be relative to.
This is a step towards #284.
When moving the post-processing into the builder, I went ahead and
implemented the link semantics talked about in #216. This causes a
minor change to output. RSS and jsonfeed's links to the main website
will not have a trailing slash which no one should notice.
This is now hardcoded to `_layouts`, like data and scss import dir are
hard coded. I cannot forsee why someone would have a need to customize
these.
BREAKING CHANGE: A config file with `layouts` will either error or be
ignored.
This is a stepping stone to #284.
BREAKING CHANGE: like git, cobalt will now search the parent dir for a
config file. If non is found, the default will be used. Previously, if
the config wasn't found in the CWD, cobalt used a default config.
This is an attempt to try to simplify things until someone has a use
case for it.
What are the problems with custom folders?
- Less confusing to users. When giving the user a choicem, we should be
able to describe why they might want to make that choice.
- Less to test
- No semantic problems to worry about.
- What should be the behavior for a non-`_`-prefixed folder
- What should be the behavior for deeply nesting particularly with the
above question mixed in at random points.
The configuration was dumped to `.rustfmt.toml`, so hopefully people can
also use newer versions of rustfmt.
The config was not updated to also include the latest style RFCs just
out of laziness.
Add capability to read yaml, json and toml files from a configurable
folder within source (defaults to `_data`) and expose them to the
templates under the variable `site.data` for processing.
Fixes#256
- Provide more error context (like which file failed to parse).
- Restored logging of command failures (removed in split)
- Restored logging of successful commands (removed in split)
In theory, this makes the checking more strict. In practice, serde
isn't erroring out for invalid enum values as I'd expect.
BREAKING CHANGE: `post_order` now takes `Asc` and `Desc` instead of
`asc` and `desc`.
- This simplifies the config loading code.
- This is yet another stepping stone towards a revamped config.
- This allows the removal of a direct dependency.
BREAKING CHANGE:
Unknown fields are mostly not allowed now (for some reason, incorrect
syntax-highlight fields are). There isn't really a use case for unknown
fields but room for a lot of confusion (typos in fields leading to odd
behavior).
`syntax-highlight` has been renamed to `syntax_highlight`. This is more
consistent with the rest of the file.
This is mostly a refactoring but with the impact that `page.path` now
returns a non-exploded path.
BREAKING CHANGES: `page.path` now returns the non-exploded path.
The new traces are not safe against re-running with an overlapping source
and dest dir. Ideally, we'd generate to tempdir's anyways but then the paths are
different, breaking traces. So, in the end, we'd just mirroring the same
test between `trace` and `trace_alias`.
The `ignore` field in `.cobalt.yml` is changing from a list of glob patterns to
a list `gitignore` patterns, allowing whitelisting and more advanced
whitelisting/blacklisting with well defined semantics.
Previuously, Cobalt processed all files except `.dot` and `_hidden`,
*dest* files/directories.
Considerations when designing this:
- User workflow: users need `.dot` asset files, like `.htaccess`, copied over.
- Implementation: Finding files for pages and posts is coupled together
which will be a problem as we refactor them into more general
collections or sections.
- Performance: Eventually we'll want to implement incremental rebuild
(see issue #81) and to do so we'll need to know what collection a file
notification is relevant to.
`gitignore` patterns were selected for the first item to ensure we had
well defined semantics for how blacklist and whitelist features would
interact, directory vs file patterns, etc.
The last two are the motivation for factoring out file detection.
A couple downsides, for now
- `cobalt watch` will now rebuild when hidden files are touched. This is
unfortunate but seems like an acceptable short term sacrifice until we
have a better to expose what files cobal reads.
- Handling of overlapping source/dest is a bit ugly. In the future, we
should just make these cases error
- Handling of hidden post folders is ugly. In the future, we should
generalize the concept of pages and posts into collections/sections at
which point we'll walk each collection type independently. This will
make the non-hidden posts folders the ugly case. We should consider
requiring them to be hidden.
- There is a known bug where we enable all hidden folders that match the
posts folders name rather than only some.
Fixes#221 by allowing the user to whitelist `.dot` and `_hidden` files.
See the added unit tests for examples.
BREAKING CHANGE: The format of `.cobalt.yml`'s `ignore` field has changed
from a list of glob patterns to gitignore patterns.
Upgrade notes:
- notify: Debouncing was added but have not yet switched to it because of
the extra work to extract the relevant path
Dependencies that were held back:
- assert_cli: See killercup/assert_cli#30 and killercup/assert_cli#31
- rss: Seems they turned off XML escaping. Didn't have time to research
this.
* Don't render documents without `extends` twice
`liquid_escaped` test case was red before the fix:
`tests/fixtures/liquid_escaped/not-extends.liquid` renders invalid
liquid markup, so cobalt used to panic when it rendered this document
twice.
* Move lines in `Document::as_html` to improve readability
* Reorganize the code for rendering documents
This doesn't change flow, that's just a prerequisite for adding
excerpts.
* Add excerpts test fixture based on a vanilla `cobalt new` project
* Add several posts with different kinds of excerpts to `excerpts` fixture/target
* Add .liquid posts to fixture/target
* Split front matter using an improved regex
The default excerpt separator is \n\n. If the linefeed after "---" is a
part of content, a document starting from one blank line will have an
empty excerpt.
\r is there because they use both \r and \n on Windows.
* Add jekyll-like excerpts to posts
It doesn't make sense to add excerpts to other documents as they are not
injected to rendering context like "posts" is. So we won't do it to save
some CPU time.
* Cache layouts to avoid repeated fs calls and memory allocations
Fixes#120 (we don't need to use mutex here because crossbeam has been
removed in #146).
* Add draft support (fixes#121)
* Add documentation for drafts
* Add support for draft front matter attributes
* Run rustfmt
* Draft related debug messages
This is something I've been meaning to do for a long time now.
I would like to add consistency in how we deal with files and folders
that have a leading dot or underscore. This commit makes it so that both
kinds are simply ignored by default when looking for documents to
generate or assets to copy. I like to see those filenames as
indication that the folders contain "meta" information.
My idea of a good site generator is that your source file structure is
not fundamentally different from the resulting file structure. You
basically end up with the same structure but "enhanced" by the site
generator (e.g. by turning .md and .liquid files into .html files).
It is very useful to have an easy indicator like an underscore to show
that this file will be used in the generation process but will not be
there in the resulting site. You can now simply have a file called _data.json
next to your template or blog file.
The default post path has been changed to "posts".
For compatibility it is still possible to set your default post path to
"_posts", however, you now have to do it explicitly in your .cobalt.yml.
This is good, as having _posts/blog-post.md generate to
_posts/blog-post.html was just laughable.
I will make PRs for that in all affected user pages.
_layouts obviously stays the same. I changed the layout handling a
bit, though. Layouts are now read from disk every time they are
required. This needs a bit of optmization in the future but allows for
better and more flexible layout specification.
* Move parse_document code into Document
* Prevent race condition on deep post paths
fs::create_dir_all is racy and will not do well when run in parallel for
a number of sufficiently deep directories with same parents.
I fixed it by writing my own version that is thread-safe.
I also reorganized some of the document code, it seems more clean to me
now at least.
* Implement custom document paths
Some things still need to be finished, like proper slugification. But
that should be for follow up bugs.
Note that this also removes the automatically injected variable `name`
which used to be the file name without the extension. I think it never
really made sense to have it.
This commit removes the dependency on markdown.rs for now, as
pulldown_cmark offers more compatibility and stability. However,
depending on how the two libraries turn out, we might want to consider
switching back again. None of the alternatives for Rust markdown parsing
is in a great state, currently.
This is a pretty big commit that implements generating RSS feeds from
the posts folder. This can be achieved by adding some fields to the
cobalt config file. See the added documentation.
I also found it necessary to refactor how the internal API receives
config arguments. We now have a cobalt::Config struct that holds the
relevant fields. Moving config parsing file parsing to its own module
(config.rs) also gives us much better modularity and testability, I
hope.
This commit also fixes#44 by creating a target folder before trying to
build into it.
Posts are now sorted by date by default. Dates have to have the format
`%d %B %Y %H:%M:%S %z`, e.g. `29 May 2016 23:00:00 +0100` to be
successfully parsed. If no dates are provided or the parsing fails, it
falls back to 1970.
This is a backwards-incompatible change, as `@extends` is an invalid
identifier in yaml (specifically the @ part). I changed it to `extends`,
which doesn't seem bad.
This comes together with the changes for supporting datetime properties
and sorting posts by creation date. More implementation details will
follow in later commits.
The test doesn't run right now. It wouldn't work anyway, since we have
no way of testing stuff from the main function at this time.
I've kept the fixtures since they're used in tests in main.rs
- Uses liquid 0.2, which does better error handling
- Introduces a cobalt::Error that converts from the different error
types and enables much conciser and safer code
- Transitions all panics and unwraps to use the new error system