Because I can I built a basic blogging platform using Node-RED. This is done out of pure fun and pleasure. Based on the ideas from Jekyll - a Ruby static page generator.
Having described my previous Node-RED projects, I was left with coming up with a new idea. Still not having any IoT devices and not particularly interested in integrating AI, I pondered.
Suddenly it hit me like a bus in reverse: a blog! Every good web framework worth its digital salt has a blog application as their hello world example.
So how to do this in Node-RED?
First off, what does a blog consist of:
Top level domain - a domain such as blog.openmindmap.org so it is clear what content should be expected. Also paths that should have meaning /blog/how-i-built-a-blog-using-node-red. How to handle domains in Node-RED?
Content Management System (CMS) - how to manage the content? How to organise it so that there is an overview of what is available, what has been published and what still needs to be worked on? How to store images and other non-text content?
Search Engine Optimisations (SEO) - How will a search find the blog? How to avoid duplicate content using canonical URLs? How to provide text snippets that can be indexed?
Social Media - user feedback - how to do this? Integrating third party solution or roll own social functionality?
Advertising - gotta make some dosh, cash in the tash, reddies in the hand! How can advertising and revenue analysis be integrated into Node-RED?
Markup Language - no one wants to write pure HTML. A modern blogging platform needs to have some sort of markup language. Thankfully this question has a Node-RED answer: Markdown in combination with Mustache templating. Node-RED has first-level support for both so that’s a no-brainer.
Branding - CSS Styling - if the content is bad, then it should at least look good! Favicon - no name, no fame, no logo - need some visual branding. Here the only question here is how to host this stuff in Node-RED.
RSS Feed - automatically generated from the articles available on the blog. This becomes tricky since how do manage HTTP endpoints (i.e. the blog page links) in an environment that is flow-based and visual? There is no concept of “article” or “page” within Node-RED, its not an CMS or blog tool.
Renaming paths - how to rename paths without getting search engines to complain about duplicate content? Sometimes paths change and old paths should redirect to new paths without affecting SEO rankings. So a redirect concept needs to be available.
That list skips the underlying technology: which database? Which model/view/controller concept? Which database mapping layer? Which version control system? … Basically the answer to all those technical questions is Node-RED!
Disclaimer:
This is not one way but my way of doing a blog with Node-RED. In no way is this the only way nor the best way - this is a way, my way as Frank Sinatra would have said.
Personally Philosophically Reflecting on Node-RED
What is my motivation in doing this?
I began using Node-RED as a programming environment for doing stuff and soon realised that the two-dimensionality of Node-RED provided one more dimension than my editor. I began also seeing the flexibility Node-RED provided and began more and more to think over the meaning of nodes.
Node-RED node makes the assumption that nodes are bits of computer code that get executed and passed along connections. I saw colourful boxes that were joined together by grey connector lines! I saw these boxes as representing anything, not just code to be executed.
I began using nodes as content containing my writings. I realised that the one-dimensionality of my editor was limiting my ideas and writing. What was at the top of a document was never seen again. What was written days ago, was forgotten and repeated in long documents.
I needed to organise my writing in a different structure. That is when I began viewing Node-RED as a mind-map tool, but a mind-map tool with executable nodes. So I began wondering what my mind-map nodes should be doing when they get executed.
And that’s when I came up with the idea of have my mind-maps generate texts for me.
Ironically this is proving to be difficult since I am going from two-dimensions to one-dimension and that means that I lose a dimension. Gaining a dimension means more freedom, reducing dimensions means culling freedom.
I am beginning to think that a blog, i.e., a one-deminsional web representation, is not the perfect means to transport content in mind-map form.
But that is still part of the experiment: how to find a better way to provide motivation for creating your own mind-map and uploading to openmindmap.org (one day) to create a global mind map.
This is a question for Node-RED since by default, Node-RED takes the top-level path and throws you into the flow editor. That can be changed by setting the adminRoot
in the settings.js
file. The dashboard component has the default path of /ui
which is fine.
Using the dashboard component as a blog site is not workable. There are too many assumptions made about its usage, therefore I have to setup my own endpoint using http-in
nodes.
My aim is to have a blog domain and an Node-RED domain, i.e., separate domains that have no overlap. This prevents /wp-admin
like-attacks on the domain since the flow editor domain remains secret and the blog domain has no access to the flow editor.
This site is hosted at Heroku and they allow as many custom domains as needed. Therefore I now have my two domains pointing to this Heroku application and route requests according to the hostname. This is done in the Blogroller main flow.
I also had to add middleware into the settings,js
for preventing access to the flow editor and the dashboard via the blog domain.
Security through obscurity.
Having two domains is a bit of security through obscurity since once those the domain becomes public knowledge, it becomes difficult to change. So this is strictly necessary nor does it particularly increase security.
But what it does do is provide a means to host other domains. This might be useful for agencies that have many customers with many domains. The steps I went through aren’t limited to two domains, I can configure more if I so desired.
Content Management System (CMS) vary a lot, everything from Wordpress to Discourse to Google Docs to Salesforce, all have some sort of content management. Be it customers or content or sales.
The most flexible content management systems are the ones that make few assumptions. This makes Node-RED ideal for implementing a basic CMS.
Starting out with a blanket sheet of paper, I am shining light into an unknown world. Node-RED has no conventions or opinions on how to do CMS. So I began but taking my mind-map idea and using those as content for my blog application.
A mind-map node is very simple: it has a name and info box. The name is what is shown within the flow editor and the info is shown in the info panel in the sidebar. Mind-map nodes use the existing properties that each node has - name and info. This is good since Node-RED supports those properties out-of-box.
Mind-map nodes are connected using the Node-RED data-stream connections, so no need to write custom code for connecting my mind-map. In fact Node-RED has more flexibility in creating mind-maps since normally connetions go in one direction away from the node. Node-RED allows input and output connections - use both and not consistly, i.e., an input connections is sometimes used purely out aesthetic reasons.
Each mind-map node does the same when executed: the simply place their content onto a stack that gets pushed all the way until it reaches the end of a path or it gets consumed. I can consume content in the middle of a flow, this allows me to define “partial” text that I can place anywhere in the final text.
The reason I have so many is simply to divide up my thoughts into various categories, i.e., ideas, observations, inspiration, etc. Each has its own type, so that searching by type:xxxx
makes total sense sometimes.
Using the collection of mind-map/writer-map nodes is breaking my thoughts down into consumable chunks.
Autoupdate
I fell into the ctrl-D, ctrl-R trap. Ctrl-D to deploy my new text and then switch to the other browser window to reload the article.
Of course, I often reloaded my Node-RED editor or get a prompt asking whether I wanted to leave my changes beyond.
So to avoid the ctrl-R step, I setup a template that uses a websocket connection to reload the page automagically for me.
I can now leave a open browser page to the finished text and one with the flow editor to update the text.
Info is front & centre
All my mind-map nodes have the info box as the many input window in the properties sidebar. So text can be quickly added and updated. Using what Node-RED already provides makes it so much simpler to implement a mind-map.
Spll Chckr
There is no spelling check on Node-RED. It’s not an editor as iA Writer or Word. One of my biggest wishes is that Node-RED would have a spell checker so that writing the text in the info box would become like working in an editor.
And spelling is just one thing, iA Writer has a terrific “highlight all my fill words” feature so that texts become very very much smoother and polished.
The focus of any blog is the content in form of pages. Each page is a blog entry and each page must have a path to access that content. For example:
https://blog.openmindmap.org/blog/how-i-built-a-blog-using-node-red
Path here is /blog/how-i-built-a-blog-using-node-red
, how to map that to the flow? I choose to use link-in
and link-call
nodes for generating content within the request-response cycle.
The mapping from path to link-in node becomes the path. The link-in node for this page is [blog] how-i-built-a-blog-using-node-red
and that is a convention that I follow. Using this convention means there is a single definition of the path (by the link-in node) and the router calls the link-call node with a dynamic target. It sets the target to [path] <path>
where <path>
is whatever the user entered after /blog/
. This means that if the link-call node fails, the users sees a 404 not found page.
If a link-in node is defined with that name, the content is generated and delivered to the user.
Examples
These are all conventions that must be followed and when not followed, bad things might happen!
Using Heroku its impractical to upload data since I would have to purchase storage. Instead all image data is committed into the repositort and accessible via /content/xxxx.png
provided by this flow.
If I pursue this project professional, an upload interface would be provided by the dashboard using dashboard compoments. This I have already done locally for my own mind-map.
This and the following two:
all do not really interest me, so I won’t cover them. I was an early adapter and recall when the internet was about transporting knowledge and encouraging cooperation amongst academics.
Unfortunately the internet has degenerated into a cesspool of cat memes and fake news. No need to encourage that.
The coming wave of AI generated content will only accentuate the cesspool further.
For all those that argue that advertising is necessary to pay for content, I say you lack imagination. We humans have been to the moon yet we cannot come up with a less-detrimental form of financing the internet than advertising?
What would the aliens say when they heard that? And if you are a believer, then ask yourself what would God think?
Its a wonder we made it this far going some 60000 years without advertising.
Using the BlogPages
node, this became a piece of cake. Basically it was a matter of using the template node to generate XML that is created based on the blog pages available.