💾 Archived View for mozz.us › journal › 2020-12-01.gmi captured on 2023-06-16 at 16:37:37. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2021-11-30)
-=-=-=-=-=-=-
Published 2020-12-01
Pygopherd is an old gopher server from the 2000's that still has some active users. I think primarily it's still relevant because it's packaged for debian and fairly easy to install. It's notable as being the only server that I've seen to actually support gopher+, as well as multiplexing a handful of other protocols including HTTP and WAP over the same port. It was also the first server to pioneer the "hURL:" links in gophermaps that are now widely used to link to WWW from gopherspace.
Example of a gopher server being multiplexed over HTTP (we don't need no stinkin' proxy)
The inception of the hURL: item type on the gopher mailing list
Pygopherd was written in an early 2000's version of python (I think python 2.2 initially?). Since then it's been kept alive with very few updates over the past 20 years. But now that linux distros are finally dropping python 2 in favor of python 3, the debian package is at risk of being dropped as well. The author and maintainer of pygopherd, John Goerzen, posted on the gopher mailing list that that he was not going to finish porting to python 3 himself. He made an honest attempt at it but ran into a lot of issues with bytes and non-unicode filenames. Some of this frustration was vented in a series of very interesting blog posts:
The Fundamental Problem in Python 3
So since I already maintain a gopher server written in python, and I have experience updating large codebases to python 3 at my dayjob, I volunteered to take a shot at updating pygopherd. I figured why not, it would at least be an opportunity to finally try out gopher+.
My python 3 fork of pygopherd (still in progress)
Flask-Gopher - my first gopher server
Pygopherd has a concept of pluggable file handlers, and it comes with a bunch of built-in handlers to choose from. You can configure pygopherd to serve a gopher directory from inside of a compressed zip file, or have it generate a file from a CGI script, or read an .mbox file. etc... It's a neat idea and very extendable.
One of these handlers is just called "tal". It's not listed in the documentation anywhere so I'm guessing it was written as more of an experiement than anything else. It depends on an optional python library called SimpleTAL. I had to look it up, and I found out that TAL is an HTML templating language that was pioneered by Zope, the "original" python web framework. The timing makes sense since Zope was big around the same time that pygopherd development was active.
The SimpleTAL software homepage
The interesting thing about TAL is that it's an XML-based templating language. Coming from modern jinja2/django templates I haven't seen anything like this before. Literally everything in the template is specified through valid XML attributes (ignore the fact that HTML is not valid XML in the first place...).
The end result is ugly as sin, which is exactly what I would expect an XML document to come out looking like:
<html> <body> <h1 tal:content="title"> <h2 tal:condition="username">Welcome back <b tal:replace="username">Username here</b></h2> <p> Hot topics for today are: <ul> <li tal:repeat="news hotItems"> <a tal:attributes="href news/link" tal:content="news/title">News item</a> </li> </ul> </p> </body> </html>
Jinja2 is my favorite python templating library. I've used it in both my gopher and gemini sites.
Example jinja2 template for a gopher directory (Flask-Gopher)
Example jinja2 template for gemtext page (Jetforce)
Of course, I had to google for "jinja2 vs TAL" and see if there were any arguments in favor of TAL. I came across this interesting discussion on Reddit from 2011, talking about how web development was done back in the web 1.0 era.
Behold: /r/javascript before it turned into a cesspool
That has been a major argument in Python's template languages, too.
Some people argue "XML-style" template languages are cleaner because they don't clutter the templates with magical plaintext and theoretically allow viewing HTML templates as proper HTML in a browser (in practice they might not, for example when resource URLs are generated by function calls rather than being hardcoded in the templates, plus all the other problems I list in my other comment).
Generally "plain text" template languages are much easier too parse and don't require the overhead of generating a full DOM. I would argue that you're actually doing it wrong if you're trying to look at the templates themselves in a browser. CSS aside, you should be able to read HTML to understand its structure. And looking at the styling normally requires at least some dummy content. For loops, you probably also want to look at different cases: an empty dataset, a small one, a big one, etc. The same goes for conditionals (true/false) and their various possible combinations. You just can't do that just by looking at a plain template, even if it's valid XHTML 1.9000 SuperStrict+.
The original argument that I heard (about a decade ago) was that a designer could mock-up everything in Dreamweaver, hand it off to a developer who would insert the namespaced XML attributes, and then continue to refine the page without needing to go back and forth with the dev. This was because adding the attributes changed the DOM, which Dreamweaver understood.
But yes, loops and such sort of make it fall apart. Then you have to engineer some new solution to the same problem
This got me thinking. What would a template language designed specifically for gemini look like? text/gemini is intentionally a simple format. Could we do any better than a "plain text" style template engine like jinja2? Or am I just not being creative enough?
On a completely unrelated note, I've updated my gemlog index to match the new format that was pitched by solderpunk. I like this method a lot more than maintaining an atom feed using a build script. It's both elegant and functional. If I were to start fresh, I would write my gemlog index by hand and skip the atom feed completely. But it's already setup so it seems like a waste to not use it now.