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] Build Time Data Injection #115

Closed
1 of 5 tasks
thescientist13 opened this issue Jul 7, 2019 · 4 comments
Closed
1 of 5 tasks

[RFC] Build Time Data Injection #115

thescientist13 opened this issue Jul 7, 2019 · 4 comments
Assignees
Labels
Content as Data RFC Proposal and changes to workflows, architecture, APIs, etc v0.5.0 Data w/ GraphQL
Milestone

Comments

@thescientist13
Copy link
Member

Type of Change

  • New Feature Request
  • Documentation / Website
  • Improvement / Suggestion
  • Bug
  • Other (please clarify below)

Summary

As a precursor to something like #21 , being able to pass data from build time to runtime is a critical API for Greenwood to provide.

Details

A good example of where this could be useful now is in how the items and subitem are configured for the Shelf component.

Currently the pages and links are determined by hardcoding a list of items and subitems in a JSON file in www/templates/page-template.js

setupShelf() {
  // based on path, display selected list
  const path = window.location.pathname;

  if (path.substring(0, 5) === '/docs') {
    shelfList = require('../components/shelf/documentation-list.json');
  } else {
    shelfList = require('../components/shelf/getting-started-list.json');
  }
}

...

<eve-shelf .shelfList="${shelfList}"></eve-shelf>

So an example of how Greenwood could help with this is by being able to pass information from the build, like the graph.

import { graph } from 'xxx';

setupShelf() {
  // map over the graph and create the shelfList object dynamically
  graph.pages.map((page) => {
    // xxx
  } 
}

Crossing this membrane is essentially how eventually external data and plugins can operate and provide dynamic information at build time, for the run time.

@thescientist13 thescientist13 added the RFC Proposal and changes to workflows, architecture, APIs, etc label Jul 7, 2019
@thescientist13 thescientist13 added this to the MVP milestone Jul 7, 2019
@thescientist13 thescientist13 self-assigned this Jul 7, 2019
@thescientist13
Copy link
Member Author

In working on #127, I noticed that a similar issue was occurring and so wanted to capture those thoughts here to ensure concentration of the subject matter. Essentially, the issue with the <eve-meta> is that a web component, it will requires a lifecycle update in the browser to actually render any DOM.

In other words, doing this (essentially)

<eve-meta .attributes="${metadata}"></eve-meta>

means that regardless of what the initial contents of metadata are, this code still needs to run in a browser in order to output any "content" to the DOM. Of course, since this is what we are literally doing, then of course this works for us.

To continue from the description of this issue then, I think it's becoming clearer that the app-template and / or page-template make the most sense for "piercing the membrane" so to speak. Essentially, to take the existing component and just move it from scaffolding, would like this:

import { metadata } from 'xxx';
import { html, LitElement } from 'lit-element';

...

class AppComponent extends LitElement {
  render() {
    return html`
       <eve-meta .attributes=${metadata}>
        MYROUTES
        <lit-route><h1>404 Not found</h1></lit-route>
    `;
  }
}

customElements.define('eve-app', AppComponent);

This frees up the CLI and no more swapping files in and out, and still keeps the <eve-meta> component essentially the same and (IMO) puts more control in the user, which I think is the greatest win.

So, that aside, and also looping in #17, is what we want the API of this tool to really be, because it seems like it should comes down to, how much do we want rely on rendering in the browser? The more complex the app, the longer the build times? Or as long as components all define a firstUpdated / connectedCallback then it will get serialized?

Otherwise, if we have custom plugins, they might be able to serialize at build time (no browser) but would probably be specific to just Greenwood. With the above approach, maybe in custom element / lit element would work no problem? 🤞

@thescientist13
Copy link
Member Author

Another thought: by moving <eve-meta> out of the CLI, this definitely will help with unit testing and maintenance, but improving our coverage (removing an uncovered file) and one less thing the CLI has to do.

@thescientist13
Copy link
Member Author

Another related topic is that of hydration. In regards to #128 for example, one thing I notice with current implementation is of course that being that <eve-meta> is a Web Component, it will of course only render on the client side and then dynamically adds the <meta> tags. One side effect of this when developing is that the title of the browser tab will go from My App (default value) to whatever is provided by the config.

So basically, maybe just a development related thing, depending on how reliable our puppeteer implementation can be.

@thescientist13
Copy link
Member Author

Would also be good to be able to define data via frontmatter, e.g.

---
template: 'blog'
date: '2019-09-01'
title: 'Blog Post Title'
---

Would help a lot in this project and would allow more (all?) of the logic to happen in the template
https://raw.githubusercontent.com/thegreenhouseio/www.thegreenhouse.io/technical/issue-96-greenwood-migration/src/pages/blog/2018/01/24/index.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Content as Data RFC Proposal and changes to workflows, architecture, APIs, etc v0.5.0 Data w/ GraphQL
Projects
None yet
Development

No branches or pull requests

2 participants