Monthly Archives: April 2022

Blogging on static generated sites with OPML and XSLT in 2022

This is gonna be a long blog-post, so bare with me.

I started blogging in February of 2014. A friend of mine, my mentor, norayr, got me my first domain, pingvinashen.am (literally means: the town of penguins), because I did not have money back then. I started hosting WordPress on it, tried to blog as much as I can, anything from technical knowledge to personal opinions.

Over the years I moved from a WordPress blog to a statically generated website using Hugo, and then I started an English blog with the same framework as well.

This worked all fine for me, because everyone was doing the same and it did fulfill my needs anyway.

Until I realized that many of my title-less posts (actually, the title was just »»») were kinda “icky”.

So I started researching about the origins of blogging. Now, I already knew about Adam Curry and how he started the PodCasting “industry”, but I never knew about blogging itself.

Obviously, I found DaveNet, the oldest running blog.

Currently, Scripting.com (Dave Winer’s updated blog) has been running for: 27 years, 6 months, 9 days, 21 hours, 20 minutes, 42 seconds. (taken from his website).

Learning more about Dave, I learned a lot about the origin of OPML, which stands for Outline Processor Markup Language. I knew a bit about it since it’s the standard format to export and import RSS/Atom feeds into news aggregators, but I never actually KNEW what it was about. If you are interested, checkout opml.org/Spec2.opml.

My interest of OPML got boomed when I saw my favorite blogger, Rubenerd, was using it for his Omake page.

Okay, so you can host OPML pages WITH styling using XSLT, the Extensible Stylesheet Language Transformations language.

As you know, I’m a huge fan of XML, while it’s not as “modern” as JSON or “cool” as YAML, I think it has a proper place for its usage. This seems to be one of them.

I started copying Rubenerd’s XSL file and ended up with this, which is not close to it anymore. I learned about recursive calling, templating with matches, etc.

First, I would love to tell you that my homepage is finally made in OPML+XSLT. Here’s my process:

  • Write the content using an outliner and export as OPML
  • Use xsltproc (part of macOS base, BTW) to generate an HTML output
  • Export that HTML to where-ever you want.

Does this sound similar to static site generators? Because it is, except that static site generators have their own templating language, while in this case, I’m using XSLT.

Okay, let’s talk more about the details.

First, I was using Zavala, my outliner of choice for Apple-ecosystem. First issue was that the links in there are markdown (which is [text](link)). The second issue was that (and I’m not sure about this) I was not able to edit the attributes of a node/outline.

I wanted to use Drummer, but I didn’t want to log-in with Twitter to use it. I’ve had issues with Twitter in the past, where they deleted my 6-year-old account in 2015.

Luckily, there’s a version called Electric Drummer (hereafter D/E), it’s a bit outdated, but it was good enough for my needs.

First thing first, I “converted” my homepage to OPML.

After that I wrote the XSLT code.

The xsltproc tool is actually very interesting, the usage is pretty simple and it follows the standards very well. The error messages are pretty human readable.

On my first try, I had an issue with links, as in <a HREF=""> tags, because XSLT does not allow < in the field by default. So my idea was to see what would D/E do after saving. Turns out it would convert to HTML encoded text, i.e. &lt;a href=&quot;https://antranigv.am/&quot;&gt;antranigv&lt;/a&gt; . Which meant that I could use disable-output-escaping to achieve my <a> tag needs.

This got me thinking, maybe I could also use the HTML <img> tag?

Technically, there’s no way to add an image tag in D/E, however, you can script your way around it, so here’s what I did:

<outline text="Add image" created="Mon, 11 Apr 2022 23:37:14 GMT">
    <outline text="url = dialog.ask(&quot;Enter image URL&quot;, &quot;&quot;, &quot;&quot;)" created="Tue, 12 Apr 2022 21:45:09 GMT"/>
    <outline text="op.insert('&lt;img src=&quot;' + url + '&quot;&gt;', right)" created="Tue, 12 Apr 2022 21:46:01 GMT"/>
</outline>

Basically, I used Dialog to ask the user for the link and then paste the outline as a new first child of the bar cursor.

After that I just do xsltproc -o index.html opml.xsl index.opml. Wait, can’t I just include the XSL page into OPML like Rubenerd’s Omake? Yes, I can, but I’m not sure how things will work out in other people’s browser, so I just generate the HTML file locally and publish it remotely.

In an ideal world, I would use these technologies for my day-to-day blogging with a bit of change.

  • I would either do some changes in E/D, e.g.
    • Add a dialog.form, which is similar to dialog.ask, where the input can be a text field instead of a single line (more on that later)
    • Make it understand Operating System commands using Shell (execute publish.sh) or add more Node-like JS in it.
  • Or, do changes in Zavala to support HTML links, HTML image tags. I would love this more, because it’s native to macOS. I’ve been playing around with Swift lately, I’ll try this next month.

Assuming I would use this for my day-to-day blogging software, how would this look like? Well, I started experimenting, this is what I got for now.

The nice thing about Drummer is that it adds the calendarMonth and calendarDay types automatically.

The last missing piece for me would be the ability to add a code block. Ideally, I would use dialog, but oh boy it does not understand \n or \r, which meant doing a very dirty hack. If anyone knows a better way, please let me know.

First, I wrote a Drummer script that takes in the code encoded as base64, decodes it, replaces the newlines with <br/>, and puts them in a <code><pre> tag as a new first child of the bar cursor. Here’s the script:

Like I said, in an ideal world 🙂

So, here are my conclusions.

I started tinkering with all this because I wanted title-less posts like Dave (here’s an example of how that would look like in RSS). I learned a lot about OPML and XSL, I got motivated by Rubenerd to write my own XSL which ended up looking like a mini-hugo.

I think I will spend some time making patches to Electric Drummer and Zavala, and I will try building a PoC for blogging.

I think XSLT is very interesting in this day and age, it has a huge potential when used correctly and most importantly, there’s a lot of history behind it.

The questions is, where do we go from here? Should I do this because it’s old-school and cool, or should I find another way to blog more with title-less posts?

All that aside, this was very fun.

Thank you for reading.

P.S. If you have any questions, ideas, suggestions or want to chat with me, I’m always available.

That’s all folks…

Reply via email.

Git Remote URL, the lazy way

I develop and run my code on different machines. We have a centralized storage in our infrastructure which can be mounted via NFS, SSHFS or SMB.

The “problem” is that the remote servers, which also mount my remote home (automatically, thanks to AutoFS), don’t have my keys, they never should, the keys are only in one place, my laptop. The keys that I need to commit are my SSH keys for Git push and my GPG keys for signing those commits.

The usual problem was when I git pull on the development server needs to be an HTTP URL, internally accessible for the mentioned server. Which mean that I can’t git push from my laptop, because we don’t allow pushing via HTTP(s).

At the same time, if I set the URL to an SSH URL, then git pull will not work on the development server, because it does not have my SSH keys.

I know that I can set multiple remotes in git, but how about setting a different URL for a remote’s push and pull?

Turns out that’s doable!

It’s also very simple:

First, we clone using the accessible HTTP URL

git clone https://my.git.server.local/myuser/myrepo.git

Then we set the URL only for pushing

git remote set-url --push origin git@my.git.server.local:myuser/myrepo.git

And now let’s check the remote addresses

% git remote -v
origin  https://my.git.server.local/myuser/myrepo.git (fetch)
origin  git@my.git.server.local:myuser/myrepo.git (push)

Yey, exactly what I needed!

That’s all folks…

Reply via email.