Fractal: context data doesn't travel

Created on 25 Apr 2016  路  6Comments  路  Source: frctl/fractal

Ok, I've got a set of patterns that are in a folder /hoff which are each in their own folder /hoff/hoff-title, /hoff/hoff-paragraph and /hoff/hoff-media. These patterns pull in data from a .yml file that's in the parent folder (/hoff).
As part of our pattern library we are also showing certain generic pages. If I have the page in a new folder /baywatch and each pattern in /hoff is included the context data gets pull in when making the page (which is ace) but when going to the dropdown of /baywatch the context data isn't there.

Is there any way of getting this showing up? Maybe even with multiple data files too?

question

Most helpful comment

Hey @shawnbot - This is actually a different issue to the one originally opened by @sturobson. However you are correct, currently there is no way to pass custom properties through like that, and that would definitely be a useful feature. I've added a separate issue to implement that here: https://github.com/frctl/fractal/issues/89

However there is a bigger issue here which is that it should be easier to auto-generate links to component's assets for use in the preview layouts or similar. Hard coding them into config files _would_ work (once I implement that feature) but it's very brittle - re-organising your components around would cause all the links to break which is really something I'm trying to avoid. I'm going to have a quick think about how this could be handled better and address it as a matter of priority - this is a really common use case I think.

(At the moment the assumption was that most people would be using a build step to move/process/concat assets into a 'public' folder or similar and then link to them from there. That assumption sucks!)

All 6 comments

@sturobson - so... you are correct about context data not 'travelling'. This is due to the fact that all Fractal is really doing is rendering templates (and doesn't have any specific knowledge about the content of those templates, what sub-templates they include etc). The only data passed to the templates when they are rendered to generate a preview is the context data defined in the data file for that specific component.

However, when rendering a preview of a parent component that includes sub components, you will often want to avoid specifying 'fresh' data for all the sub-components you are pulling in. So there are a few ways to handle this.

  1. Use the 'render' helper ( {{render '@example'}}) instead of the standard Handlebars partial syntax ({{> @example }}) to include sub-components. If you don't pass any data into the helper, it will render the component in place using the context data defined for the sub-component itself, which is likely the behaviour that you are expecting. Data for sub components then can be overridden on a per-component basis, if needed.
  2. 'Import' the context data for each of the sub-components into the parent components context data using the static reference syntax.
  3. Use JavaScript as the format for your configuration files. You can then require other components files (or create a shared 'data store' file that multiple components can pull data out of) using the standard Node module system.

Unless you have an reason to not want to include Fractal-specific helpers into your components, I'd recommend the first option as it's the simplest and likely gives you the behaviour you are expecting.

Does that make sense?

And I guess not only does it just make sense... would one of the above actually solve the issue you are having in a useful manner? Or are there other problems that I've not considered with the above approaches?

Hi Mark -- I'm not sure if this answers my use case - or I can't read well...
in the 'page' that's made up of all the components, with the components having a parent .yml file so on each component you can see the context data - it'd be nice for the 'page' to show that context data too.

I think you've answered it with preview explanation above. But just double checking :)

Ah right - you mean in the UI view? Unfortunately that is not really possible. Fractal isn't actually parsing the templates, that is all down to the template engine. So Fractal itself doesn't know what is included or not in the page.

You can do this manually by using the standard handlebars partial syntax ({{> @foo }}) and then manually specify the full context for the parent page (and it's sub-components) in the parent's config file. But you may be repeating data for sub-components in this case.

I think I'm having this same issue, but I'm not 100% sure. I'm also not completely familiar with what's going on in Handlebars land, so forgive me if I'm just being dense here.

I have a component with several variations, and I want the preview for all of them to programmatically include the the same CSS and JS files. This is a pattern that applies to all of my components, so I was expecting that I could just add arbitrary data to the component configs, a la:

# component.config.yml
title: My Component

scripts:
  # this is the path that Fractal generates for the component's script asset
  - /assets/components/my-component/my-component.js

stylesheets:
  - /assets/components/my-component/my-component.css

context:
  foo: bar

Then, in my preview template for all components, I figured I could access them via _target like so:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>{{ _target.title }}</title>
    {{#each _target.stylesheets}}
    <link rel="stylesheet" href="{{ path href }}" media="{{ media }}">
    {{/each}}
  </head>
  <body>
    <main>{{{ yield }}}</main>

    {{#each _target.scripts}}
    <script src="{{ path . }}"></script>
    {{/each}}
  </body>
</html>

Unfortunately, though, the _target data doesn't contain the scripts or stylesheets keys that I specified in the config by the time it gets to Handlebars. (I confirmed this by writing a jsonify helper and spitting out its contents on the page.) Coming from Jekyll, where you can access anything in a page's front matter, this was frustrating. I had to move the scripts and stylesheets into the config's context (where they clutter up the Context preview) to get it working the way I need it to.

I haven't dug into the source, but I suspect that what's happening is that the _target is the result of copying specific keys from the config. My suggestion is that the entire config be copied over or used directly, and specific keys merged into _that_ from the component data structure, so the config becomes the source of truth rather than the internal representation of the component. Either that, or make the raw config available via _target.config?

Hey @shawnbot - This is actually a different issue to the one originally opened by @sturobson. However you are correct, currently there is no way to pass custom properties through like that, and that would definitely be a useful feature. I've added a separate issue to implement that here: https://github.com/frctl/fractal/issues/89

However there is a bigger issue here which is that it should be easier to auto-generate links to component's assets for use in the preview layouts or similar. Hard coding them into config files _would_ work (once I implement that feature) but it's very brittle - re-organising your components around would cause all the links to break which is really something I'm trying to avoid. I'm going to have a quick think about how this could be handled better and address it as a matter of priority - this is a really common use case I think.

(At the moment the assumption was that most people would be using a build step to move/process/concat assets into a 'public' folder or similar and then link to them from there. That assumption sucks!)

Was this page helpful?
0 / 5 - 0 ratings