Skip to content

Commit

Permalink
feat: import from JSON (#139)
Browse files Browse the repository at this point in the history
  • Loading branch information
kptdobe authored Mar 29, 2023
1 parent b8ed934 commit 8eb9d9c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
72 changes: 72 additions & 0 deletions docs/import-from-json.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Case study: import from a json file or a JSON API

Page to consider: https://main--hlxsite--kptdobe.hlx.page/content/json-page.json

This is dummy page, do not worry about the data, it is just here to illustrate how to consume some random JSON.
The goal is to convert that JSON object into a docx. The only additionals step is to parse the JSON object and load the useful data as DOM elements. This is probably not the smartest approach (a JSON to MD conversion would be more direct) but since everything is there in the importer, we are just reusing the existing process.

Here is an import.js example:

```js
const createMetadata = (main, document) => {
const meta = {};

const title = document.querySelector('title');
if (title) {
meta.Title = title.innerHTML.replace(/[\n\t]/gm, '');
}

const block = WebImporter.Blocks.getMetadataBlock(document, meta);
main.append(block);
};

export default {
preprocess: ({ document }) => {
if (document.body.firstChild && document.body.firstChild.nodeName === 'PRE') {
const json = JSON.parse(document.body.firstChild.textContent);

// from here, convert your JSON into DOM elements
// this is really specific to the JSON you're importing
if (json.data && json.data.length > 0) {
document.body.innerHTML = '';

const title = document.createElement('title');
title.textContent = json.data[0].Title;
document.head.append(title);

const main = document.createElement('main');
const h1 = document.createElement('h1');
h1.textContent = json.data[0].Title;
main.append(h1);

const p1 = document.createElement('p');
p1.textContent = json.data[0]['Paragraph 1'];
main.append(p1);

const p2 = document.createElement('p');
p2.textContent = json.data[0]['Paragraph 2'];
main.append(p2);

document.body.append(main);
}
}
},

transformDOM: ({
// eslint-disable-next-line no-unused-vars
document,
url,
}) => {
const main = document.body;

// you can implement your usual DOM transformation rules here
createMetadata(main, document);

return main;
},
};
```

Notes:
- the JSON to DOM element conversion depends on the JSON schema
- If the JSON is super generic, it might be cleaner to focus on the JSON to DOM conversion in the `preprocess` step to get a clean DOM and on the usual DOM transformation rules in `transformDOM` for the project specific block creations. If the JSON is super specific (i.e. blocks are already identified here), then the JSN to DOM conversion might already output the blocs.
1 change: 1 addition & 0 deletions importer-guidelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,7 @@ Sites in the https://github.com/hlxsites/ organization have all be imported. The
Here is growing list of case studies to help you drive some more sophisticated imports.

1. [Convert a page and download all PDF files referenced on the page](./docs/download-pdf.md)
2. [Import content from a JSON API](./docs/import-from-json.md)

## Helpers

Expand Down
2 changes: 1 addition & 1 deletion js/import/import.ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ const attachListeners = () => {
processNext();
} else {
const contentType = res.headers.get('content-type');
if (contentType.includes('html')) {
if (contentType.includes('html') || contentType.includes('json')) {
const frame = document.createElement('iframe');
frame.id = 'import-content-frame';

Expand Down

0 comments on commit 8eb9d9c

Please sign in to comment.