From cb2271267c8fce7e622b7ff1bb7f3afe72a3f9d7 Mon Sep 17 00:00:00 2001 From: Asko Soukka Date: Sun, 5 Aug 2018 00:44:08 +0300 Subject: [PATCH] Update documentation * update index * make tutorial root level * remove BFS traversal documentation * remove references to removed parent / children hierarchy --- docs/authentication.md | 55 -------- docs/expansions.md | 81 ------------ docs/gatsby_v2.md | 3 - docs/index.md | 20 ++- docs/plugin_options.md | 35 ----- docs/publish.sh | 2 +- docs/recursive_traversal.md | 37 ------ docs/reference/authentication.md | 59 +++++++++ docs/reference/expansions.md | 85 +++++++++++++ docs/{ => reference}/file_handling.md | 12 +- docs/{ => reference}/html_parsing.md | 6 +- docs/reference/plugin_options.md | 32 +++++ docs/reference/search_parameters.md | 20 +++ docs/reference/search_traversal.md | 79 ++++++++++++ docs/reference/tree-hierarchy.md | 21 +++ docs/search_parameters.md | 13 -- docs/search_traversal.md | 78 ------------ docs/tree-hierarchy.md | 25 ---- .../fixture/.index.json | 20 ++- .../gatsby-starter-default/fixture/docs.json | 120 ------------------ .../fixture/docs/authentication.json | 54 -------- .../fixture/docs/expansions.json | 54 -------- .../fixture/docs/file_handling.json | 54 -------- .../fixture/docs/gatsby_v2.json | 54 -------- .../fixture/docs/index.json | 54 -------- .../fixture/docs/plugin_options.json | 54 -------- .../fixture/docs/recursive_traversal.json | 54 -------- .../fixture/docs/search_parameters.json | 54 -------- .../fixture/docs/search_traversal.json | 54 -------- .../fixture/docs/tree-hierarchy.json | 54 -------- .../fixture/examples.json | 22 ++-- .../a-link-to-the-documentation-of-plone.json | 8 +- .../fixture/examples/a-nico-e-pagie.json | 8 +- .../a-page-with-internal-linking.json | 8 +- .../fixture/examples/event-collection.json | 8 +- .../fixture/examples/first-results.json | 8 +- .../fixture/examples/midsummer.jpg.json | 8 +- .../examples/plone-conference-tokyo.json | 8 +- .../fixture/examples/plone-logo-1.svg.json | 10 +- .../fixture/examples/plone-logo-192.png.json | 8 +- .../fixture/examples/plone-logo.pdf.json | 8 +- .../fixture/examples/plone-logo.svg.json | 10 +- .../fixture/examples/subfolder-level-two.json | 8 +- .../subfolder-level-two/level-three.json | 8 +- .../level-three/level-four.json | 8 +- .../fixture/examples/the-news-collection.json | 53 ++++---- .../gatsby-starter-default/fixture/index.json | 12 +- .../gatsby-starter-default/fixture/news.json | 8 +- .../fixture/news/gatsby-plugin-for-plone.json | 8 +- .../news/gsoc-gatsby-source-plone.json | 8 +- .../fixture/reference.json | 106 ++++++++++++++++ .../fixture/reference/authentication.json | 54 ++++++++ .../fixture/reference/expansions.json | 54 ++++++++ .../fixture/reference/file_handling.json | 54 ++++++++ .../fixture/reference/html_parsing.json | 54 ++++++++ .../fixture/reference/plugin_options.json | 54 ++++++++ .../fixture/reference/search_parameters.json | 54 ++++++++ .../fixture/reference/search_traversal.json | 54 ++++++++ .../fixture/reference/tree-hierarchy.json | 54 ++++++++ .../fixture/tutorial.json | 78 ++++++++++++ .../fixture/tutorial/1_getting_started.json | 54 ++++++++ .../fixture/tutorial/2_querying_and_auth.json | 54 ++++++++ .../fixture/tutorial/3_page_creation.json | 54 ++++++++ .../tutorial/4_handling_data_types.json | 54 ++++++++ tests/gatsby-starter-default/gatsby-config.js | 2 +- tests/gatsby-starter-default/gatsby-node.js | 1 + .../src/components/Folder.js | 2 +- .../src/components/Layout.js | 9 +- .../src/components/NavBar.js | 2 +- .../gatsby-starter-default/src/pages/index.js | 2 +- tests/gatsby-starter-default/test.robot | 22 ++-- 71 files changed, 1309 insertions(+), 1133 deletions(-) delete mode 100644 docs/authentication.md delete mode 100644 docs/expansions.md delete mode 100644 docs/gatsby_v2.md delete mode 100644 docs/plugin_options.md delete mode 100644 docs/recursive_traversal.md create mode 100644 docs/reference/authentication.md create mode 100644 docs/reference/expansions.md rename docs/{ => reference}/file_handling.md (85%) rename docs/{ => reference}/html_parsing.md (89%) create mode 100644 docs/reference/plugin_options.md create mode 100644 docs/reference/search_parameters.md create mode 100644 docs/reference/search_traversal.md create mode 100644 docs/reference/tree-hierarchy.md delete mode 100644 docs/search_parameters.md delete mode 100644 docs/search_traversal.md delete mode 100644 docs/tree-hierarchy.md delete mode 100644 tests/gatsby-starter-default/fixture/docs.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/authentication.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/expansions.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/file_handling.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/gatsby_v2.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/index.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/plugin_options.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/recursive_traversal.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/search_parameters.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/search_traversal.json delete mode 100644 tests/gatsby-starter-default/fixture/docs/tree-hierarchy.json create mode 100644 tests/gatsby-starter-default/fixture/reference.json create mode 100644 tests/gatsby-starter-default/fixture/reference/authentication.json create mode 100644 tests/gatsby-starter-default/fixture/reference/expansions.json create mode 100644 tests/gatsby-starter-default/fixture/reference/file_handling.json create mode 100644 tests/gatsby-starter-default/fixture/reference/html_parsing.json create mode 100644 tests/gatsby-starter-default/fixture/reference/plugin_options.json create mode 100644 tests/gatsby-starter-default/fixture/reference/search_parameters.json create mode 100644 tests/gatsby-starter-default/fixture/reference/search_traversal.json create mode 100644 tests/gatsby-starter-default/fixture/reference/tree-hierarchy.json create mode 100644 tests/gatsby-starter-default/fixture/tutorial.json create mode 100644 tests/gatsby-starter-default/fixture/tutorial/1_getting_started.json create mode 100644 tests/gatsby-starter-default/fixture/tutorial/2_querying_and_auth.json create mode 100644 tests/gatsby-starter-default/fixture/tutorial/3_page_creation.json create mode 100644 tests/gatsby-starter-default/fixture/tutorial/4_handling_data_types.json diff --git a/docs/authentication.md b/docs/authentication.md deleted file mode 100644 index aa19ea07..00000000 --- a/docs/authentication.md +++ /dev/null @@ -1,55 +0,0 @@ -# Authentication - -For Plone sites requiring authentication to use plone.restapi, use the following guide to set up a safe method of authentication using [JWT](http://plonerestapi.readthedocs.io/en/latest/authentication.html#json-web-tokens-jwt) and [dotenv](https://github.com/motdotla/dotenv) configuration. - -* In UNIX-like systems (OSX, Linux, Linux subsystem for Windows), a bash script would serve as a good way to retrieve the JWT from plone.restapi, by prompting for username and password: - -```bash -# 1. enter a new bash environment -bash -# 2. read username into environment variable -read -p "Username: " USERNAME -# 3. read password into environment variable without displaying it while typing -read -sp "Password: " PASSWORD -# 4. request authorization token -curl -s -X POST http://localhost:8080/Plone/@login -H 'Accept: application/json' -H 'Content-Type: application/json' --data-raw '{"login": "'"$USERNAME"'", "password": "'"$PASSWORD"'"}' -# 5. exit bash to forget environment variables -exit -``` - -* This would give you a token as output: - -``` -{ - "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI" -} -``` - -* Install dotenv and setup `.env` with the token so that it can be used in the Gatsby project - -``` -// Install dotenv -yarn install dotenv - - -// In .env in the project folder -TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI -``` - -* Finally setup `gatsby-config.js` to use this in your project: - -```javascript -// Top of your file -require("dotenv").config({ - path: '.env', -}); - -// In plugins list -{ - resolve: 'gatsby-source-plone', - options: { - baseUrl: 'http://localhost:8080/Plone/', - token: process.env.TOKEN, - }, -} -``` diff --git a/docs/expansions.md b/docs/expansions.md deleted file mode 100644 index c9077a3b..00000000 --- a/docs/expansions.md +++ /dev/null @@ -1,81 +0,0 @@ -# Expansions - -According to [plone.restapi docs](https://plonerestapi.readthedocs.io/en/latest/expansion.html), expansion is a mechanism to embed additional “components”, such as _navigation, breadcrumbs, schema,_ or _workflow_ within the main content response, helping the API consumers to avoid unnecessary requests. - -For instance, a normal GET request to `http://localhost:8080/Plone` would give the following response: - -```json -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/@navigation" - } - }, - "@id": "http://localhost:8080/Plone", - "@type": "Plone Site", - "id": "Plone", - ... -``` - -But in the case we need the _breadcrumbs, navigation_ data or so on, we'll need to make more requests to `/@breadcrumbs`, `/@navigation` and more depending on the data we need. - -Expansions simplifies this process by retrieving all data in a single request as `http://localhost:8080/Plone?expand=breadcrumbs,navigation` giving the response: - -```json -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/@breadcrumbs", - "items": [] - }, - "navigation": { - "@id": "http://localhost:8080/Plone/@navigation", - "items": [ - { - "@id": "http://localhost:8080/Plone", - "description": "", - "title": "Home" - }, - { - "@id": "http://localhost:8080/Plone/news", - "description": "News on gatsby-source-plone development", - "title": "News" - }, - { - "@id": "http://localhost:8080/Plone/index", - "description": "", - "title": "gatsby-source-plone" - }, - { - "@id": "http://localhost:8080/Plone/search_traversal", - "description": "", - "title": "Traversal using @search endpoint" - }, - { - "@id": "http://localhost:8080/Plone/plugin_options", - "description": "", - "title": "Plugin Options" - }, - { - "@id": "http://localhost:8080/Plone/testcases", - "description": "A folder with different standard content types that Plone supports out of the box", - "title": "Testcases" - } - ] - } - }, - "@id": "http://localhost:8080/Plone?expand=breadcrumbs%2Cnavigation", - "@type": "Plone Site", - "id": "Plone", - "is_folderish": true, - ... -``` diff --git a/docs/gatsby_v2.md b/docs/gatsby_v2.md deleted file mode 100644 index c402e0ec..00000000 --- a/docs/gatsby_v2.md +++ /dev/null @@ -1,3 +0,0 @@ -# Migration to Gatsby v2 - -Currently, the plugin and it's tester project is running on Gatsby v2 Beta. diff --git a/docs/index.md b/docs/index.md index f95a39c3..6eda42a0 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,20 @@ # gatsby-source-plone -Gatsby is a blazing fast static site generator for React. By using Plone as source, this can be used to generate a static site with PWA features with something equivalent to the click of a button. That’s the essence of the **“Big Green Button”** proposal, according to **Martin Aspeli**, who wrote a blog post **"[Pete and Andy try Plone 4](http://www.martinaspeli.net/articles/pete-and-andy-try-plone-4)"**: +[GatsbyJS](https://www.gatsbyjs.org/) is a generator for blazing fast static web sites or web apps powered by pre-rendered [ReactJS](https://reactjs.org/). With this plugin, you can build any amount of gatsby sites from a single [Plone CMS](https://plone.org/), the ultimate open source enterprise CMS. -_"Andy goes to Plone's Deployment control panel. There he finds a Big Green Button. -He pushes it and covers his eyes. A minute later, a bunch of static HTML files appear in a directory on the server, covering the Plone site, with basic navigation and a site map. Search is provided via a form that posts to Google for search results on the current site."_ +This gatsby-source plugin pulls the whole content tree from a Plone site (or its sub-folder) using [Plone REST API](https://plonerestapi.readthedocs.io/en/latest/) and makes it available for querying via GraphQL in a Gatsby based project. -A gatsby-source plugin pulls the whole content tree from the plone.restapi and makes it available for querying via GraphQL in a hierarchical data structure. The gatsby-plone-starter that uses the plugin to source the data from a Plone site will illustrate all use cases of the plugin in a Gatsby project. \ No newline at end of file +Common use-cases include to + +* spin-off practically unlimited amount of individually hosted, branded and featured static sites from content managed in a single Plone instance without side-effects to the Plone instance in question + +* allow mixed use of Plone, where small individually branded ˝poster sites˝ could be published from larger Plone site with unified theme without need for hosting secondary CMS instances for a such need + +* build mash-ups mixin Plone content with content from file-system or other sources. + +No Plone knowledge should be required to use this plugin. Just follow the examples in gatsby-starter-plone and the official Gatsby user documentation. + +A Plone add-on [collective.webhook](https://pypi.org/project/collective.webhook/) can be used to trigger CI pipelines to rebuild and deploy sites after any change in Plone content. + +_˝Andy goes to Plone’s Deployment control panel. There he finds a Big Green Button. +He pushes it and covers his eyes. A minute later, a bunch of static HTML files appear in a directory on the server, covering the Plone site, with basic navigation and a site map. Search is provided via a form that posts to Google for search results on the current site.˝_ –Martin Aspeli, 2009, ˝[Pete and Andy try Plone 4](http://www.martinaspeli.net/articles/pete-and-andy-try-plone-4)˝ diff --git a/docs/plugin_options.md b/docs/plugin_options.md deleted file mode 100644 index ef402591..00000000 --- a/docs/plugin_options.md +++ /dev/null @@ -1,35 +0,0 @@ -# Plugin Options - -A sample configuration in `gatsby-config.js` in your Gatsby project, would look like: - -```javascript -plugins: [ - { - resolve: 'gatsby-source-plone', - options: { - // The base URL of the Plone site you're using as source - baseUrl: 'localhost:8080/Plone', - - // Provide authorization token (not required by default) - // process.env.TOKEN is set by .env - // Read more about setup in authentication docs - token: process.env.TOKEN, - - // Pass search parameters as an object - // By default passes no parameters - searchParams: { - SearchableText: 'tree', - }, - - // Expands passed components - // Accepts components list as an array - // Defaults to ['breadcrumbs', 'navigation'] - expansions: ['breadcrumbs', 'actions'], - - // Show logs of progress as plugin is run - // Defaults to false - showLogs: true, - }, - }, -], -``` diff --git a/docs/publish.sh b/docs/publish.sh index e8e07bbf..a212d977 100755 --- a/docs/publish.sh +++ b/docs/publish.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -baseUrl="http://localhost:8080/Plone/docs" +baseUrl="http://localhost:8080/Plone" DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" marked="$DIR/../node_modules/.bin/marked" diff --git a/docs/recursive_traversal.md b/docs/recursive_traversal.md deleted file mode 100644 index bd85cc2b..00000000 --- a/docs/recursive_traversal.md +++ /dev/null @@ -1,37 +0,0 @@ -# Traversal using recursion - -In the method using `@search` endpoint for traversal, it's required to first create an array of items, and then data of each item is fetched and further processed step by step to an array of nodes. For small list of items, this may seem efficient or when using [search parameters](https://plonerestapi.readthedocs.io/en/latest/searching.html#search). - -So what's preferred in the normal scenario is recursively going through each node's children for traversal. A [Breadth-First Search](https://en.wikipedia.org/wiki/Breadth-first_search) (BFS) was implemented to efficiently traverse through nodes and process them directly. - -A basic implementation of the algorithm in JavaScript can be seen below, (as per this [answer](https://stackoverflow.com/a/33704700/9779563) on Stack Overflow) : - -```javascript -Tree.prototype.traverse = function(callback) { - var queue = [this]; - var n; - - while (queue.length > 0) { - n = queue.shift(); - callback(n.value); - - if (!n.children) { - continue; - } - - for (var i = 0; i < n.children.length; i++) { - queue.push(n.children[i]); - } - } -}; -``` - -This was used as the reference, and the basic idea of the BFS algorithm was followed, ie, using the queue data structure to start with the first item, and then consecutively store the children of each processed item, while processing the dequeued element in each iteration of the loop. - -## Handling Collections - -Collections are data types that are basically a group of content objects returned which a certain search query is run. This means they have children that are originally children of other nodes, which means there isn't a need for them to be traversed again. - -The algorithm was modified to handle this condition as well using a `seen[path]` approach, in which an object `seen` has a list of all paths that's been traversed already saved as `seen[path] = true`. - -Furthermore, it was noted that often, when content objects have a huge list of children, they too, are batched like the `@search` response, and so all content objects have batching support added. diff --git a/docs/reference/authentication.md b/docs/reference/authentication.md new file mode 100644 index 00000000..4d2b9f40 --- /dev/null +++ b/docs/reference/authentication.md @@ -0,0 +1,59 @@ +# Authenticating REST API calls + +For Plone sites requiring authentication to use Plone REST API (or limiting publishable content by permissions of specific user) you may use this guide to set up a safe method of authentication using [JWT](http://plonerestapi.readthedocs.io/en/latest/authentication.html#json-web-tokens-jwt) and [dotenv](https://github.com/motdotla/dotenv) configuration. + +**Note:** In time of writing, Plone REST API only created tokens valid for the next 12 hours. + +In UNIX-like systems (OSX, Linux, Linux subsystem for Windows), a bash script would serve as a good way to retrieve the JWT from plone.restapi, by prompting for username and password: + +```bash +bash +read -p "Username: " USERNAME +read -sp "Password: " PASSWORD +curl -s -X POST http://localhost:8080/Plone/@login -H 'Accept: application/json' -H 'Content-Type: application/json' --data-raw '{"login": "'"$USERNAME"'", "password": "'"$PASSWORD"'"}' +exit +``` +The above script will + +1. enter a new bash environment +2. read username into environment variable +3. read password into environment variable without displaying it when you type +4. request authorization token +5. exit bash to forget environment variables. + +This would give you a token as output: + +```json +{ + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI" +} +``` + +Install dotenv and setup `.env` with the token so that it can be used in the Gatsby project: + +```bash +// Install dotenv +yarn install dotenv + + +// In .env in the project folder +TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI +``` + +Finally setup `gatsby-config.js` to use this in your project: + +```javascript +// Top of your file +require("dotenv").config({ + path: '.env', +}); + +// In plugins list +module.exports = { + resolve: 'gatsby-source-plone', + options: { + baseUrl: 'http://localhost:8080/Plone/', + token: process.env.TOKEN, + } +}; +``` diff --git a/docs/reference/expansions.md b/docs/reference/expansions.md new file mode 100644 index 00000000..d11c449d --- /dev/null +++ b/docs/reference/expansions.md @@ -0,0 +1,85 @@ +# Supported REST API expansions + +This source plugin only supports fixed set of Plone REST API expansions, currently *breadcrumbs* and *navigation*, which are both published as their own GraphQL nodes, *PloneBreadcrumbs* and *PloneNavigation* respectively. + +Expansions are [plone.restapi](https://plonerestapi.readthedocs.io/en/latest/expansion.html) mechanism to embed additional “components”, such as _navigation, breadcrumbs, schema,_ or _workflow_ within the main content response, helping the API consumers to avoid unnecessary requests. + +For instance, a normal GET request to `http://localhost:8080/Plone` would give the following response: + +```json +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/@navigation" + } + }, + "@id": "http://localhost:8080/Plone", + "@type": "Plone Site", + "id": "Plone", + "...": "..." +} +``` + +But in the case we need the _breadcrumbs, navigation_ data or so on, we'll need to make more requests to `/@breadcrumbs`, `/@navigation` and more depending on the data we need. + +Expansions simplifies this process by retrieving all data in a single request as `http://localhost:8080/Plone?expand=breadcrumbs,navigation` giving the response: + +```json +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/@breadcrumbs", + "items": [] + }, + "navigation": { + "@id": "http://localhost:8080/Plone/@navigation", + "items": [ + { + "@id": "http://localhost:8080/Plone", + "description": "", + "title": "Home" + }, + { + "@id": "http://localhost:8080/Plone/news", + "description": "News on gatsby-source-plone development", + "title": "News" + }, + { + "@id": "http://localhost:8080/Plone/index", + "description": "", + "title": "gatsby-source-plone" + }, + { + "@id": "http://localhost:8080/Plone/search_traversal", + "description": "", + "title": "Traversal using @search endpoint" + }, + { + "@id": "http://localhost:8080/Plone/plugin_options", + "description": "", + "title": "Plugin Options" + }, + { + "@id": "http://localhost:8080/Plone/testcases", + "description": "A folder with different standard content types that Plone supports out of the box", + "title": "Testcases" + } + ] + } + }, + "@id": "http://localhost:8080/Plone?expand=breadcrumbs%2Cnavigation", + "@type": "Plone Site", + "id": "Plone", + "is_folderish": true, + "...": "..." +} +``` diff --git a/docs/file_handling.md b/docs/reference/file_handling.md similarity index 85% rename from docs/file_handling.md rename to docs/reference/file_handling.md index f5146ac1..bb2d20de 100644 --- a/docs/file_handling.md +++ b/docs/reference/file_handling.md @@ -1,4 +1,6 @@ -# File Handling +# File and image field support + +**Note:** In time of writing, this plugin only supported file fields named `file` and image fields named `image`. Gatsby along with the plugin [gatsby-source-filesystem](https://v2--gatsbyjs.netlify.com/packages/gatsby-source-filesystem) and the [`createRemoteFileNode`](https://v2--gatsbyjs.netlify.com/packages/gatsby-source-filesystem#createremotefilenode) function it exposes, can be used to pull all types of remote files into the Gatsby cache and use them in the generated Gatsby-site. @@ -6,14 +8,18 @@ For images, another plugin, [gatsby-transformer-sharp](https://v2--gatsbyjs.netl For allowing other types of files to be used in the gatsby-site, gatsby-source-filesystem needs to be configured in the project itself as well, with path configured to a `static` folder: -``` +```javascript // gatsby-config.js - { +module.exports = { + plugins: [ + { resolve: 'gatsby-source-filesystem', options: { path: `${__dirname}/src/static`, }, }, + ] +} ``` This exposes a `publicURL` field in GraphQL for the file node, which can be used to link to the file node and make it downloadable, as implemented in the example gatsby-site. diff --git a/docs/html_parsing.md b/docs/reference/html_parsing.md similarity index 89% rename from docs/html_parsing.md rename to docs/reference/html_parsing.md index af3f4e75..8fc1655b 100644 --- a/docs/html_parsing.md +++ b/docs/reference/html_parsing.md @@ -1,10 +1,12 @@ -# HTML Parsing +# RichText field support + +**Note:** In time of writing, this plugin only supported RichText fields named `text`. HTML content from the [plone.restapi](https://github.com/plone/plone.restapi) is returned as string of HTML. Using a combination of [react-html-parser](url) and [react-serialize](url), this HTML content is processed into React nodes. ## RichText Component -It deserializes the React nodes field which was processed by the plugin to be used in the component and also handles images, files and relative links. Using backlinks, images and files are queried separately and passed into the RichText componoent and it replaces the `img` and `a` tags with updated data, in the case of relative links, it even replaces it with `Link` tags. +It deserializes the React nodes field which was processed by the plugin to be used in the component and also handles images, files and relative links. Using backlinks, images and files are queried separately and passed into the RichText componoent and it replaces the `img` and `a` tags with updated data, in the case of relative links, it even replaces it with `Img` or `Link` tags respectively. ## Parsing process diff --git a/docs/reference/plugin_options.md b/docs/reference/plugin_options.md new file mode 100644 index 00000000..dc49f27a --- /dev/null +++ b/docs/reference/plugin_options.md @@ -0,0 +1,32 @@ +# Plugin Options + +A sample configuration in `gatsby-config.js` in your Gatsby project, could look like: + +```javascript +module.exports = { + plugins: [ + { + resolve: 'gatsby-source-plone', + options: { + // The base URL of the Plone site you're using as source + baseUrl: 'http:///localhost:8080/Plone', + + // Provide authorization token (not required by default) + // process.env.TOKEN is set by .env + // Read more about setup in authentication docs + token: process.env.TOKEN, + + // Pass search parameters as an object + // By default passes no parameters + searchParams: { + review_state: 'published', + }, + + // Show logs of progress as plugin is run + // Defaults to no logging by plugin at all + logLevel: 'INFO', + }, + }, + ] +}; +``` diff --git a/docs/reference/search_parameters.md b/docs/reference/search_parameters.md new file mode 100644 index 00000000..634ae6c4 --- /dev/null +++ b/docs/reference/search_parameters.md @@ -0,0 +1,20 @@ +# Customizing search Parameters + +Plone REST API @search endpoint allows you to pass query string parameters that filters the returned response based on the parameters rather than giving the whole listing of content objects. + +For example + +```javascript +module.exports = { + plugins: [ + { + resolve: 'gatsby-source-plone', + options: { + SearchableText: 'example', + }, + } + ] +} +``` + +searches for 'example' in the Plone site and returns only the relevant objects as response. diff --git a/docs/reference/search_traversal.md b/docs/reference/search_traversal.md new file mode 100644 index 00000000..07cc4b80 --- /dev/null +++ b/docs/reference/search_traversal.md @@ -0,0 +1,79 @@ +# How plugin uses @search endpoint + +In the [plone.restapi](https://github.com/plone/plone.restapi), the `@search` endpoint when fetched without any query returns the full list of content objects. This is used to pull the whole content tree and create nodes with tree hierarchy. + +The procedure followed for this: + +At first, this plugin uses `@search` endpoint to get a flat list of all content objects. + +For instance, `https://plonedemo.kitconcept.com/en/@search` gives the response: + +```json +{ + "@id": "https://plonedemo.kitconcept.com/en/@search", + "items": [ + { + "@id": "https://plonedemo.kitconcept.com/en", + "@type": "LRF", + "description": "", + "review_state": "published", + "title": "English" + }, + { + "@id": "https://plonedemo.kitconcept.com/en/frontpage", + "@type": "Document", + "description": "The ultimate Open Source Enterprise CMS", + "review_state": "published", + "title": "Welcome to Plone 5" + }, + { + "@id": "https://plonedemo.kitconcept.com/en/demo/a-page", + "@type": "Document", + "description": "Aenean dictum auctor elit, in volutpat ipsum venenatis at. Quisque lobortis augue et enim venenatis interdum. In egestas, est at condimentum ultrices, tortor enim malesuada nulla; vel sagittis nullam.", + "review_state": "published", + "title": "A Page" + } + ] +} +``` + +The `items` is an array of all the content objects. + +Next, using this flat list, plugin iterates through the `@id` attributes making individual requests for each content object to get full data. + +From the previous request, plugin extracts the `@id`s forming a list of URLs for each content object: + +``` +https://plonedemo.kitconcept.com/en +https://plonedemo.kitconcept.com/en/frontpage +https://plonedemo.kitconcept.com/en/demo/a-page +... +``` + +Each request will fetch the required data of the content object: + +```json +{ + "@components": { + "breadcrumbs": { + "@id": "https://plonedemo.kitconcept.com/en/demo/a-page/@breadcrumbs" + }, + "navigation": { + "@id": "https://plonedemo.kitconcept.com/en/demo/a-page/@navigation" + }, + "workflow": { + "@id": "https://plonedemo.kitconcept.com/en/demo/a-page/@workflow" + } + }, + "@id": "https://plonedemo.kitconcept.com/en/demo/a-page", + "@type": "Document", + "UID": "eb023ac4d6cd4446ae692cdfd5058e91", + "allow_discussion": null, + "changeNote": "", + "contributors": [], + "created": "2015-07-31T15:42:54+02:00", + "...": "..." +} +``` + +Then this plugin spreads this data to nodes (making them available for GraphQL requests in Gatsby). diff --git a/docs/reference/tree-hierarchy.md b/docs/reference/tree-hierarchy.md new file mode 100644 index 00000000..d1882ce0 --- /dev/null +++ b/docs/reference/tree-hierarchy.md @@ -0,0 +1,21 @@ +# How content hierarchy is mapped + +This plugin does not expose Plone content hierarchy in Gatsby GraphQL queries directly. Instead each node will contain a special attribute `_path` describing the position of node in content hierarchy. Container nodes will contain `_path` attribute also for each item in its `items` attribute returned by Plone REST API. + +In `tests/gatsby-starter-default` this is illustrated for instance, in the [Folder component](https://github.com/collective/gatsby-source-plone/blob/master/tests/gatsby-starter-default/src/components/Folder.js), where details of it's children are retrieved: + +```graphql +fragment Folder on PloneFolder { + id + title + description + items { + _id + _path + _type + description + title + } + _path +} +``` diff --git a/docs/search_parameters.md b/docs/search_parameters.md deleted file mode 100644 index 048dbcb8..00000000 --- a/docs/search_parameters.md +++ /dev/null @@ -1,13 +0,0 @@ -# Search Parameters - -The @search endpoint allows you to pass query string parameters that filters the returned response based on the parameters rather than giving the whole listing of content objects. This allows the plugin to retrieve contents and Gatsby to build way more efficiently. - -For example: - -```javascript -searchParams: { - SearchableText: 'example', -} -``` - -Searches for 'example' in the Plone site and returns only the relevant objects as response. diff --git a/docs/search_traversal.md b/docs/search_traversal.md deleted file mode 100644 index 2deed5e6..00000000 --- a/docs/search_traversal.md +++ /dev/null @@ -1,78 +0,0 @@ -# Traversal using @search endpoint - -In the [plone.restapi](https://github.com/plone/plone.restapi), the `@search` endpoint when fetched without any query returns the full list of content objects. This is used to pull the whole content tree and create nodes with tree hierarchy. - -The procedure followed for this: - -1. Use the `@search` endpoint to get a flat list of all content objects. - For instance, `https://plonedemo.kitconcept.com/en/@search` gives the response: - -```json -{ - "@id": "https://plonedemo.kitconcept.com/en/@search", - "items": [ - { - "@id": "https://plonedemo.kitconcept.com/en", - "@type": "LRF", - "description": "", - "review_state": "published", - "title": "English" - }, - { - "@id": "https://plonedemo.kitconcept.com/en/frontpage", - "@type": "Document", - "description": "The ultimate Open Source Enterprise CMS", - "review_state": "published", - "title": "Welcome to Plone 5" - }, - { - "@id": "https://plonedemo.kitconcept.com/en/demo/a-page", - "@type": "Document", - "description": "Aenean dictum auctor elit, in volutpat ipsum venenatis at. Quisque lobortis augue et enim venenatis interdum. In egestas, est at condimentum ultrices, tortor enim malesuada nulla; vel sagittis nullam.", - "review_state": "published", - "title": "A Page" - }, - ... -``` - -The `items` is an array of all the content objects. - -2. Using this flat list, iterate through the `@id` attributes making individual requests for each content object to get full data. - From the previous request, we extract the `@id`s forming a list of URLs for each content object: - -``` -https://plonedemo.kitconcept.com/en -https://plonedemo.kitconcept.com/en/frontpage -https://plonedemo.kitconcept.com/en/demo/a-page -... -``` - -Each request will fetch the required data of the content object: - -```json -// https://plonedemo.kitconcept.com/en/demo/a-page -{ - "@components": { - "breadcrumbs": { - "@id": "https://plonedemo.kitconcept.com/en/demo/a-page/@breadcrumbs" - }, - "navigation": { - "@id": "https://plonedemo.kitconcept.com/en/demo/a-page/@navigation" - }, - "workflow": { - "@id": "https://plonedemo.kitconcept.com/en/demo/a-page/@workflow" - } - }, - "@id": "https://plonedemo.kitconcept.com/en/demo/a-page", - "@type": "Document", - "UID": "eb023ac4d6cd4446ae692cdfd5058e91", - "allow_discussion": null, - "changeNote": "", - "contributors": [], - "created": "2015-07-31T15:42:54+02:00", - ... -``` - -3. Spread this data to nodes (making them available for GraphQL requests in Gatsby) - -4. For hierarchy, _Gatsby at node level uses a 'parent' and 'children' property_. From the data retrieved parent will be assigned from `parent` attribute of the object directly, while children is an array of `@id` which is obtained by traversal of `items` attribute of a content object. This is possible considering that `node.id` is the `@id` attribute. diff --git a/docs/tree-hierarchy.md b/docs/tree-hierarchy.md deleted file mode 100644 index f85942d1..00000000 --- a/docs/tree-hierarchy.md +++ /dev/null @@ -1,25 +0,0 @@ -# Tree Hierarchy - -In Gatsby hierarchy between nodes is established using the `parent` and `children` attributes of the node object. These attributes can be assigned with ids establishing the relation. A node can only have one parent and but it's children is an array of nodes. - -A sample for this kind of relationship is illustrated in this [gist](https://gist.github.com/ajayns/53c5cef6b83a7d7f70bb369b58706698) in which basic parent-child hierarchy is established and queried. - -In `tests/gatsby-starter-default` this is illustrated for instance, in the [Folder component](https://github.com/collective/gatsby-source-plone/blob/master/tests/gatsby-starter-default/src/components/Folder.js), where details of it's children are retrieved: - -```graphql -fragment Folder on PloneFolder { - id - title - description - parent { - ...Breadcrumbs - } - children { - ...Document - ...NewsItem - } - fields { - slug - } -} -``` diff --git a/tests/gatsby-starter-default/fixture/.index.json b/tests/gatsby-starter-default/fixture/.index.json index c8c07064..8a2a80bb 100644 --- a/tests/gatsby-starter-default/fixture/.index.json +++ b/tests/gatsby-starter-default/fixture/.index.json @@ -15,6 +15,13 @@ "id": "Plone", "is_folderish": true, "items": [ + { + "@id": "http://localhost:8080/Plone/index", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "gatsby-source-plone" + }, { "@id": "http://localhost:8080/Plone/news", "@type": "Folder", @@ -30,14 +37,21 @@ "title": "Examples" }, { - "@id": "http://localhost:8080/Plone/docs", + "@id": "http://localhost:8080/Plone/tutorial", + "@type": "Folder", + "description": "", + "review_state": "published", + "title": "Tutorial" + }, + { + "@id": "http://localhost:8080/Plone/reference", "@type": "Folder", - "description": "Plugin documentation", + "description": "Reference documentation", "review_state": "published", "title": "Docs" } ], - "items_total": 3, + "items_total": 5, "parent": {}, "title": "Gatsby source plugin for Plone" } diff --git a/tests/gatsby-starter-default/fixture/docs.json b/tests/gatsby-starter-default/fixture/docs.json deleted file mode 100644 index 264c0700..00000000 --- a/tests/gatsby-starter-default/fixture/docs.json +++ /dev/null @@ -1,120 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "UID": "127defba2d7e4227812374308ae16947", - "allow_discussion": false, - "contributors": [], - "created": "2018-07-11T08:03:46+00:00", - "creators": [ - "admin" - ], - "description": "Plugin documentation", - "effective": "2018-06-23T21:22:00", - "exclude_from_nav": false, - "expires": null, - "id": "docs", - "is_folderish": true, - "items": [ - { - "@id": "http://localhost:8080/Plone/docs/index", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "gatsby-source-plone" - }, - { - "@id": "http://localhost:8080/Plone/docs/plugin_options", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Plugin Options" - }, - { - "@id": "http://localhost:8080/Plone/docs/authentication", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Authentication" - }, - { - "@id": "http://localhost:8080/Plone/docs/tree-hierarchy", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Tree Hierarchy" - }, - { - "@id": "http://localhost:8080/Plone/docs/expansions", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Expansions" - }, - { - "@id": "http://localhost:8080/Plone/docs/recursive_traversal", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Traversal using recursion" - }, - { - "@id": "http://localhost:8080/Plone/docs/search_traversal", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Traversal using @search endpoint" - }, - { - "@id": "http://localhost:8080/Plone/docs/search_parameters", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Search Parameters" - }, - { - "@id": "http://localhost:8080/Plone/docs/gatsby_v2", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "Migration to Gatsby v2" - }, - { - "@id": "http://localhost:8080/Plone/docs/file_handling", - "@type": "Document", - "description": "", - "review_state": "published", - "title": "File Handling" - } - ], - "items_total": 10, - "language": "en", - "layout": "listing_view", - "modified": "2018-07-12T12:29:49+00:00", - "nextPreviousEnabled": false, - "parent": { - "@id": "http://localhost:8080/Plone", - "@type": "Plone Site", - "description": "", - "title": "Gatsby source plugin for Plone" - }, - "relatedItems": [], - "review_state": "published", - "rights": null, - "subjects": [], - "title": "Docs", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/authentication.json b/tests/gatsby-starter-default/fixture/docs/authentication.json deleted file mode 100644 index c630a10f..00000000 --- a/tests/gatsby-starter-default/fixture/docs/authentication.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/authentication/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/authentication/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/authentication/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/authentication/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/authentication", - "@type": "Document", - "UID": "d63154b8294a48018b72f4bb454cf3bd", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:51+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "authentication", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:35+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

