Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: "generate" rule #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions active/0000-generate-rule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
start_date: 2016-11-15
rfc_issue: (leave this empty)
---

# Generator rule

Introduce a `generate` rule that allows generating in-memory items in a declarative way.

## Motivation

The current preprocessor is a black box, and its effects cannot be analysed. In particular, the preprocessor makes it impossible to do the following:

* Directly querying data sources from item collections is not possible, because the data from the data sources can have been mutated.

* As a result of this, sites must be loaded fully into memory, which is problematic for larger sites.

* The preprocessor must be run in full before every compilation. There are no optimisations that can be made here. This can be the cause of a significant slowdown.

The preprocessor is commonly used for generating in-memory items, such as year and tag archive pages. A declarative method for describing the generation of such items could be a full replacement for the preprocessor, without its problems.

## Detailed design

Introduce a `generate` rule that looks as follows:

```ruby
generate(@items.find_all('/blog/articles/*').map { |i| i[:year] }) do |year|
new_item("Year #{year}", {}, "/archive/year-#{year}")
end

generate(@items.flat_map { |i| i[:tags] }) do |tag|
new_item("tag #{tag}", {}, "/archive/tag-#{tag}")
end

generate do
new_item('Some random item', {}, '/random')
end
```

The `generate` rule has a selector, which specifies which items to consider as the input. It also has a block, to which each element of the resulting array is yielded.

An alternate `generator` form with no selector exist, and will be called with no block argument.

## Drawbacks

TODO

## Alternatives

TODO

## Unresolved questions

TODO