Skip to content

Commit

Permalink
restore docs
Browse files Browse the repository at this point in the history
  • Loading branch information
thescientist13 committed Mar 19, 2021
1 parent 9b6df9b commit efbb1c9
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 91 deletions.
53 changes: 50 additions & 3 deletions packages/plugin-graphql/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# @greenwood/plugin-graphl

## Overview
A plugin for Greenwood for using GraphQL to query your content within your application.
A plugin for Greenwood to support using [GraphQL](https://graphql.org/) to query your content graph. It runs [**apollo-server**](https://www.apollographql.com/docs/apollo-server/) on the backend and provides an [**@apollo/client** like](https://www.apollographql.com/docs/react/api/core/ApolloClient/#ApolloClient.readQuery) interface for the frontend.

> This package assumes you already have `@greenwood/cli` installed.
Expand Down Expand Up @@ -32,6 +32,53 @@ module.exports = {
}
```

This will then allow you to use a query your content using GraphQL.
## Example
This will then allow you to use GraphQL to query your content.

TODO
```js
import client from '@greenwood/plugin-graphql/core/client';
import MenuQuery from '@greenwood/plugin-graphql/queries/menu';

class HeaderComponent extends HTMLElement {
constructor() {
super();

this.root = this.attachShadow({ mode: 'open' });
}

connectedCallback() {
const response = await client.query({
query: MenuQuery,
variables: {
name: 'navigation',
order: 'index_asc'
}
});

this.navigation = response.data.menu.children.map(item => item.item);
this.root.innerHTML = this.getTemplate(navigation);
}

getTemplate(navigation) {
const navigationList = navigation.map((menuItem) => {
return `
<li>
<a href="${menuItem.route}" title="Click to visit the ${menuItem.label} page">${menuItem.label}</a>
</li>
`;
}).join();

return `
<header>
<nav>
<ul>
${navigationList}
</ul>
</nav>
<header>
`;
}
}
```

> _For more information on using GraphQL with Greenwood, [please review our docs](https://www.greenwoodjs.io/docs/data)._
3 changes: 2 additions & 1 deletion packages/plugin-graphql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"Greenwood",
"GraphQL",
"Static Site Generator",
"NodeJS"
"NodeJS",
"Apollo"
],
"main": "src/index.js",
"files": [
Expand Down
164 changes: 101 additions & 63 deletions www/pages/docs/data.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@ linkheadings: 3

## Data Sources

> [_**Coming Soon!**_](https://github.com/ProjectEvergreen/greenwood/issues/278)
<!--
### Overview

Having to repeat things when programming is no fun, and that's why (web) component based development is so useful! As websites start to grow, there comes a point where being able to have access to the content and structure of your site's layout and configuration as part of the development process becomes essential towards maintainability, performance, and scalability.

As an example, if you are developing a blog site, like in our [Getting Started](/getting-started/) guide, having to list a couple blogs posts by hand isn't so bad.
As an example, if you are developing a blog site, like in our [Getting Started](/getting-started/) guide, having to manually list a couple of blog posts by hand isn't so bad.

```html
<ul>
Expand All @@ -25,47 +22,77 @@ As an example, if you are developing a blog site, like in our [Getting Started](
</ul>
```

But what happens over time, when that list grows to 10, 50, 100+ posts? Imagine maintaining that list each time, over and over again? Not only that, but wouldn't it be great to also be able to sort, search, filter, and organize those posts to make them easier for users to navigate and find? Even better would be not having to maintain a secondary list of your own content.
But what happens over time, when that list grows to 10, 50, 100+ posts? Imagine maintaining that list each time, over and over again? Or just remembering to update that list each time you publish a new post? Not only that, but wouldn't it also be great to sort, search, filter, and organize those posts to make them easier for users to navigate and find?

Instead, Greenwood uses GraphQL + Apollo to make that a reality! So instead of a static list, you can do something like this!
So instead of a static list, you can do something like this!

```javascript
render() {
return html`
<ul>
${pages.map((page) => {
return html`
<li><a href=\"${page.path}\">${page.title}</a></li>
<li><a href="${page.path}">${page.title}</a></li>
`;
})}
</ul>
`;
}
```

To assist with this, Greenwood provides all your content as data, accessible from a single _graph.json_ file that you can simply [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) RESTfully or, if you install our [plugin for GraphQL](https://github.com/ProjectEvergreen/greenwood/tree/master/packages/plugin-graphql), you can use a GraphQL interfact to make all this a reality! 💯


### Internal Sources
Greenwood exposes a [GraphQL](https://graphql.org/) + [Apollo](https://www.apollographql.com/docs/apollo-server/) server locally when developing available at `localhost:4000` that can be used to get information about your local content like path, "slug", title and other useful information that will be dynamic to the content you have. Programmatic access to this data can provide the oppourtunity to share your content with your users in a way that supports sorting, filter, organizing, and more!
Greenwood (via [**plugin-graphql**](https://github.com/ProjectEvergreen/greenwood/tree/master/packages/plugin-graphql)) exposes an [Apollo](https://www.apollographql.com/docs/apollo-server/) server locally when developing available at `localhost:4000` that can be used to get information about your local content like path, "slug", title and other useful information that will be dynamic to the content you create. Programmatic access to this data can provide you the oppourtunity to share your content with your users in a way that supports sorting, filter, organizing, and more!

![graphql-playground](/assets/graphql-playground.png)

#### Schema
To kick things off, let's review what is available to you. Currently, the main "API" is just a list of all pages in your _pages/_ directory, represented as a `Page` [type definition](https://graphql.org/graphql-js/basic-types/). This is called Greenwood's `graph`.


/*
* Graph Properties (per page)
*----------------------
* data: custom page frontmatter
* filename: name of the file
* id: filename without the extension
* label: "pretty" text representation of the filename
* path: path to the file relative to the workspace
* route: URL route for a given page on outputFilePath
* template: page template to use as a base for a generated component
* title: a default value that can be used for <title></title>
*/
pages.push({
data: customData || {},
filename,
id,
label,
path: route === '/' || relativePagePath.lastIndexOf('/') === 0
? `${relativeWorkspacePath}${filename}`
: `${relativeWorkspacePath}/${filename}`,
route,
template,
title
});

This is what the schema looks like:
```javascript
graph {
id, // (string) the unique ID given to the generated component as it's selector e.g. `<wc-md-id></wc-md-id>`
filename, // (string) file name without extension/path, so that it can be copied to scratch dir with same name

id, // (string) filename without the extension

link, // (string) A URL link, typically derived from the filesystem path, e.g. /blog/2019/first-post/
label, // (string) best guess pretty text / display based on filename

title, // (string) Useful for a page's <title> tag or the title attribute for an <a> tag, inferred from the filesystem path, e.g. "First Post" or provided through front matter.
path, // (string) path to the file

filePath, // (string) path to file
route, // (string) A URL, typically derived from the filesystem path, e.g. /blog/2019/first-post/

fileName, // (string) file name without extension/path, so that it can be copied to scratch dir with same name
template, // (string) page template used for the page

template // (string) page template used for the page
title, // (string) Useful for a page's <title> tag or the title attribute for an <a> tag, inferred from the filesystem path, e.g. "First Post" or provided through front matter.
}
```

Expand All @@ -83,21 +110,22 @@ The Graph query returns an array of all pages.
```javascript
query {
graph {
filename,
id,
title,
link,
filePath,
fileName,
template
label,
path,
route,
template,
title
}
}
```

###### Usage
`import` the query in your component
```javascript
import client from '@greenwood/cli/data/client';
import GraphQuery from '@greenwood/cli/data/queries/graph';
import client from '@greenwood/plugin-graphql/core/client';
import GraphQuery from '@greenwood/plugin-graphql/queries/menu';

.
.
Expand All @@ -118,20 +146,30 @@ This will return the full `graph` of all pages as an array
```javascript
[
{
id: "dd1ec2ef00cc386",
title: "Blog",
link: "/blog/2019/first-post",
filePath: "./blog/2019/first-post.md",
fileName: "first-post",
template: "blog"
filename: "index.md",
id: "index",
label: "Index",
path: "./index.md",
route: "/",
template: "page",
title: "Home Page"
}, {
filename: "first-post.md",
id: "first-post",
label: "First Post",
path: "./blog/2019/first-post.md",
route: "/blog/2019/first-post",
template: "blog",
title: "My First Blog Poast"
},
{
id: "9d2b98c69ab0867"
title: "Blog",
link: "/blog/2019/second-post",
filePath: "./blog/2019/second-post.md",
fileName: "second-post",
template: "blog"
filename: "second-post.md",
id: "second-post",
label: "Second Post",
path: "./blog/2019/second-post.md",
route: "/blog/2019/second-post",
template: "blog",
title: "My Second Blog Poast"
}
]
```
Expand All @@ -148,20 +186,21 @@ The Children query returns an array of all pages below a given top level route.
query {
children {
id,
title,
link,
filePath,
fileName,
template
filename,
label,
path,
route,
template,
title
}
}
```

###### Usage
`import` the query in your component
```javascript
import client from '@greenwood/cli/data/client';
import ChildrenQuery from '@greenwood/cli/data/queries/children';
import client from '@greenwood/plugin-graphql/core/client';
import ChildrenQuery from '@greenwood/plugin-graphql/queries/menu';

.
.
Expand All @@ -185,20 +224,22 @@ This will return the full `graph` of all pages as an array that are under a give
```javascript
[
{
id: "dd1ec2ef00cc386",
title: "Blog",
link: "/blog/2019/first-post",
filePath: "./blog/2019/first-post.md",
fileName: "first-post",
template: "blog"
filename: "first-post.md",
id: "first-post",
label: "First Post",
path: "./blog/2019/first-post.md",
route: "/blog/2019/first-post",
template: "blog",
title: "My First Blog Poast"
},
{
id: "9d2b98c69ab0867"
title: "Blog",
link: "/blog/2019/second-post",
filePath: "./blog/2019/first-post.md",
fileName: "second-post",
template: "blog"
filename: "second-post.md",
id: "second-post",
label: "Second Post",
path: "./blog/2019/second-post.md",
route: "/blog/2019/second-post",
template: "blog",
title: "My Second Blog Poast"
}
]
```
Expand Down Expand Up @@ -231,17 +272,16 @@ query {
###### Usage
`import` the query in your component
```javascript
import client from '@greenwood/cli/data/client';
import ConfigQuery from '@greenwood/cli/data/queries/config';
import client from '@greenwood/plugin-graphql/core/client';
import ConfigQuery from '@greenwood/plugin-graphql/queries/menu';
.
.
.

async connectedCallback() {
super.connectedCallback();
const response = await client.query({
query: GraphQuery
query: ConfigQuery
});

this.meta = response.data.config.meta;
Expand Down Expand Up @@ -298,8 +338,8 @@ Now of course comes the fun part, actually seeing it all come together. Here is

```javascript
import { LitElement, html } from 'lit-element';
import client from '@greenwood/cli/data/client';
import MenuQuery from '@greenwood/cli/data/queries/menu';
import client from '@greenwood/plugin-graphql/core/client';
import MenuQuery from '@greenwood/plugin-graphql/queries/menu';

class HeaderComponent extends LitElement {

Expand All @@ -326,7 +366,7 @@ class HeaderComponent extends LitElement {
}
});

this.navigation = response.data.menu.children;
this.navigation = response.data.menu.children.map(item => item.item);
}

render() {
Expand All @@ -339,7 +379,7 @@ class HeaderComponent extends LitElement {
<ul>
${navigation.map(({ item }) => {
return html`
<li><a href="${item.link}" title="Click to visit the ${item.label} page">${item.label}</a></li>
<li><a href="${item.route}" title="Click to visit the ${item.label} page">${item.label}</a></li>
`;
})}
</ul>
Expand All @@ -354,6 +394,4 @@ customElements.define('app-header', HeaderComponent);
```

### External Sources
Coming [soon](https://github.com/ProjectEvergreen/greenwood/issues/21)!
-->
Coming [soon](https://github.com/ProjectEvergreen/greenwood/issues/21)!
4 changes: 2 additions & 2 deletions www/pages/docs/front-matter.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ In this example, the `<title>` tag will be the `title`.
### Custom Data

You can also pass custom data from your markdown file and extract that through the GraphQL server.
You can also pass custom data from your markdown file and extract that from Greenwood's [_graph.json_ via `fetch` or our GraphQL server](/docs/data/).


#### Example
Expand All @@ -107,4 +107,4 @@ query {
}
```

> See [our docs](https://deploy-preview-284--elastic-blackwell-3aef44.netlify.com/docs/data#internal-sources) on using GraphQL w/Greenwood for more information on querying for data.
> See [our docs](/docs/data#internal-sources) on using GraphQL w/Greenwood for more information on querying for data.
Loading

0 comments on commit efbb1c9

Please sign in to comment.