For Plone sites requiring authentication to use plone.restapi, use the following guide to set up a safe method of authentication using JWT and dotenv configuration.

\n\n
# 1. enter a new bash environment\nbash\n# 2. read username into environment variable\nread -p \"Username: \" USERNAME\n# 3. read password into environment variable without displaying it while typing\nread -sp \"Password: \" PASSWORD\n# 4. request authorization token\ncurl -s -X POST http://localhost:8080/Plone/@login -H 'Accept: application/json' -H 'Content-Type: application/json' --data-raw '{\"login\": \"'\"$USERNAME\"'\", \"password\": \"'\"$PASSWORD\"'\"}'\n# 5. exit bash to forget environment variables\nexit\n
\n\n
{\n  \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI\"\n}\n
\n
// Install dotenv\nyarn install dotenv\n\n\n// In .env in the project folder\nTOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI\n
\n
// Top of your file\nrequire(\"dotenv\").config({\n  path: '.env',\n});\n\n// In plugins list\n{\n  resolve: 'gatsby-source-plone',\n  options: {\n    baseUrl: 'http://localhost:8080/Plone/',\n    token: process.env.TOKEN,\n  },\n}\n
", - "encoding": "utf-8" - }, - "title": "Authentication", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/expansions.json b/tests/gatsby-starter-default/fixture/docs/expansions.json deleted file mode 100644 index 723124c6..00000000 --- a/tests/gatsby-starter-default/fixture/docs/expansions.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/expansions/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/expansions/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/expansions/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/expansions/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/expansions", - "@type": "Document", - "UID": "dc2602f550414063a93a75eed838da08", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:54+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "expansions", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:41+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

According to plone.restapi docs, expansion is a mechanism to embed additional “components”, such as navigation, breadcrumbs, schema, or workflow within the main content response, helping the API consumers to avoid unnecessary requests.

\n

For instance, a normal GET request to http://localhost:8080/Plone would give the following response:

\n
{\n    \"@components\": {\n        \"actions\": {\n            \"@id\": \"http://localhost:8080/Plone/@actions\"\n        },\n        \"breadcrumbs\": {\n            \"@id\": \"http://localhost:8080/Plone/@breadcrumbs\"\n        },\n        \"navigation\": {\n            \"@id\": \"http://localhost:8080/Plone/@navigation\"\n        }\n    },\n    \"@id\": \"http://localhost:8080/Plone\",\n    \"@type\": \"Plone Site\",\n    \"id\": \"Plone\",\n    ...\n
\n

But in the case we need the breadcrumbs, navigation data or so on, we'll need to make more requests to /@breadcrumbs, /@navigation and more depending on the data we need.

\n

Expansions simplifies this process by retrieving all data in a single request as http://localhost:8080/Plone?expand=breadcrumbs,navigation giving the response:

\n
{\n    \"@components\": {\n        \"actions\": {\n            \"@id\": \"http://localhost:8080/Plone/@actions\"\n        },\n        \"breadcrumbs\": {\n            \"@id\": \"http://localhost:8080/Plone/@breadcrumbs\",\n            \"items\": []\n        },\n        \"navigation\": {\n            \"@id\": \"http://localhost:8080/Plone/@navigation\",\n            \"items\": [\n                {\n                    \"@id\": \"http://localhost:8080/Plone\",\n                    \"description\": \"\",\n                    \"title\": \"Home\"\n                },\n                {\n                    \"@id\": \"http://localhost:8080/Plone/news\",\n                    \"description\": \"News on gatsby-source-plone development\",\n                    \"title\": \"News\"\n                },\n                {\n                    \"@id\": \"http://localhost:8080/Plone/index\",\n                    \"description\": \"\",\n                    \"title\": \"gatsby-source-plone\"\n                },\n                {\n                    \"@id\": \"http://localhost:8080/Plone/search_traversal\",\n                    \"description\": \"\",\n                    \"title\": \"Traversal using @search endpoint\"\n                },\n                {\n                    \"@id\": \"http://localhost:8080/Plone/plugin_options\",\n                    \"description\": \"\",\n                    \"title\": \"Plugin Options\"\n                },\n                {\n                    \"@id\": \"http://localhost:8080/Plone/testcases\",\n                    \"description\": \"A folder with different standard content types that Plone supports out of the box\",\n                    \"title\": \"Testcases\"\n                }\n            ]\n        }\n    },\n    \"@id\": \"http://localhost:8080/Plone?expand=breadcrumbs%2Cnavigation\",\n    \"@type\": \"Plone Site\",\n    \"id\": \"Plone\",\n    \"is_folderish\": true,\n    ...\n
", - "encoding": "utf-8" - }, - "title": "Expansions", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/file_handling.json b/tests/gatsby-starter-default/fixture/docs/file_handling.json deleted file mode 100644 index 195dc9cf..00000000 --- a/tests/gatsby-starter-default/fixture/docs/file_handling.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/file_handling/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/file_handling/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/file_handling/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/file_handling/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/file_handling", - "@type": "Document", - "UID": "f1c927527fd441d1b842d1c92a50ead4", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-12T12:29:49+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "file_handling", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:49+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

Gatsby along with the plugin gatsby-source-filesystem and the createRemoteFileNode function it exposes, can be used to pull all types of remote files into the Gatsby cache and use them in the generated Gatsby-site.

\n

For images, another plugin, gatsby-transformer-sharp to handle resizing, cropping, creating responsive images using the Sharp image processing library.

\n

For allowing other types of files to be used in the gatsby-site, gatsby-source-filesystem needs to be configured in the project itself as well, with path configured to a static folder:

\n
// gatsby-config.js\n  {\n      resolve: 'gatsby-source-filesystem',\n      options: {\n        path: `${__dirname}/src/static`,\n      },\n    },\n

This exposes a publicURL field in GraphQL for the file node, which can be used to link to the file node and make it downloadable, as implemented in the example gatsby-site.

", - "encoding": "utf-8" - }, - "title": "File Handling", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/gatsby_v2.json b/tests/gatsby-starter-default/fixture/docs/gatsby_v2.json deleted file mode 100644 index 5d8c49e3..00000000 --- a/tests/gatsby-starter-default/fixture/docs/gatsby_v2.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/gatsby_v2/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/gatsby_v2/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/gatsby_v2/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/gatsby_v2/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/gatsby_v2", - "@type": "Document", - "UID": "2a20954311604ca39744ae2b4532309d", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:04:00+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "gatsby_v2", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:41+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

Currently, the plugin and it's tester project is running on Gatsby v2 Beta.

", - "encoding": "utf-8" - }, - "title": "Migration to Gatsby v2", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/index.json b/tests/gatsby-starter-default/fixture/docs/index.json deleted file mode 100644 index f0641c62..00000000 --- a/tests/gatsby-starter-default/fixture/docs/index.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/index/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/index/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/index/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/index/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/index", - "@type": "Document", - "UID": "c94e377acbac4f05b758737db3219fb7", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:48+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": "2018-06-23T21:23:00", - "exclude_from_nav": false, - "expires": null, - "id": "index", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:33+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

Gatsby is a blazing fast static site generator for React. By using Plone as source, this can be used to generate a static site with PWA features with something equivalent to the click of a button. That’s the essence of the “Big Green Button” proposal, according to Martin Aspeli, who wrote a blog post \"Pete and Andy try Plone 4\":

\n

\"Andy goes to Plone's Deployment control panel. There he finds a Big Green Button.\nHe pushes it and covers his eyes. A minute later, a bunch of static HTML files appear in a directory on the server, covering the Plone site, with basic navigation and a site map. Search is provided via a form that posts to Google for search results on the current site.\"

\n

A gatsby-source plugin pulls the whole content tree from the plone.restapi and makes it available for querying via GraphQL in a hierarchical data structure. The gatsby-plone-starter that uses the plugin to source the data from a Plone site will illustrate all use cases of the plugin in a Gatsby project.

", - "encoding": "utf-8" - }, - "title": "gatsby-source-plone", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/plugin_options.json b/tests/gatsby-starter-default/fixture/docs/plugin_options.json deleted file mode 100644 index bc9f869b..00000000 --- a/tests/gatsby-starter-default/fixture/docs/plugin_options.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/plugin_options/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/plugin_options/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/plugin_options/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/plugin_options/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/plugin_options", - "@type": "Document", - "UID": "d21f81c0b6f44fa487842d03c92a93a7", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:49+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "plugin_options", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:44+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

A sample configuration in gatsby-config.js in your Gatsby project, would look like:

\n
plugins: [\n  {\n    resolve: 'gatsby-source-plone',\n    options: {\n      // The base URL of the Plone site you're using as source\n      baseUrl: 'localhost:8080/Plone',\n\n      // Provide authorization token (not required by default)\n      // process.env.TOKEN is set by .env\n      // Read more about setup in authentication docs\n      token: process.env.TOKEN,\n\n      // Pass search parameters as an object\n      // By default passes no parameters\n      searchParams: {\n        SearchableText: 'tree',\n      },\n\n      // Expands passed components\n      // Accepts components list as an array\n      // Defaults to ['breadcrumbs', 'navigation']\n      expansions: ['breadcrumbs', 'actions'],\n\n      // Show logs of progress as plugin is run\n      // Defaults to false\n      showLogs: true,\n    },\n  },\n],\n
", - "encoding": "utf-8" - }, - "title": "Plugin Options", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/recursive_traversal.json b/tests/gatsby-starter-default/fixture/docs/recursive_traversal.json deleted file mode 100644 index 2f347082..00000000 --- a/tests/gatsby-starter-default/fixture/docs/recursive_traversal.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/recursive_traversal/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/recursive_traversal/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/recursive_traversal/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/recursive_traversal/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/recursive_traversal", - "@type": "Document", - "UID": "d4aa8e5c2b134e019c37c737c2a4e056", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:55+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "recursive_traversal", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:46+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

In the method using @search endpoint for traversal, it's required to first create an array of items, and then data of each item is fetched and further processed step by step to an array of nodes. For small list of items, this may seem efficient or when using search parameters.

\n

So what's preferred in the normal scenario is recursively going through each node's children for traversal. A Breadth-First Search (BFS) was implemented to efficiently traverse through nodes and process them directly.

\n

A basic implementation of the algorithm in JavaScript can be seen below, (as per this answer on Stack Overflow) :

\n
Tree.prototype.traverse = function(callback) {\n  var queue = [this];\n  var n;\n\n  while (queue.length > 0) {\n    n = queue.shift();\n    callback(n.value);\n\n    if (!n.children) {\n      continue;\n    }\n\n    for (var i = 0; i < n.children.length; i++) {\n      queue.push(n.children[i]);\n    }\n  }\n};\n
\n

This was used as the reference, and the basic idea of the BFS algorithm was followed, ie, using the queue data structure to start with the first item, and then consecutively store the children of each processed item, while processing the dequeued element in each iteration of the loop.

", - "encoding": "utf-8" - }, - "title": "Traversal using recursion", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/search_parameters.json b/tests/gatsby-starter-default/fixture/docs/search_parameters.json deleted file mode 100644 index 4981a1b5..00000000 --- a/tests/gatsby-starter-default/fixture/docs/search_parameters.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/search_parameters/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/search_parameters/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/search_parameters/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/search_parameters/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/search_parameters", - "@type": "Document", - "UID": "928dfb7b83e64c1c93474d8a3145b394", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:58+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "search_parameters", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:47+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

The @search endpoint allows you to pass query string parameters that filters the returned response based on the parameters rather than giving the whole listing of content objects. This allows the plugin to retrieve contents and Gatsby to build way more efficiently.

\n

For example:

\n
searchParams: {\n  SearchableText: 'example',\n}\n
\n

Searches for 'example' in the Plone site and returns only the relevant objects as response.

", - "encoding": "utf-8" - }, - "title": "Search Parameters", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/search_traversal.json b/tests/gatsby-starter-default/fixture/docs/search_traversal.json deleted file mode 100644 index fb619977..00000000 --- a/tests/gatsby-starter-default/fixture/docs/search_traversal.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/search_traversal/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/search_traversal/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/search_traversal/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/search_traversal/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/search_traversal", - "@type": "Document", - "UID": "7ec8087c2b4e44acb4d96495db037415", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:57+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "search_traversal", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:30+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

In the plone.restapi, the @search endpoint when fetched without any query returns the full list of content objects. This is used to pull the whole content tree and create nodes with tree hierarchy.

\n

The procedure followed for this:

\n
    \n
  1. Use the @search endpoint to get a flat list of all content objects.\nFor instance, https://plonedemo.kitconcept.com/en/@search gives the response:
  2. \n
\n
{\n    \"@id\": \"https://plonedemo.kitconcept.com/en/@search\",\n    \"items\": [\n        {\n            \"@id\": \"https://plonedemo.kitconcept.com/en\",\n            \"@type\": \"LRF\",\n            \"description\": \"\",\n            \"review_state\": \"published\",\n            \"title\": \"English\"\n        },\n        {\n            \"@id\": \"https://plonedemo.kitconcept.com/en/frontpage\",\n            \"@type\": \"Document\",\n            \"description\": \"The ultimate Open Source Enterprise CMS\",\n            \"review_state\": \"published\",\n            \"title\": \"Welcome to Plone 5\"\n        },\n        {\n            \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page\",\n            \"@type\": \"Document\",\n            \"description\": \"Aenean dictum auctor elit, in volutpat ipsum venenatis at. Quisque lobortis augue et enim venenatis interdum. In egestas, est at condimentum ultrices, tortor enim malesuada nulla; vel sagittis nullam.\",\n            \"review_state\": \"published\",\n            \"title\": \"A Page\"\n        },\n        ...\n
\n

The items is an array of all the content objects.

\n
    \n
  1. Using this flat list, iterate through the @id attributes making individual requests for each content object to get full data.\nFrom the previous request, we extract the @ids forming a list of URLs for each content object:
  2. \n
\n
https://plonedemo.kitconcept.com/en\nhttps://plonedemo.kitconcept.com/en/frontpage\nhttps://plonedemo.kitconcept.com/en/demo/a-page\n...\n

Each request will fetch the required data of the content object:

\n
// https://plonedemo.kitconcept.com/en/demo/a-page\n{\n    \"@components\": {\n        \"breadcrumbs\": {\n            \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page/@breadcrumbs\"\n        },\n        \"navigation\": {\n            \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page/@navigation\"\n        },\n        \"workflow\": {\n            \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page/@workflow\"\n        }\n    },\n    \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page\",\n    \"@type\": \"Document\",\n    \"UID\": \"eb023ac4d6cd4446ae692cdfd5058e91\",\n    \"allow_discussion\": null,\n    \"changeNote\": \"\",\n    \"contributors\": [],\n    \"created\": \"2015-07-31T15:42:54+02:00\",\n    ...\n
\n
    \n
  1. Spread this data to nodes (making them available for GraphQL requests in Gatsby)

    \n
  2. \n
  3. For hierarchy, Gatsby at node level uses a 'parent' and 'children' property. From the data retrieved parent will be assigned from parent attribute of the object directly, while children is an array of @id which is obtained by traversal of items attribute of a content object. This is possible considering that node.id is the @id attribute.

    \n
  4. \n
", - "encoding": "utf-8" - }, - "title": "Traversal using @search endpoint", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/docs/tree-hierarchy.json b/tests/gatsby-starter-default/fixture/docs/tree-hierarchy.json deleted file mode 100644 index 94f3aa75..00000000 --- a/tests/gatsby-starter-default/fixture/docs/tree-hierarchy.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "@components": { - "actions": { - "@id": "http://localhost:8080/Plone/docs/tree-hierarchy/@actions" - }, - "breadcrumbs": { - "@id": "http://localhost:8080/Plone/docs/tree-hierarchy/@breadcrumbs" - }, - "navigation": { - "@id": "http://localhost:8080/Plone/docs/tree-hierarchy/@navigation" - }, - "workflow": { - "@id": "http://localhost:8080/Plone/docs/tree-hierarchy/@workflow" - } - }, - "@id": "http://localhost:8080/Plone/docs/tree-hierarchy", - "@type": "Document", - "UID": "2db7a3b7801c479cbb49797b89d49714", - "allow_discussion": false, - "changeNote": "", - "contributors": [], - "created": "2018-07-11T08:03:52+00:00", - "creators": [ - "admin" - ], - "description": "", - "effective": null, - "exclude_from_nav": false, - "expires": null, - "id": "tree-hierarchy", - "is_folderish": false, - "language": "", - "layout": "document_view", - "modified": "2018-07-12T12:29:38+00:00", - "parent": { - "@id": "http://localhost:8080/Plone/docs", - "@type": "Folder", - "description": "Plugin documentation", - "review_state": "published", - "title": "Docs" - }, - "relatedItems": [], - "review_state": "published", - "rights": "", - "subjects": [], - "table_of_contents": null, - "text": { - "content-type": "text/html", - "data": "

In Gatsby hierarchy between nodes is established using the parent and children attributes of the node object. These attributes can be assigned with ids establishing the relation. A node can only have one parent and but it's children is an array of nodes.

\n

A sample for this kind of relationship is illustrated in this gist in which basic parent-child hierarchy is established and queried.

\n

In tests/gatsby-starter-default this is illustrated for instance, in the Folder component, where details of it's children are retrieved:

\n
fragment Folder on PloneFolder {\n  id\n  title\n  description\n  parent {\n    ...Breadcrumbs\n  }\n  children {\n    ...Document\n    ...NewsItem\n  }\n  fields {\n    slug\n  }\n}\n
", - "encoding": "utf-8" - }, - "title": "Tree Hierarchy", - "version": "current" -} diff --git a/tests/gatsby-starter-default/fixture/examples.json b/tests/gatsby-starter-default/fixture/examples.json index e9b5cf92..6db7d9a1 100644 --- a/tests/gatsby-starter-default/fixture/examples.json +++ b/tests/gatsby-starter-default/fixture/examples.json @@ -15,27 +15,20 @@ }, "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", - "UID": "c70fd016424943e0b37794af62e5e948", + "UID": "52430a578d12481b8557e47c7ef48973", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:16+00:00", + "created": "2018-08-04T19:28:03+00:00", "creators": [ "admin" ], "description": "A folder with different standard content types that Plone supports out of the box", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "examples", "is_folderish": true, "items": [ - { - "@id": "http://localhost:8080/Plone/examples/first-results", - "@type": "News Item", - "description": "The Google Summer of Code project \"Gatsby source plugin for Plone\" is underway!", - "review_state": "published", - "title": "First results" - }, { "@id": "http://localhost:8080/Plone/examples/subfolder-level-two", "@type": "Folder", @@ -78,6 +71,13 @@ "review_state": "published", "title": "A link to the documentation of Plone" }, + { + "@id": "http://localhost:8080/Plone/examples/first-results", + "@type": "News Item", + "description": "The Google Summer of Code project \"Gatsby source plugin for Plone\" is underway!", + "review_state": "published", + "title": "First results" + }, { "@id": "http://localhost:8080/Plone/examples/plone-conference-tokyo", "@type": "Event", @@ -124,7 +124,7 @@ "items_total": 13, "language": "en", "layout": "listing_view", - "modified": "2018-07-12T12:31:27+00:00", + "modified": "2018-08-04T20:25:59+00:00", "nextPreviousEnabled": false, "parent": { "@id": "http://localhost:8080/Plone", diff --git a/tests/gatsby-starter-default/fixture/examples/a-link-to-the-documentation-of-plone.json b/tests/gatsby-starter-default/fixture/examples/a-link-to-the-documentation-of-plone.json index e05558c4..b51828d7 100644 --- a/tests/gatsby-starter-default/fixture/examples/a-link-to-the-documentation-of-plone.json +++ b/tests/gatsby-starter-default/fixture/examples/a-link-to-the-documentation-of-plone.json @@ -15,23 +15,23 @@ }, "@id": "http://localhost:8080/Plone/examples/a-link-to-the-documentation-of-plone", "@type": "Link", - "UID": "92f9f9ff5be1413b9c01a8164f3bd1c0", + "UID": "56408d86fe164506ad2597a1b14af9a0", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-11T08:03:37+00:00", + "created": "2018-08-04T19:28:18+00:00", "creators": [ "admin" ], "description": "Plone contains a special \"link\" content type", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "a-link-to-the-documentation-of-plone", "is_folderish": false, "language": "en", "layout": "link_redirect_view", - "modified": "2018-07-11T08:03:38+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/a-nico-e-pagie.json b/tests/gatsby-starter-default/fixture/examples/a-nico-e-pagie.json index a4b93b3c..7c9ce157 100644 --- a/tests/gatsby-starter-default/fixture/examples/a-nico-e-pagie.json +++ b/tests/gatsby-starter-default/fixture/examples/a-nico-e-pagie.json @@ -15,23 +15,23 @@ }, "@id": "http://localhost:8080/Plone/examples/a-nico-e-pagie", "@type": "Document", - "UID": "90319e90165e45e1bef330593819081d", + "UID": "0e1d2b0970924b62b645644977908c6e", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-11T08:03:39+00:00", + "created": "2018-08-04T19:28:16+00:00", "creators": [ "admin" ], "description": "𝓣ℎι𝓼 𝕚𝑠 𝝉𝐫𝒾𝙘𝗸𝘺", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "a-nico-e-pagie", "is_folderish": false, "language": "en", "layout": "document_view", - "modified": "2018-07-11T08:03:39+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/a-page-with-internal-linking.json b/tests/gatsby-starter-default/fixture/examples/a-page-with-internal-linking.json index f861709c..185a7fb3 100644 --- a/tests/gatsby-starter-default/fixture/examples/a-page-with-internal-linking.json +++ b/tests/gatsby-starter-default/fixture/examples/a-page-with-internal-linking.json @@ -15,23 +15,23 @@ }, "@id": "http://localhost:8080/Plone/examples/a-page-with-internal-linking", "@type": "Document", - "UID": "41acf8d8f75d4443ab6fa54e4938ebdf", + "UID": "374310fbc3ab40b4910f02c3c3b76c7a", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-11T08:03:45+00:00", + "created": "2018-08-04T19:28:15+00:00", "creators": [ "admin" ], "description": "", - "effective": "2018-07-05T06:10:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "a-page-with-internal-linking", "is_folderish": false, "language": "en", "layout": "document_view", - "modified": "2018-07-14T10:25:15+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/event-collection.json b/tests/gatsby-starter-default/fixture/examples/event-collection.json index 8987f9b2..b8013a51 100644 --- a/tests/gatsby-starter-default/fixture/examples/event-collection.json +++ b/tests/gatsby-starter-default/fixture/examples/event-collection.json @@ -15,10 +15,10 @@ }, "@id": "http://localhost:8080/Plone/examples/event-collection", "@type": "Collection", - "UID": "78949b18399f412a974f156513910966", + "UID": "c8ac67109ae04672818504a2de8ab7a3", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:43+00:00", + "created": "2018-08-04T19:28:12+00:00", "creators": [ "admin" ], @@ -29,7 +29,7 @@ "ModificationDate" ], "description": "A common use case for collections is to present upcoming events", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "event-collection", @@ -48,7 +48,7 @@ "language": "en", "layout": "listing_view", "limit": 1000, - "modified": "2018-07-11T08:03:43+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/first-results.json b/tests/gatsby-starter-default/fixture/examples/first-results.json index fd30dec8..f005395f 100644 --- a/tests/gatsby-starter-default/fixture/examples/first-results.json +++ b/tests/gatsby-starter-default/fixture/examples/first-results.json @@ -15,16 +15,16 @@ }, "@id": "http://localhost:8080/Plone/examples/first-results", "@type": "News Item", - "UID": "b3ed701d96db45fbaffd38b90c8bdfe2", + "UID": "b36bcbb727af4376bc0a1f76d71f5485", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-11T08:03:40+00:00", + "created": "2018-08-04T19:28:05+00:00", "creators": [ "admin" ], "description": "The Google Summer of Code project \"Gatsby source plugin for Plone\" is underway!", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "first-results", @@ -77,7 +77,7 @@ "is_folderish": false, "language": "en", "layout": "newsitem_view", - "modified": "2018-07-11T08:03:42+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/midsummer.jpg.json b/tests/gatsby-starter-default/fixture/examples/midsummer.jpg.json index 76f65628..dfed889c 100644 --- a/tests/gatsby-starter-default/fixture/examples/midsummer.jpg.json +++ b/tests/gatsby-starter-default/fixture/examples/midsummer.jpg.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/midsummer.jpg", "@type": "Image", - "UID": "4d323515404a4949b6277883971fc5fd", + "UID": "a0f1a9f8f6224fdf8d986f04140d8e90", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:18+00:00", + "created": "2018-08-04T19:28:26+00:00", "creators": [ "admin" ], "description": null, - "effective": null, + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "midsummer.jpg", @@ -75,7 +75,7 @@ "is_folderish": false, "language": "en", "layout": "image_view", - "modified": "2018-07-14T10:23:41+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/plone-conference-tokyo.json b/tests/gatsby-starter-default/fixture/examples/plone-conference-tokyo.json index 12b482e4..a1cec536 100644 --- a/tests/gatsby-starter-default/fixture/examples/plone-conference-tokyo.json +++ b/tests/gatsby-starter-default/fixture/examples/plone-conference-tokyo.json @@ -15,7 +15,7 @@ }, "@id": "http://localhost:8080/Plone/examples/plone-conference-tokyo", "@type": "Event", - "UID": "c763636c16064263b712fd5aa2291149", + "UID": "6ca80a9b44b44dbc8b5b1583d260f576", "allow_discussion": false, "attendees": [ "everybody" @@ -25,12 +25,12 @@ "contact_name": "Tokyo Plone preparation team", "contact_phone": null, "contributors": [], - "created": "2018-07-11T08:03:22+00:00", + "created": "2018-08-04T19:28:19+00:00", "creators": [ "admin" ], "description": "The worldwide gathering of the Plone family (and friends) will happen in Japan this year.", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "end": "2018-11-11T23:45:00+00:00", "event_url": "https://2018.ploneconf.org/", "exclude_from_nav": false, @@ -40,7 +40,7 @@ "language": "en", "layout": "event_view", "location": "Tokyo", - "modified": "2018-07-11T08:03:22+00:00", + "modified": "2018-08-04T19:44:14+00:00", "open_end": false, "parent": { "@id": "http://localhost:8080/Plone/examples", diff --git a/tests/gatsby-starter-default/fixture/examples/plone-logo-1.svg.json b/tests/gatsby-starter-default/fixture/examples/plone-logo-1.svg.json index 8f7aee68..9571cdac 100644 --- a/tests/gatsby-starter-default/fixture/examples/plone-logo-1.svg.json +++ b/tests/gatsby-starter-default/fixture/examples/plone-logo-1.svg.json @@ -15,28 +15,28 @@ }, "@id": "http://localhost:8080/Plone/examples/plone-logo-1.svg", "@type": "File", - "UID": "7142f7188824459997f7dab397b3706b", + "UID": "dfedaf5a0ae1404cacf48b7b9fa14f34", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:28+00:00", + "created": "2018-08-04T19:28:31+00:00", "creators": [ "admin" ], "description": "", - "effective": null, + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "file": { "content-type": "image/svg+xml", "download": "http://localhost:8080/Plone/examples/plone-logo-1.svg/@@download/file", "filename": "plone-logo.svg", - "size": 3823 + "size": 3775 }, "id": "plone-logo-1.svg", "is_folderish": false, "language": "en", "layout": "file_view", - "modified": "2018-07-11T08:03:29+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/plone-logo-192.png.json b/tests/gatsby-starter-default/fixture/examples/plone-logo-192.png.json index f8667c6d..90a613bc 100644 --- a/tests/gatsby-starter-default/fixture/examples/plone-logo-192.png.json +++ b/tests/gatsby-starter-default/fixture/examples/plone-logo-192.png.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/plone-logo-192.png", "@type": "Image", - "UID": "1528ed9213b04fdb8469f62af50a3832", + "UID": "a731577165b84416b63a6ff495b90beb", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:23+00:00", + "created": "2018-08-04T19:28:21+00:00", "creators": [ "admin" ], "description": "In png format", - "effective": null, + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "plone-logo-192.png", @@ -75,7 +75,7 @@ "is_folderish": false, "language": "en", "layout": "image_view", - "modified": "2018-07-11T08:03:25+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/plone-logo.pdf.json b/tests/gatsby-starter-default/fixture/examples/plone-logo.pdf.json index cf63c492..0271e7ad 100644 --- a/tests/gatsby-starter-default/fixture/examples/plone-logo.pdf.json +++ b/tests/gatsby-starter-default/fixture/examples/plone-logo.pdf.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/plone-logo.pdf", "@type": "File", - "UID": "f23557e6c382483abcea3dd4412129c1", + "UID": "a2b24aa112024cc6b37afdeb1d1cdb86", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:31+00:00", + "created": "2018-08-04T19:28:28+00:00", "creators": [ "admin" ], "description": "", - "effective": null, + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "file": { @@ -36,7 +36,7 @@ "is_folderish": false, "language": "en", "layout": "file_view", - "modified": "2018-07-11T08:03:32+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/plone-logo.svg.json b/tests/gatsby-starter-default/fixture/examples/plone-logo.svg.json index 4de3f771..7a35e58e 100644 --- a/tests/gatsby-starter-default/fixture/examples/plone-logo.svg.json +++ b/tests/gatsby-starter-default/fixture/examples/plone-logo.svg.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/plone-logo.svg", "@type": "Image", - "UID": "ec573ad99a8b44e3b80955db882b553b", + "UID": "c7ef2a57f32348ae802215aa3e1d9e3a", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:26+00:00", + "created": "2018-08-04T19:28:23+00:00", "creators": [ "admin" ], "description": "Scalable vector graphics", - "effective": null, + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "plone-logo.svg", @@ -69,13 +69,13 @@ "width": 64 } }, - "size": 3823, + "size": 3775, "width": -1 }, "is_folderish": false, "language": "en", "layout": "image_view", - "modified": "2018-07-11T08:03:27+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/examples/subfolder-level-two.json b/tests/gatsby-starter-default/fixture/examples/subfolder-level-two.json index bd93ca5f..55e2fa14 100644 --- a/tests/gatsby-starter-default/fixture/examples/subfolder-level-two.json +++ b/tests/gatsby-starter-default/fixture/examples/subfolder-level-two.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/subfolder-level-two", "@type": "Folder", - "UID": "177722ff95d941e892afdd858c219811", + "UID": "182e8f200e4d4661985d29cbefe3f541", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:33+00:00", + "created": "2018-08-04T19:28:07+00:00", "creators": [ "admin" ], "description": "", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "subfolder-level-two", @@ -40,7 +40,7 @@ "items_total": 1, "language": "en", "layout": "listing_view", - "modified": "2018-07-11T08:03:34+00:00", + "modified": "2018-08-04T19:44:14+00:00", "nextPreviousEnabled": false, "parent": { "@id": "http://localhost:8080/Plone/examples", diff --git a/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three.json b/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three.json index 688e537a..49a655bf 100644 --- a/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three.json +++ b/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/subfolder-level-two/level-three", "@type": "Folder", - "UID": "74ba7b9791d24f61b1599e699aa1c6b8", + "UID": "4ae7c98d3e36490d99b63c81af3644c3", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:34+00:00", + "created": "2018-08-04T19:28:09+00:00", "creators": [ "admin" ], "description": "", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "level-three", @@ -40,7 +40,7 @@ "items_total": 1, "language": "en", "layout": "listing_view", - "modified": "2018-07-11T08:03:36+00:00", + "modified": "2018-08-04T19:44:14+00:00", "nextPreviousEnabled": false, "parent": { "@id": "http://localhost:8080/Plone/examples/subfolder-level-two", diff --git a/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three/level-four.json b/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three/level-four.json index c7bc7219..ae509d3d 100644 --- a/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three/level-four.json +++ b/tests/gatsby-starter-default/fixture/examples/subfolder-level-two/level-three/level-four.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/examples/subfolder-level-two/level-three/level-four", "@type": "Folder", - "UID": "457a40ae26b14561909b06224dd98d92", + "UID": "a895a80532ef4e629449f0a4097f7d65", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:36+00:00", + "created": "2018-08-04T19:28:10+00:00", "creators": [ "admin" ], "description": "", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "level-four", @@ -32,7 +32,7 @@ "items_total": 0, "language": "en", "layout": "listing_view", - "modified": "2018-07-11T08:03:36+00:00", + "modified": "2018-08-04T19:44:14+00:00", "nextPreviousEnabled": false, "parent": { "@id": "http://localhost:8080/Plone/examples/subfolder-level-two/level-three", diff --git a/tests/gatsby-starter-default/fixture/examples/the-news-collection.json b/tests/gatsby-starter-default/fixture/examples/the-news-collection.json index f6872e5c..115d90ae 100644 --- a/tests/gatsby-starter-default/fixture/examples/the-news-collection.json +++ b/tests/gatsby-starter-default/fixture/examples/the-news-collection.json @@ -4,24 +4,25 @@ "@id": "http://localhost:8080/Plone/examples/the-news-collection/@actions" }, "breadcrumbs": { - "@id": "http://localhost:8080/Plone/examples/the-news-collection/@breadcrumbs" + "@id": + "http://localhost:8080/Plone/examples/the-news-collection/@breadcrumbs" }, "navigation": { - "@id": "http://localhost:8080/Plone/examples/the-news-collection/@navigation" + "@id": + "http://localhost:8080/Plone/examples/the-news-collection/@navigation" }, "workflow": { - "@id": "http://localhost:8080/Plone/examples/the-news-collection/@workflow" + "@id": + "http://localhost:8080/Plone/examples/the-news-collection/@workflow" } }, "@id": "http://localhost:8080/Plone/examples/the-news-collection", "@type": "Collection", - "UID": "fdcec3323a0841fda64dd07b15759759", + "UID": "cb607b4becab42b1ba0ecd9d65483b74", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:20+00:00", - "creators": [ - "admin" - ], + "created": "2018-08-04T19:28:13+00:00", + "creators": ["admin"], "customViewFields": [ "Title", "Creator", @@ -30,7 +31,7 @@ "Subject" ], "description": "Collection that shows all the news", - "effective": "2018-05-27T13:35:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "the-news-collection", @@ -40,34 +41,38 @@ { "@id": "http://localhost:8080/Plone/examples/first-results", "@type": "News Item", - "description": "The Google Summer of Code project \"Gatsby source plugin for Plone\" is underway!", + "description": + "The Google Summer of Code project \"Gatsby source plugin for Plone\" is underway!", "review_state": "published", "title": "First results" }, { - "@id": "http://localhost:8080/Plone/news/gsoc-gatsby-source-plone", + "@id": "http://localhost:8080/Plone/news/gatsby-plugin-for-plone", "@type": "News Item", - "description": "Ajay NS was selected for Google Summer of Code to work on Plone Foundation project on GatsbyJS integration with Plone", + "description": + "Gatsby is a blazing fast static site generator for React.", "review_state": "published", - "title": "GSOC for Gatsby source for Plone started" + "title": "Let's do a GatsbyJS plugin for Plone!" }, { - "@id": "http://localhost:8080/Plone/news/gatsby-plugin-for-plone", + "@id": "http://localhost:8080/Plone/news/gsoc-gatsby-source-plone", "@type": "News Item", - "description": "Gatsby is a blazing fast static site generator for React.", + "description": + "Ajay NS was selected for Google Summer of Code to work on Plone Foundation project on GatsbyJS integration with Plone", "review_state": "published", - "title": "Let's do a GatsbyJS plugin for Plone!" + "title": "GSOC for Gatsby source for Plone started" } ], "items_total": 3, "language": "en", "layout": "listing_view", "limit": 1000, - "modified": "2018-07-11T08:03:20+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/examples", "@type": "Folder", - "description": "A folder with different standard content types that Plone supports out of the box", + "description": + "A folder with different standard content types that Plone supports out of the box", "review_state": "published", "title": "Examples" }, @@ -75,9 +80,7 @@ { "i": "portal_type", "o": "plone.app.querystring.operation.selection.any", - "v": [ - "News Item" - ] + "v": ["News Item"] } ], "relatedItems": [], @@ -85,13 +88,11 @@ "rights": null, "sort_on": "effective", "sort_reversed": true, - "subjects": [ - "examples", - "collections" - ], + "subjects": ["examples", "collections"], "text": { "content-type": "text/html", - "data": "

Collections are 'virtual folders' that contain content objects based on criteria. Those criteria can be

\n \n

And, of course, you can combine all of them to narrow down your selection.

\n

Richtext

\n

They also come with a richtext introduction, meaning the introduction can contain formatting, links and images

\n

\"A

", + "data": + "

Collections are 'virtual folders' that contain content objects based on criteria. Those criteria can be

\n \n

And, of course, you can combine all of them to narrow down your selection.

\n

Richtext

\n

They also come with a richtext introduction, meaning the introduction can contain formatting, links and images

\n

\"A

", "encoding": "utf-8" }, "title": "The news collection", diff --git a/tests/gatsby-starter-default/fixture/index.json b/tests/gatsby-starter-default/fixture/index.json index 568784e5..4a4430d5 100644 --- a/tests/gatsby-starter-default/fixture/index.json +++ b/tests/gatsby-starter-default/fixture/index.json @@ -15,28 +15,28 @@ }, "@id": "http://localhost:8080/Plone/index", "@type": "Document", - "UID": "c9a5f557e20f4ce78f54348d255190da", + "UID": "ebb2ab19c5204c818a38d572c559e8c2", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-10T06:16:49+00:00", + "created": "2018-08-04T19:37:19+00:00", "creators": [ "admin" ], "description": "", - "effective": null, + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "index", "is_folderish": false, "language": "", "layout": "document_view", - "modified": "2018-07-10T06:16:49+00:00", + "modified": "2018-08-04T21:36:58+00:00", "parent": { "@id": "http://localhost:8080/Plone", "@type": "Plone Site", "description": "", - "title": "Plone site" + "title": "Gatsby source plugin for Plone" }, "relatedItems": [], "review_state": "published", @@ -45,7 +45,7 @@ "table_of_contents": null, "text": { "content-type": "text/html", - "data": "

Gatsby is a blazing fast static site generator for React. By using Plone as source, this can be used to generate a static site with PWA features with something equivalent to the click of a button. That’s the essence of the “Big Green Button” proposal, according to Martin Aspeli, who wrote a blog post \"Pete and Andy try Plone 4\":

\n

\"Andy goes to Plone's Deployment control panel. There he finds a Big Green Button.\nHe pushes it and covers his eyes. A minute later, a bunch of static HTML files appear in a directory on the server, covering the Plone site, with basic navigation and a site map. Search is provided via a form that posts to Google for search results on the current site.\"

\n

A gatsby-source plugin pulls the whole content tree from the plone.restapi and makes it available for querying via GraphQL in a hierarchical data structure. The gatsby-plone-starter that uses the plugin to source the data from a Plone site will illustrate all use cases of the plugin in a Gatsby project.

", + "data": "

GatsbyJS is a generator for blazing fast static web sites or web apps powered by pre-rendered ReactJS. With this plugin, you can build any amount of gatsby sites from a single Plone CMS, the ultimate open source enterprise CMS.

\n

This gatsby-source plugin pulls the whole content tree from a Plone site (or its sub-folder) using Plone REST API and makes it available for querying via GraphQL in a Gatsby based project.

\n

Common use-cases include to

\n\n

No Plone knowledge should be required to use this plugin. Just follow the examples in gatsby-starter-plone and the official Gatsby user documentation.

\n

A Plone add-on collective.webhook can be used to trigger CI pipelines to rebuild and deploy sites after any change in Plone content.

\n

˝Andy goes to Plone’s Deployment control panel. There he finds a Big Green Button.\nHe pushes it and covers his eyes. A minute later, a bunch of static HTML files appear in a directory on the server, covering the Plone site, with basic navigation and a site map. Search is provided via a form that posts to Google for search results on the current site.˝ –Martin Aspeli, 2009, ˝Pete and Andy try Plone 4˝

", "encoding": "utf-8" }, "title": "gatsby-source-plone", diff --git a/tests/gatsby-starter-default/fixture/news.json b/tests/gatsby-starter-default/fixture/news.json index 7c7f8334..f7a2e3b8 100644 --- a/tests/gatsby-starter-default/fixture/news.json +++ b/tests/gatsby-starter-default/fixture/news.json @@ -15,15 +15,15 @@ }, "@id": "http://localhost:8080/Plone/news", "@type": "Folder", - "UID": "f6a1fdbfbbab4f9eb6dcd863bc683d49", + "UID": "72dc357b964547cc9b9dd25bffd3273a", "allow_discussion": false, "contributors": [], - "created": "2018-07-11T08:03:09+00:00", + "created": "2018-08-04T19:27:57+00:00", "creators": [ "admin" ], "description": "News on gatsby-source-plone development", - "effective": "2018-05-24T14:41:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "news", @@ -47,7 +47,7 @@ "items_total": 2, "language": "en", "layout": "listing_view", - "modified": "2018-07-11T08:03:14+00:00", + "modified": "2018-08-04T19:44:14+00:00", "nextPreviousEnabled": false, "parent": { "@id": "http://localhost:8080/Plone", diff --git a/tests/gatsby-starter-default/fixture/news/gatsby-plugin-for-plone.json b/tests/gatsby-starter-default/fixture/news/gatsby-plugin-for-plone.json index daff1d47..8ddedb04 100644 --- a/tests/gatsby-starter-default/fixture/news/gatsby-plugin-for-plone.json +++ b/tests/gatsby-starter-default/fixture/news/gatsby-plugin-for-plone.json @@ -15,16 +15,16 @@ }, "@id": "http://localhost:8080/Plone/news/gatsby-plugin-for-plone", "@type": "News Item", - "UID": "83c4ff9d325248608ed40e1bc03d697d", + "UID": "497bc0b219df43109e608e882ae85962", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-11T08:03:14+00:00", + "created": "2018-08-04T19:28:01+00:00", "creators": [ "admin" ], "description": "Gatsby is a blazing fast static site generator for React.", - "effective": "2017-01-05T00:00:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "gatsby-plugin-for-plone", @@ -77,7 +77,7 @@ "is_folderish": false, "language": "en", "layout": "newsitem_view", - "modified": "2018-07-11T08:03:15+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/news", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/news/gsoc-gatsby-source-plone.json b/tests/gatsby-starter-default/fixture/news/gsoc-gatsby-source-plone.json index 48c6275f..bbc50820 100644 --- a/tests/gatsby-starter-default/fixture/news/gsoc-gatsby-source-plone.json +++ b/tests/gatsby-starter-default/fixture/news/gsoc-gatsby-source-plone.json @@ -15,16 +15,16 @@ }, "@id": "http://localhost:8080/Plone/news/gsoc-gatsby-source-plone", "@type": "News Item", - "UID": "e221222333994bab96e91d1957022561", + "UID": "d182b4a55e31496da01799cf7f7dc448", "allow_discussion": false, "changeNote": "", "contributors": [], - "created": "2018-07-11T08:03:11+00:00", + "created": "2018-08-04T19:27:58+00:00", "creators": [ "admin" ], "description": "Ajay NS was selected for Google Summer of Code to work on Plone Foundation project on GatsbyJS integration with Plone", - "effective": "2018-05-14T00:00:00", + "effective": "2018-08-04T00:00:00", "exclude_from_nav": false, "expires": null, "id": "gsoc-gatsby-source-plone", @@ -77,7 +77,7 @@ "is_folderish": false, "language": "en", "layout": "newsitem_view", - "modified": "2018-07-11T08:03:12+00:00", + "modified": "2018-08-04T19:44:14+00:00", "parent": { "@id": "http://localhost:8080/Plone/news", "@type": "Folder", diff --git a/tests/gatsby-starter-default/fixture/reference.json b/tests/gatsby-starter-default/fixture/reference.json new file mode 100644 index 00000000..f54df672 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference.json @@ -0,0 +1,106 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "UID": "21c9a68466df415c990bb33934d07255", + "allow_discussion": false, + "contributors": [], + "created": "2018-08-04T19:37:19+00:00", + "creators": [ + "admin" + ], + "description": "Reference documentation", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "reference", + "is_folderish": true, + "items": [ + { + "@id": "http://localhost:8080/Plone/reference/plugin_options", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Plugin Options" + }, + { + "@id": "http://localhost:8080/Plone/reference/authentication", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Authenticating REST API calls" + }, + { + "@id": "http://localhost:8080/Plone/reference/file_handling", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "File and image field support" + }, + { + "@id": "http://localhost:8080/Plone/reference/html_parsing", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "RichText field support" + }, + { + "@id": "http://localhost:8080/Plone/reference/expansions", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Supported REST API expansions" + }, + { + "@id": "http://localhost:8080/Plone/reference/search_parameters", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Customizing search Parameters" + }, + { + "@id": "http://localhost:8080/Plone/reference/search_traversal", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "How plugin uses @search endpoint" + }, + { + "@id": "http://localhost:8080/Plone/reference/tree-hierarchy", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "How content hierarchy is mapped" + } + ], + "items_total": 8, + "language": "en", + "layout": "listing_view", + "modified": "2018-08-04T21:17:48+00:00", + "nextPreviousEnabled": false, + "parent": { + "@id": "http://localhost:8080/Plone", + "@type": "Plone Site", + "description": "", + "title": "Gatsby source plugin for Plone" + }, + "relatedItems": [], + "review_state": "published", + "rights": null, + "subjects": [], + "title": "Docs", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/authentication.json b/tests/gatsby-starter-default/fixture/reference/authentication.json new file mode 100644 index 00000000..776b5def --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/authentication.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/authentication/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/authentication/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/authentication/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/authentication/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/authentication", + "@type": "Document", + "UID": "56f9c153d19f4abcb6bb929f0f14c843", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:20+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "authentication", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:15:57+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

For Plone sites requiring authentication to use Plone REST API (or limiting publishable content by permissions of specific user) you may use this guide to set up a safe method of authentication using JWT and dotenv configuration.

\n

Note: In time of writing, Plone REST API only created tokens valid for the next 12 hours.

\n

In UNIX-like systems (OSX, Linux, Linux subsystem for Windows), a bash script would serve as a good way to retrieve the JWT from plone.restapi, by prompting for username and password:

\n
bash\nread -p \"Username: \" USERNAME\nread -sp \"Password: \" PASSWORD\ncurl -s -X POST http://localhost:8080/Plone/@login -H 'Accept: application/json' -H 'Content-Type: application/json' --data-raw '{\"login\": \"'\"$USERNAME\"'\", \"password\": \"'\"$PASSWORD\"'\"}'\nexit\n
\n

The above script will

\n
    \n
  1. enter a new bash environment
  2. \n
  3. read username into environment variable
  4. \n
  5. read password into environment variable without displaying it when you type
  6. \n
  7. request authorization token
  8. \n
  9. exit bash to forget environment variables.
  10. \n
\n

This would give you a token as output:

\n
{\n  \"token\": \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI\"\n}\n
\n

Install dotenv and setup .env with the token so that it can be used in the Gatsby project:

\n
// Install dotenv\nyarn install dotenv\n\n\n// In .env in the project folder\nTOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmdWxsbmFtZSI6IkpvaG4gRG9lIiwic3ViIjoidXNlcm5hbWUiLCJleHAiOjE1Mjc0NDk0NTl9.epewKm09S6JXe07Ha6UNicN7v9MT32Rrkflxq2OqVRI\n
\n

Finally setup gatsby-config.js to use this in your project:

\n
// Top of your file\nrequire(\"dotenv\").config({\n  path: '.env',\n});\n\n// In plugins list\nmodule.exports = {\n  resolve: 'gatsby-source-plone',\n    options: {\n    baseUrl: 'http://localhost:8080/Plone/',\n    token: process.env.TOKEN,\n  }\n};\n
", + "encoding": "utf-8" + }, + "title": "Authenticating REST API calls", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/expansions.json b/tests/gatsby-starter-default/fixture/reference/expansions.json new file mode 100644 index 00000000..8320f8cb --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/expansions.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/expansions/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/expansions/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/expansions/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/expansions/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/expansions", + "@type": "Document", + "UID": "243bf4f2e50c4ac4a2ee287ac87003a8", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:22+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "expansions", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:16:00+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

This source plugin only supports fixed set of Plone REST API expansions, currently breadcrumbs and navigation, which are both published as their own GraphQL nodes, PloneBreadcrumbs and PloneNavigation respectively.

\n

Expansions are plone.restapi mechanism to embed additional “components”, such as navigation, breadcrumbs, schema, or workflow within the main content response, helping the API consumers to avoid unnecessary requests.

\n

For instance, a normal GET request to http://localhost:8080/Plone would give the following response:

\n
{\n  \"@components\": {\n    \"actions\": {\n      \"@id\": \"http://localhost:8080/Plone/@actions\"\n    },\n    \"breadcrumbs\": {\n      \"@id\": \"http://localhost:8080/Plone/@breadcrumbs\"\n    },\n    \"navigation\": {\n      \"@id\": \"http://localhost:8080/Plone/@navigation\"\n    }\n  },\n  \"@id\": \"http://localhost:8080/Plone\",\n  \"@type\": \"Plone Site\",\n  \"id\": \"Plone\",\n  \"...\": \"...\"\n}\n
\n

But in the case we need the breadcrumbs, navigation data or so on, we'll need to make more requests to /@breadcrumbs, /@navigation and more depending on the data we need.

\n

Expansions simplifies this process by retrieving all data in a single request as http://localhost:8080/Plone?expand=breadcrumbs,navigation giving the response:

\n
{\n  \"@components\": {\n    \"actions\": {\n      \"@id\": \"http://localhost:8080/Plone/@actions\"\n    },\n    \"breadcrumbs\": {\n      \"@id\": \"http://localhost:8080/Plone/@breadcrumbs\",\n      \"items\": []\n    },\n    \"navigation\": {\n      \"@id\": \"http://localhost:8080/Plone/@navigation\",\n      \"items\": [\n        {\n          \"@id\": \"http://localhost:8080/Plone\",\n          \"description\": \"\",\n          \"title\": \"Home\"\n        },\n        {\n          \"@id\": \"http://localhost:8080/Plone/news\",\n          \"description\": \"News on gatsby-source-plone development\",\n          \"title\": \"News\"\n        },\n        {\n          \"@id\": \"http://localhost:8080/Plone/index\",\n          \"description\": \"\",\n          \"title\": \"gatsby-source-plone\"\n        },\n        {\n          \"@id\": \"http://localhost:8080/Plone/search_traversal\",\n          \"description\": \"\",\n          \"title\": \"Traversal using @search endpoint\"\n        },\n        {\n          \"@id\": \"http://localhost:8080/Plone/plugin_options\",\n          \"description\": \"\",\n          \"title\": \"Plugin Options\"\n        },\n        {\n          \"@id\": \"http://localhost:8080/Plone/testcases\",\n          \"description\": \"A folder with different standard content types that Plone supports out of the box\",\n          \"title\": \"Testcases\"\n        }\n      ]\n    }\n  },\n  \"@id\": \"http://localhost:8080/Plone?expand=breadcrumbs%2Cnavigation\",\n  \"@type\": \"Plone Site\",\n  \"id\": \"Plone\",\n  \"is_folderish\": true,\n  \"...\": \"...\"\n}\n
", + "encoding": "utf-8" + }, + "title": "Supported REST API expansions", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/file_handling.json b/tests/gatsby-starter-default/fixture/reference/file_handling.json new file mode 100644 index 00000000..69f81be8 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/file_handling.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/file_handling/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/file_handling/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/file_handling/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/file_handling/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/file_handling", + "@type": "Document", + "UID": "9b4db4718d404a99847e16c7e9234665", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:24+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "file_handling", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:15:52+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

Note: In time of writing, this plugin only supported file fields named file and image fields named image.

\n

Gatsby along with the plugin gatsby-source-filesystem and the createRemoteFileNode function it exposes, can be used to pull all types of remote files into the Gatsby cache and use them in the generated Gatsby-site.

\n

For images, another plugin, gatsby-transformer-sharp to handle resizing, cropping, creating responsive images using the Sharp image processing library.

\n

For allowing other types of files to be used in the gatsby-site, gatsby-source-filesystem needs to be configured in the project itself as well, with path configured to a static folder:

\n
// gatsby-config.js\nmodule.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-source-filesystem',\n      options: {\n        path: `${__dirname}/src/static`,\n      },\n    },\n  ]\n}\n
\n

This exposes a publicURL field in GraphQL for the file node, which can be used to link to the file node and make it downloadable, as implemented in the example gatsby-site.

", + "encoding": "utf-8" + }, + "title": "File and image field support", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/html_parsing.json b/tests/gatsby-starter-default/fixture/reference/html_parsing.json new file mode 100644 index 00000000..83b0ae88 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/html_parsing.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/html_parsing/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/html_parsing/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/html_parsing/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/html_parsing/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/html_parsing", + "@type": "Document", + "UID": "52b115d58e934d3ab92b3a1496d78c17", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:26+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "html_parsing", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:15:55+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

Note: In time of writing, this plugin only supported RichText fields named text.

\n

HTML content from the plone.restapi is returned as string of HTML. Using a combination of react-html-parser and react-serialize, this HTML content is processed into React nodes.

\n

RichText Component

\n

It deserializes the React nodes field which was processed by the plugin to be used in the component and also handles images, files and relative links. Using backlinks, images and files are queried separately and passed into the RichText componoent and it replaces the img and a tags with updated data, in the case of relative links, it even replaces it with Img or Link tags respectively.

\n

Parsing process

\n

react-html-parser is used to parse the HTML string into React nodes, it is then serialized by react-serialize so that it can be passed into and retrieved via GraphQL queries. In this process of parsing, backlinks and relative links are configured, and in the gatsby-site, RichText component is used to handle deserialization and displaying images, files and so on.

\n

Backlinks

\n

Backlinks provide an optimized way to get the relevant images and files for a certain component. It's basically an object with stores a list of nodes to which a certain file/image is relevant to. This eliminates the need for iterating every single image and file to replace the a or img tag with.

\n

Taking the case of the tests/gatsby-starter-default:

\n", + "encoding": "utf-8" + }, + "title": "RichText field support", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/plugin_options.json b/tests/gatsby-starter-default/fixture/reference/plugin_options.json new file mode 100644 index 00000000..9f2f3032 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/plugin_options.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/plugin_options/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/plugin_options/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/plugin_options/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/plugin_options/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/plugin_options", + "@type": "Document", + "UID": "b13dace696f64ea88e46a07a70c7eae4", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:28+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "plugin_options", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:15:47+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

A sample configuration in gatsby-config.js in your Gatsby project, could look like:

\n
module.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-source-plone',\n      options: {\n        // The base URL of the Plone site you're using as source\n        baseUrl: 'http:///localhost:8080/Plone',\n\n        // Provide authorization token (not required by default)\n        // process.env.TOKEN is set by .env\n        // Read more about setup in authentication docs\n        token: process.env.TOKEN,\n\n        // Pass search parameters as an object\n        // By default passes no parameters\n        searchParams: {\n          review_state: 'published',\n        },\n\n        // Show logs of progress as plugin is run\n        // Defaults to no logging by plugin at all \n        logLevel: 'INFO',\n      },\n    },\n  ]\n};\n
", + "encoding": "utf-8" + }, + "title": "Plugin Options", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/search_parameters.json b/tests/gatsby-starter-default/fixture/reference/search_parameters.json new file mode 100644 index 00000000..2447bcbc --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/search_parameters.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/search_parameters/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/search_parameters/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/search_parameters/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/search_parameters/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/search_parameters", + "@type": "Document", + "UID": "11a42779cab1464a85a2b8820c6b59ed", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:30+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "search_parameters", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:18:13+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

Plone REST API @search endpoint allows you to pass query string parameters that filters the returned response based on the parameters rather than giving the whole listing of content objects.

\n

For example

\n
module.exports = {\n  plugins: [\n    {\n      resolve: 'gatsby-source-plone',\n      options: {\n        SearchableText: 'example',\n      },\n    }\n  ]\n}\n
\n

searches for 'example' in the Plone site and returns only the relevant objects as response.

", + "encoding": "utf-8" + }, + "title": "Customizing search Parameters", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/search_traversal.json b/tests/gatsby-starter-default/fixture/reference/search_traversal.json new file mode 100644 index 00000000..dc1f3d0e --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/search_traversal.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/search_traversal/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/search_traversal/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/search_traversal/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/search_traversal/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/search_traversal", + "@type": "Document", + "UID": "56e902defe054aa187cb2ad13d79edd8", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:32+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "search_traversal", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:18:16+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

In the plone.restapi, the @search endpoint when fetched without any query returns the full list of content objects. This is used to pull the whole content tree and create nodes with tree hierarchy.

\n

The procedure followed for this:

\n

At first, this plugin uses @search endpoint to get a flat list of all content objects.

\n

For instance, https://plonedemo.kitconcept.com/en/@search gives the response:

\n
{\n  \"@id\": \"https://plonedemo.kitconcept.com/en/@search\",\n  \"items\": [\n    {\n      \"@id\": \"https://plonedemo.kitconcept.com/en\",\n      \"@type\": \"LRF\",\n      \"description\": \"\",\n      \"review_state\": \"published\",\n      \"title\": \"English\"\n    },\n    {\n      \"@id\": \"https://plonedemo.kitconcept.com/en/frontpage\",\n      \"@type\": \"Document\",\n      \"description\": \"The ultimate Open Source Enterprise CMS\",\n      \"review_state\": \"published\",\n      \"title\": \"Welcome to Plone 5\"\n    },\n    {\n      \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page\",\n      \"@type\": \"Document\",\n      \"description\": \"Aenean dictum auctor elit, in volutpat ipsum venenatis at. Quisque lobortis augue et enim venenatis interdum. In egestas, est at condimentum ultrices, tortor enim malesuada nulla; vel sagittis nullam.\",\n      \"review_state\": \"published\",\n      \"title\": \"A Page\"\n    }\n ]\n}\n
\n

The items is an array of all the content objects.

\n

Next, using this flat list, plugin iterates through the @id attributes making individual requests for each content object to get full data.

\n

From the previous request, plugin extracts the @ids forming a list of URLs for each content object:

\n
https://plonedemo.kitconcept.com/en\nhttps://plonedemo.kitconcept.com/en/frontpage\nhttps://plonedemo.kitconcept.com/en/demo/a-page\n...\n

Each request will fetch the required data of the content object:

\n
{\n  \"@components\": {\n    \"breadcrumbs\": {\n      \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page/@breadcrumbs\"\n    },\n    \"navigation\": {\n      \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page/@navigation\"\n    },\n    \"workflow\": {\n      \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page/@workflow\"\n    }\n  },\n  \"@id\": \"https://plonedemo.kitconcept.com/en/demo/a-page\",\n  \"@type\": \"Document\",\n  \"UID\": \"eb023ac4d6cd4446ae692cdfd5058e91\",\n  \"allow_discussion\": null,\n  \"changeNote\": \"\",\n  \"contributors\": [],\n  \"created\": \"2015-07-31T15:42:54+02:00\",\n  \"...\": \"...\"\n}\n
\n

Then this plugin spreads this data to nodes (making them available for GraphQL requests in Gatsby).

", + "encoding": "utf-8" + }, + "title": "How plugin uses @search endpoint", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/reference/tree-hierarchy.json b/tests/gatsby-starter-default/fixture/reference/tree-hierarchy.json new file mode 100644 index 00000000..d9d4591b --- /dev/null +++ b/tests/gatsby-starter-default/fixture/reference/tree-hierarchy.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/reference/tree-hierarchy/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/reference/tree-hierarchy/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/reference/tree-hierarchy/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/reference/tree-hierarchy/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/reference/tree-hierarchy", + "@type": "Document", + "UID": "38b038805d444a10a00e58a851d997d1", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:34+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "tree-hierarchy", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T21:18:16+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/reference", + "@type": "Folder", + "description": "Reference documentation", + "review_state": "published", + "title": "Docs" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

This plugin does not expose Plone content hierarchy in Gatsby GraphQL queries directly. Instead each node will contain a special attribute _path describing the position of node in content hierarchy. Container nodes will contain _path attribute also for each item in its items attribute returned by Plone REST API.

\n

In tests/gatsby-starter-default this is illustrated for instance, in the Folder component, where details of it's children are retrieved:

\n
fragment Folder on PloneFolder {\n  id\n  title\n  description\n  items {\n    _id\n    _path\n    _type\n    description\n    title\n  }\n  _path\n}\n
", + "encoding": "utf-8" + }, + "title": "How content hierarchy is mapped", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/tutorial.json b/tests/gatsby-starter-default/fixture/tutorial.json new file mode 100644 index 00000000..7b9cad46 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/tutorial.json @@ -0,0 +1,78 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/tutorial/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/tutorial/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/tutorial/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/tutorial/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/tutorial", + "@type": "Folder", + "UID": "a016c40b4475473299bb6367f4b2aedc", + "allow_discussion": false, + "contributors": [], + "created": "2018-08-04T19:37:10+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "tutorial", + "is_folderish": true, + "items": [ + { + "@id": "http://localhost:8080/Plone/tutorial/1_getting_started", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Getting Started" + }, + { + "@id": "http://localhost:8080/Plone/tutorial/2_querying_and_auth", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Querying Data with GraphQL" + }, + { + "@id": "http://localhost:8080/Plone/tutorial/3_page_creation", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Page Creation" + }, + { + "@id": "http://localhost:8080/Plone/tutorial/4_handling_data_types", + "@type": "Document", + "description": "", + "review_state": "published", + "title": "Handling different data types" + } + ], + "items_total": 4, + "language": "", + "layout": "listing_view", + "modified": "2018-08-04T20:26:22+00:00", + "nextPreviousEnabled": false, + "parent": { + "@id": "http://localhost:8080/Plone", + "@type": "Plone Site", + "description": "", + "title": "Gatsby source plugin for Plone" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "title": "Tutorial", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/tutorial/1_getting_started.json b/tests/gatsby-starter-default/fixture/tutorial/1_getting_started.json new file mode 100644 index 00000000..8d2ead9f --- /dev/null +++ b/tests/gatsby-starter-default/fixture/tutorial/1_getting_started.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/tutorial/1_getting_started/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/tutorial/1_getting_started/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/tutorial/1_getting_started/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/tutorial/1_getting_started/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/tutorial/1_getting_started", + "@type": "Document", + "UID": "223c18f83c9247c3a2a6dfc8ca290258", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:12+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "1_getting_started", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T19:44:14+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/tutorial", + "@type": "Folder", + "description": "", + "review_state": "published", + "title": "Tutorial" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

Introduction

\n

We hope you've gone through the Gatsby documention and know what it's all about. Also, our docs cover what's the real purpose of this plugin and its use case.

\n

gatsby-starter-plone is a starter for Gatsby sites with Plone already setup with all the features, and so this tutorial guides you how to work your way from gatsby-starter-default, adding gatsby-source-plone and implementing features one by one to get gatsby-starter-plone as the end product.\nThis way the tutorial covers how to generate a static site from a Plone site using gatsby-source-plone.

\n

Setting up

\n

Make sure you have Gatsby CLI installed globally, get started with gatsby-starter-default and add gatsby-source-plone with basic configuration:

\n
gatsby new gatsby-starter-plone\nyarn add gatsby-source-plone\n
\n

In gatsby-starter-plone/gatsby-config.js add:

\n
 plugins: [\n    {\n      resolve: 'gatsby-source-plone',\n      options: {\n        // Url of Plone site to use as source\n        baseUrl: '<site-url-here>',\n        // Show logs while processing nodes\n        showLogs: true,\n      },\n    },\n  ],\n
\n

Configuring gatsby-config.js is covered in detail in the plugin options docs. Furthermore if your site is protected, go through the authentication docs to learn how to setup access with JWT.

", + "encoding": "utf-8" + }, + "title": "Getting Started", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/tutorial/2_querying_and_auth.json b/tests/gatsby-starter-default/fixture/tutorial/2_querying_and_auth.json new file mode 100644 index 00000000..2ed1c12b --- /dev/null +++ b/tests/gatsby-starter-default/fixture/tutorial/2_querying_and_auth.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/tutorial/2_querying_and_auth/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/tutorial/2_querying_and_auth/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/tutorial/2_querying_and_auth/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/tutorial/2_querying_and_auth/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/tutorial/2_querying_and_auth", + "@type": "Document", + "UID": "cac50f8560c94d5a8eabebd14df023c0", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:14+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "2_querying_and_auth", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T19:44:14+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/tutorial", + "@type": "Folder", + "description": "", + "review_state": "published", + "title": "Tutorial" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

Once you've got the gatsby project setup with gatsby-source-plone, running gatsby develop, although we haven't updated the site itself, the data sourced by the plugin will be available in GraphiQL.

\n

Go to http://localhost:8000/___graphql, and in the query:

\n
{\n  allPloneDocument {\n    edges {\n      node {\n        title\n      }\n    }\n  }\n}\n
\n

This would give you a list of titles of all the objects of type Document in the Plone site (PloneDocument in the gatsby project) in the form:

\n
{\n  \"data\": {\n    \"allPloneDocument\": {\n      \"edges\": [\n        {\n          \"node\": {\n            \"title\": \"A page\"\n          }\n        },\n        {\n          \"node\": {\n            \"title\": \"Another page\"\n          }\n        },\n      ...\n
\n

Displaying queried data in site

\n

In our Gatsby site's index page, let's display a document. Here we have a document frontpage which has the information to be displayed at root.

\n

To get the data via GraphQL:

\n
query IndexPageQuery {\n  ploneDocument(_path: { eq: \"/frontpage/\" }) {\n    title\n    description\n  }\n}\n
\n

Displaying this data retrieved in the page:

\n
const IndexPage = ({ data }) => (\n  <Layout>\n    <article>\n      <h1>{data.ploneDocument.title}</h1>\n      <p>{data.ploneDocument.description}</p>\n    </article>\n  </Layout>\n);\n
\n

Simple as that, we've got the index page to display content of a document sourced from our Plone site.

\n

Authentication

\n

Directly sourcing data from the Plone site and getting all the objects would only work on Plone sites with anonymous access enabled, often it's the case we may need to authorize the plugin with JWT token before we're able to use it.

\n

Step by step explanation on how to set this up is given in the authentication docs.

", + "encoding": "utf-8" + }, + "title": "Querying Data with GraphQL", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/tutorial/3_page_creation.json b/tests/gatsby-starter-default/fixture/tutorial/3_page_creation.json new file mode 100644 index 00000000..b4425717 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/tutorial/3_page_creation.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/tutorial/3_page_creation/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/tutorial/3_page_creation/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/tutorial/3_page_creation/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/tutorial/3_page_creation/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/tutorial/3_page_creation", + "@type": "Document", + "UID": "ffc811f7206248378178b1f5624cca4b", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:17+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "3_page_creation", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T19:44:14+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/tutorial", + "@type": "Folder", + "description": "", + "review_state": "published", + "title": "Tutorial" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

After gatsby-source-plone has retrieved all the data and created nodes, these nodes can be used to create pages. For more detail information on page creation, visit the Gatsby docs.

\n

So let's start by creating pages for each PloneFolder:

\n
const path = require('path');\n\nexports.createPages = async ({ graphql, actions }) => {\n  const { createPage } = actions;\n\n  // Get data via GraphQL\n  const result = await graphql(`\n    {\n      allPloneFolder {\n        edges {\n          node {\n            _path\n          }\n        }\n      }\n    }\n  `);\n\n  // Create pages for each PloneFolder item\n  result.data.allPloneFolder.edges.forEach(({ node }) => {\n    createPage({\n      path: node._path,\n      component: path.resolve('./src/templates/default.js'),\n    });\n  });\n};\n
\n

Once we've got pages created for each of the, we need to display them in our Gatsby site. For this we have to work on the default.js template we previously mentioned:

\n
const DefaultLayout = ({ data }) => (\n  <Layout>\n    {data && data.ploneFolder && <Folder data={data.ploneFolder} />}\n  </Layout>\n);\n\nexport const query = graphql`\n  query DefaultTemplateQuery($path: String!) {\n    ploneFolder(_path: { eq: $path }) {\n      ...Folder\n    }\n  }\n`;\n
\n

Folder component displays the relevant information for an object of type PloneFolder:

\n
const Folder = ({ data, title }) => (\n  <nav key={data._id}>\n    <h1>{title ? title : data.title}</h1>\n    <p>\n      <strong>{data.description}</strong>\n    </p>\n    <ul className=\"list-group\">\n      {data.items.filter(item => item.title).map(item => (\n        <li key={item._path} className=\"list-group-item\">\n          <p>\n            <Link to={item._path}>{item.title}</Link>\n          </p>\n          {item.description && <p>{item.description}</p>}\n        </li>\n      ))}\n    </ul>\n  </nav>\n);\n\nexport default Folder;\n\nexport const query = graphql`\n  fragment Folder on PloneFolder {\n    id\n    title\n    description\n    items {\n      _id\n      _path\n      _type\n      description\n      title\n    }\n    _path\n  }\n`;\n
\n

Contents inside a node can be retrieved by using the items property, which includes the list of children, irrespective of type. So here, all the children of folders are retrieved and displayed as links.

\n

Note: Items in a folder includes all types of Plone content objects, and cause we don't have components for other types such as Document or NewsItem and so on yet, these links would direct to the 404 page, and this is expected. The next part of the tutorial covers page creation of each object and handling them.

\n

To see it in action, go to /demo or any existing folder path and it's details and contents displayed.

\n

Displaying Plone site contents at homepage

\n

To actually view the pages we've created in the gatsby-site, let's display the contents of the Plone site on the homepage:

\n
const IndexPage = ({ data }) => (\n  <Layout>\n    <article>\n      <h1>{data.ploneDocument.title}</h1>\n      <p>{data.ploneDocument.description}</p>\n    </article>\n    <Folder data={data.ploneSite} title=\"Contents\" />\n  </Layout>\n);\n\nexport const query = graphql`\n  query IndexPageQuery {\n    ploneDocument(_path: { eq: \"/frontpage/\" }) {\n      id\n      title\n      description\n    }\n    ploneSite(_path: { eq: \"/\" }) {\n      ...Site\n    }\n  }\n`;\n
\n

Site is a fragment defined in the Folder component to display items in the Plone Site (root or baseUrl):

\n
fragment Site on PloneSite {\n  id\n  title\n  items {\n    _id\n    _path\n    _type\n    description\n    title\n  }\n  _path\n}\n
", + "encoding": "utf-8" + }, + "title": "Page Creation", + "version": "current" +} diff --git a/tests/gatsby-starter-default/fixture/tutorial/4_handling_data_types.json b/tests/gatsby-starter-default/fixture/tutorial/4_handling_data_types.json new file mode 100644 index 00000000..1234d3c7 --- /dev/null +++ b/tests/gatsby-starter-default/fixture/tutorial/4_handling_data_types.json @@ -0,0 +1,54 @@ +{ + "@components": { + "actions": { + "@id": "http://localhost:8080/Plone/tutorial/4_handling_data_types/@actions" + }, + "breadcrumbs": { + "@id": "http://localhost:8080/Plone/tutorial/4_handling_data_types/@breadcrumbs" + }, + "navigation": { + "@id": "http://localhost:8080/Plone/tutorial/4_handling_data_types/@navigation" + }, + "workflow": { + "@id": "http://localhost:8080/Plone/tutorial/4_handling_data_types/@workflow" + } + }, + "@id": "http://localhost:8080/Plone/tutorial/4_handling_data_types", + "@type": "Document", + "UID": "677fddb95c4a44b2b4f8b1de2d8088fe", + "allow_discussion": false, + "changeNote": "", + "contributors": [], + "created": "2018-08-04T19:37:15+00:00", + "creators": [ + "admin" + ], + "description": "", + "effective": "2018-08-04T00:00:00", + "exclude_from_nav": false, + "expires": null, + "id": "4_handling_data_types", + "is_folderish": false, + "language": "", + "layout": "document_view", + "modified": "2018-08-04T19:44:14+00:00", + "parent": { + "@id": "http://localhost:8080/Plone/tutorial", + "@type": "Folder", + "description": "", + "review_state": "published", + "title": "Tutorial" + }, + "relatedItems": [], + "review_state": "published", + "rights": "", + "subjects": [], + "table_of_contents": null, + "text": { + "content-type": "text/html", + "data": "

Plone has a couple of native content object types and even custom ones. For these, we need to create separate components for each, and configure gatsby-node.js to create individual pages and display the content in a gatsby site.

\n

Firstly step would be creating pages for each of these objects:

\n
// gatsby-node.js\nexports.createPages = async ({ graphql, actions }) => {\n  const { createPage } = actions;\n  const result = await graphql(`\n    {\n      allPloneCollection {\n        edges {\n          node {\n            _path\n          }\n        }\n      }\n      allPloneDocument {\n        edges {\n          node {\n            _path\n          }\n        }\n      }\n      allPloneEvent {\n        edges {\n          node {\n            _path\n          }\n        }\n      }\n      allPloneFolder {\n        edges {\n          node {\n            _path\n          }\n        }\n      }\n      allPloneNewsItem {\n        edges {\n          node {\n            _path\n          }\n        }\n      }\n    }\n  `);\n  []\n    .concat(\n      result.data.allPloneCollection.edges,\n      result.data.allPloneDocument.edges,\n      result.data.allPloneEvent.edges,\n      result.data.allPloneFolder.edges,\n      result.data.allPloneNewsItem.edges\n    )\n    .forEach(({ node }) => {\n      createPage({\n        path: node._path,\n        component: path.resolve('./src/templates/default.js'),\n      });\n    });\n};\n
\n

Before we just handled folders, now we query for each of the content object types and create pages for them. The next step would be to configure the default template to handle the data depending on type since we're using it commonly for all of the types.

\n
// src/templates/default.js\n\n\n// Function to return relevant component as per content object type\nconst componentFor = data => {\n  if (data) {\n    if (data.ploneCollection) {\n      return (\n        <Folder\n          data={data.ploneCollection}\n        />\n      );\n    } else if (data.ploneDocument) {\n      return (\n        <Document\n          data={data.ploneDocument}\n        />\n      );\n    } else if (data.ploneEvent) {\n      return (\n        <Event\n          data={data.ploneEvent}\n        />\n      );\n    } else if (data.ploneFolder) {\n      return (\n        <Folder\n          data={data.ploneFolder}\n        />\n      );\n    } else if (data.ploneNewsItem) {\n      return (\n        <NewsItem\n          data={data.ploneNewsItem}\n        />\n      );\n    } else {\n      return null;\n    }\n  } else {\n    return null;\n  }\n};\n\nconst DefaultLayout = ({ data }) => <Layout>{componentFor(data)}</Layout>;\n\n// Query for all the different types from GraphQL\n// Fragments for each type are defined in their relevant components\nexport const query = graphql`\n  query DefaultTemplateQuery($path: String!) {\n    ploneCollection(_path: { eq: $path }) {\n      ...Collection\n    }\n    ploneDocument(_path: { eq: $path }) {\n      ...Document\n    }\n    ploneEvent(_path: { eq: $path }) {\n      ...Event\n    }\n    ploneFolder(_path: { eq: $path }) {\n      ...Folder\n    }\n    ploneNewsItem(_path: { eq: $path }) {\n      ...NewsItem\n    }\n  }\n
\n

Now all you need to do is design each component. Similar to the Folder component we already have, different components can be built depending on the data passed in and to be displayed.

", + "encoding": "utf-8" + }, + "title": "Handling different data types", + "version": "current" +} diff --git a/tests/gatsby-starter-default/gatsby-config.js b/tests/gatsby-starter-default/gatsby-config.js index 05cc9cc3..17f2c096 100644 --- a/tests/gatsby-starter-default/gatsby-config.js +++ b/tests/gatsby-starter-default/gatsby-config.js @@ -4,7 +4,7 @@ require('dotenv').config({ module.exports = { siteMetadata: { - title: 'Gatsby plugin for Plone', + title: 'Plone plugin for Gatsby', }, pathPrefix: '/gatsby-source-plone', plugins: [ diff --git a/tests/gatsby-starter-default/gatsby-node.js b/tests/gatsby-starter-default/gatsby-node.js index a7ff7e14..e72fba43 100644 --- a/tests/gatsby-starter-default/gatsby-node.js +++ b/tests/gatsby-starter-default/gatsby-node.js @@ -55,6 +55,7 @@ exports.createPages = async ({ graphql, actions }) => { result.data.allPloneFolder.edges, result.data.allPloneNewsItem.edges ) + .filter(({ node }) => node._path !== '/index/') .forEach(({ node }) => { createPage({ path: node._path, diff --git a/tests/gatsby-starter-default/src/components/Folder.js b/tests/gatsby-starter-default/src/components/Folder.js index 1204847a..b9af64d1 100644 --- a/tests/gatsby-starter-default/src/components/Folder.js +++ b/tests/gatsby-starter-default/src/components/Folder.js @@ -27,7 +27,7 @@ const Folder = ({ data, title, images = [], files = [] }) => {