jsonify-html
v2.0.1
Published
A cheerio-backed parser to transform HTML into Reactifiable, customizable JSON data (use with "reactify-json" package).
Downloads
8
Readme
This module allows transformation from "raw" HTML to a serializable JSON. In turn, the serializable JSON can be used to create React components using another module, reactify-json. It's all in the name, really.
Now, why JSON, of all formats? Because of the inherent benefits of JSON, and because of how lightweight it is, you can store it in virtually any NoSQL database. That's right, you can create your own collection of ready-made React components from simple JSON files.
makeJSONFromHTML
This is the function that generates the JSON. If you pass the example HTML below:
<html lang="fr">
<body>
<div id="bruh" class="banner" style="color: red; padding: 6px">Lord of a Dead Empire</div>
</body>
</html>
You will obtain the example JSON:
{"html":{"props":{"lang":"fr"},"children":[{"head":{"props":{},"children":[]}},{"body":{"props":{},"children":["",{"div":{"props":{"id":"bruh","key":"-1-1","className":"banner","style":{"color":"red","padding":6}},"children":["Lord of a Dead Empire"]}},""]}}]}}
So what happened exactly?
- The function parsed the provided HTML starting from a root html tag.
- It parsed its properties, and displayed them in a key-value manner for ease of manipulation.
- Because the html tag's direct children are the
body
and thehead
tags, they will feature as its children. - If one of their children is text, return the text as-is.
- This process is recursively applied until no child is left "unparsed".
Take note that even if an html tag is not provided as an argument, the function will still generate an html object. In this case, you need to look for your content inside the body JSON, which itself is the second child of the html object.
People familiar with React will notice several things:
- The
class
attribute becameclassName
. - Whenever a
<number>px
attribute value showed up, it directly got transformed as a number value only, which is essentially React-compliant. - The
props
property is exactly what it says in the tin: a holder for futureprops
to be injected inside a React component. - A key is provided by default, because of the way React renders elements.
getEditableMap
This is the second exported function in this package. It benefits directly from the first function's output, and generates what we like to call an "edit map", or "editable elements map".
This package supports the passing of two special attributes inside the HTML to provide: iseditable
and group
. The core concept of these attributes is that it should allow us to edit a property of the element marked with iseditable
(any property: style, content, any property. And because it's intended to be transformed to React, you can aim for a precise style attribute to change (because all attributes are stored as key-value pairs), like color
).
As an example, let's take a look at the following HTML:
<html lang="fr">
<body>
<div id="bruh" class="banner" group="first banner" iseditable="{'style.fontFamily': 'Font Family'}" style="color: red; padding: 6px">Lord of a Dead Empire</div>
</body>
</html>
After passing this html to makeJSONfromHTML
, then feeding its output to getEditableMap
, this is what you get:
{"json":{"html":{"props":{"lang":"fr"},"children":[{"head":{"props":{},"children":[]}},{"body":{"props":{},"children":["",{"div":{"props":{"id":"bruh","key":"-1-1","className":"banner","group":"first banner","iseditable":"{'style.fontFamily': 'Font Family'}","style":{"color":"red","padding":6}},"children":["Lord of a Dead Empire"]}},""]}}]}},"map":{"first banner":{"Font Family":"html.children.1.body.children.1.div.props.style.fontFamily"}}}
This is what happened:
- The initial JSON was kept for reference.
- But we have a new top-level property,
map
, which provides groups of editable HTML elements, and what's editable about them. The use of having groups is better illustrated by the following example: Let's say you have a bunch of whose propertysrc
you'd like to control. But here's the catch: every image should be different. So what we can do is, assign each image to a group that will contain it (in this example, "first banner"), and then determine the property we'd like to edit (the imagesrc
for example). Now, back to our original example, why is there a"Font Family"
in human-readable language? This is a label you can assign to your editable element. Let's say you'd like to create an editor in which your user is not the most technically adept person. You'll need a beginner-friendly way to convene "okay, this is where you edit your text's font family", and so on.
The map
object provides a pathway for each editable property, starting from the root html
tag all the way down to the editable element and its property. It's simply a way to keep track of its location, so whenever the user updates a property, the package will know exactly where to update that property. Of course, you can assign one or more properties of the same element to be editable, simply by adding more properties and labels inside your iseditable
attribute.