ruhoh / ruhoh.rb

http://ruhoh.com
616 stars 69 forks source link

context awareness #265

Open waynedpj opened 10 years ago

waynedpj commented 10 years ago

this is a potential feature request for a future Ruhoh release (3.0?).

in my workflows i am finding that it would be useful to be able to define data throughout the directory structure of a site's source (as discussed here) in YAML/JSON files. my addition is the ability to have that data combined with any parent collection data, as well as the theme and root data in a way that would allow properties to be accessed in a context-aware way. this feature request is in a similar vein as https://github.com/ruhoh/ruhoh.rb/issues/253 . from that issue it is seen that currently data is merged altogether and thus values are overwritten.

i am proposing a context aware way of accessing data (and perhaps other things) that goes from the most specific context to the least specific context. thus, a data property license would be resolved by checking the following potential data sources in order:

  1. front matter of the current page/template
  2. front matter of the current layout(s), with the most inner/nested layout overriding others (currently front matter is not possible in layouts in Ruhoh .. another request)
  3. any data defined in data files in the current page's directory
  4. any data defined in the current collection (i.e. inside data files inside this collection's directory)
  5. any data defined in parent collections of the current collection (i.e. data files inside parent directories) onward up until the site root
  6. any data defined in data files in the current theme's folder/subfolders
  7. data defined in the root folder
  8. front matter of the current partial (currently front matter is not possible in partials in Ruhoh .. another request). this would allow partials to define defaults in their front matter that could be overridden by any other context level

basically, as pages are processed and directories/collections are traversed, the contexts are pushed/popped on/off a stack and saved instead of overwriting property values. the current context is merged with the other contexts, overriding them for this context level but not for the entire site.

to demonstrate with an example: given the following site structure (note that this example assumes true sub collection support .. i know, another feature request).:

├── config.yaml
├── releases
│   ├── releases.yaml
│   ├── B
│   │   ├── tracks
│   │   │   ├── 1
│   │   │   │   ├── index.html
│   │   │   │   └── info.yaml
│   │   │   └── 2
│   │   │       ├── index.html
│   │   │       └── info.yaml
│   │   └── B.yaml
│   └── A
│       ├── tracks
│       │   ├── 1
│       │   │   ├── index.html
│       │   │   └── info.yaml
│       │   ├── 4
│       │   │   ├── index.html
│       │   │   └── info.yaml
│       │   ├── 2
│       │   │   ├── index.html
│       │   │   └── info.yaml
│       │   └── 3
│       │       ├── index.html
│       │       └── info.yaml
│       └── A.yaml
└── pages
    ├── about.html
    └── news.html

the root config.yaml defines a license property and value that in essence becomes the default license for all content on the site (this property is used in the default page layout via {{license}}). pages can override this value in their own front data (e.g. inside /releases/A/tracks/1/index.html), as can collections (e.g. by setting license inside /releases/releases.yaml basically a new default license is set for each collection element of the releases collection, as well as sub collections).

a nice feature of this context in this use case is that tracks (i.e. a sub collection of a release) will inherit the license property of their parent release, but also be able to override it without deleting it for other contexts. in this particular case of releases and tracks, this could obviously be useful for tracks inheriting all kinds of properties from their containing release (e.g. release date, tags, genre, links, credits, etc.) while allowing tracks to easily override properties that are different (e.g. title).

one problem with this request and current functionality: currently properties inside a page's front matter have to be prefixed with page, thus in the layout {{page.license}} would be needed to access the page's license value, while {{data.license}} is needed to get the site default. for my above scenario to work, data properties defined anywhere in the site (YFM, data files, config.yaml, etc.) would have to share the same namespace. however, for accessing special values reserved namespaces like page, this, collection could be used (e.g. collection.tags get all the tags of the current collection).

i hope this makes some sense and i have illustrated how it could be useful. also, i hope that Ruhoh does not already do this! my tests seem to indicate that it does not but i am still learning my way around.

i believe that this hierarchy of context in a natural fit with Ruhoh's directory-based layout and configuration.

peace