My comment section is static HTML

13 points by jvalol a day ago on lobsters | 27 comments

sivers | a day ago

For what it's worth, I generate static HTML comments using PostgreSQL's NOTIFY and LISTEN :

https://sive.rs/shc

The PostgreSQL function that receives the posted comment:

https://github.com/sivers/sivers/blob/master/me/comment_post.sql

Then then simple query to wrap comments in an ordered list:

https://github.com/sivers/sivers/blob/master/me/comments.sql

kaidenshi | a day ago

This is the way. Derek, once again you blow my mind with simple yet effective and "just gets the job done in a nice way" methods.

You were my inspiration to daily drive OpenBSD so many years ago and I thank you immensely for that nudge.

[OP] jvalol | a day ago

For what it's worth back, I like your version. Of course I'm biased for this one since it is after all what I built my way. Yours is instant, mine costs a roundtrip and a build. In exchange the comments end up baked into the page itself. PopsicleBoat can be thought of as ephemeral. It can also be used by anyone who wants a system like this: you wire your build to one JSON endpoint, and the rebuild-on-reply hook is optional.

[OP] jvalol | a day ago

The comment section under the post (not the lobste.rs one) is the mechanism the post describes, so view source shows the end result. If someone comments while you're reading, the page rebuilds and the comment is baked in about a minute later. Happy to answer questions about the server side.

Feels a bit recursive, now I think about it. Commenting about a novel commenting mechanism. Heh.

adam_d_ruppe | a day ago

"novel"? This sounds like the standard way it was done by everyone before the whole web dev world lost their minds and forgot how to use html.

patryk | a day ago

Can you give me any example of that? All of the comments sections before the Disqus days I remember were simple, but no way it was served directly without php rendering the page

agwa | a day ago

Movable Type, which was a pretty popular blogging platform 20+ years ago.

mro | a day ago

adam_d_ruppe | a day ago

Old perl cgi-bin things also frequently did it this way, where the page itself is html then the cgi-bin post action would rewrite it. You could tell as a user because the post actions all went into /cgi-bin/comment.pl and the views were like my_page.html.

A bit newer, any PHP + cache works this way, though lots of people won't bother setting up the cache since the cost of php is so low, but like WordPress offers cache plugins that write html to directories, or there are caching proxies that work that way under the hood and completely avoid touching the php for most loads, but again the cost of php is so low relative to 99.999% of blog traffic it wasn't worth the effort of setting it up. Wikipedia works (or worked in the past, idk anymore) this way, edits would hit the database and trigger cache invalidation but almost all the reads actually went through a cluster of caching proxies. Of course, Wikipedia is one of the heaviest traffic websites in the world, whereas my blog (along with most blogs) have like one to ten readers.

The OP blog says it takes about a minute to rebuild........ and that's after a ping notification from the comment system. That ping reduces latency, but still triggers a full rebuild of the whole site, which then polls for the comment json from the "boat" backend, which is a lot of slow work. Looking back at last month's blog post from this author, indeed, the build hook doesn't tell you what changed, so it just has to poll it all. It tries to consolidate burst updates but doesn't let you limit the scope of rebuild work to only what actually has to be done. The cpu load of the uncached php is probably lower.... and with this, suppose the comment boat goes down, the next build of the site deletes comments from ALL posts, since it is just redoing from scratch and now can't get that json. With a targeted update, it could gracefully handle failure and still show the last saved version... just like a traditional cache could do.

[OP] jvalol | a day ago

Wrong word. I know the whole web dev world has existing solutions. Maybe I should have used something like "this is my solution".

abhin4v | a day ago

Nice! I have same implemented for my blog as well. Comments are generated as a separate page per post, linked from the post page. Here is an example. I don't have automatic rebuilds though, only period ones.

[OP] jvalol | a day ago

Your work there looks awesome, it means I'm not the only one who isn't entirely satisfied with off-the-shelf solutions. FWIW I've got my system documented here https://www.popsicleboat.com/for-bloggers/api - the build hook is I think the special part, it does take some setting up but as my own blog demonstrates, it works pretty well. It's basically a hook that fires on new comments. Doesn't even have to be a rebuild, it's up to the user. It's just a hook.

coby | a day ago

This is a nice architecture! I agree with the trade-offs, and that most get this backwards. :)

Why a thread per post, though? That seems brittle. Also, what's with the name Popsicle Boat?

[OP] jvalol | a day ago

Ha. I knew someone would ask that someday. PopsicleBoat is just something whimsical, I thought it was fun when I started it. I also kind of think it evokes childhood memories, and in general serves well as a metaphor for what I'm building. It's a boat. It holds people, communities, etc.

A thread per post? Yeah, maybe that's a design consideration I should think more about. I don't think it's brittle, unless I'm missing something. The threads are ordinary threads in a small community, and the blog just consumes them as JSON. They also bake into the user's site, so the comments outlive PopsicleBoat either way. It's just a place that can serve as a commenting system for anyone who doesn't want to manage their own, or use one of the heavier solutions like Disqus.

coby | a day ago

I always like to ask about cute names because maybe it's a reference to something I haven't heard of before. But when the answer is "just for fun" that's delightful in its own way! I like "Popsicle Boat" a lot.

A thread per post? Yeah, maybe that's a design consideration I should think more about. I don't think it's brittle, unless I'm missing something. The threads are ordinary threads in a small community, and the blog just consumes them as JSON.

Hah! It was me missing something. My programmer brain read the part about "creating a thread" as "starting a long-running system thread" that then presumably listens for new comments on that specific post. Threads in the conversation sense make complete sense. :P

ryan-duve | a day ago

I'd like to understand the decision to reach for solutions like Phoenix/Cowboy to serve a website such as this, instead of say Apache/NGINX. When I think of the BEAM I think of the need for lots and lots of concurrent messages, usually for some ultra dynamic system. I don't know how to reconcile that with the author's emphasis on static and simple characteristics.

[OP] jvalol | a day ago

It could be any number of technologies. I just happen to like the Elixir/Phoenix/LiveView ecosystem. I've worked in it for close to a decade so I know it well. Does this application need incredible concurrency? No. But if it ever did, that's a nice problem to have. In the meantime it (especially LiveView) serves the purpose just fine.

One nitpick, my blog is not Phoenix. It's Hugo, just your run-of-the-mill blogging system, static files served from Netlify's CDN. The commenting system I built (PopsicleBoat) is Elixir/Phoenix/LiveView etc.

Overkill technologically maybe, but running on fly.io my costs are negligible, development lifecycle as a solo dev on it is fast. So maybe the question back is, why not?

skobes | a day ago

I typed out a comment and hit the Post button but this took me to a login page and after creating an account it did not remember the comment text, which was frustrating.

[OP] jvalol | a day ago

That's useful feedback, thank you. I'm speccing and implementing a fix now.

[OP] jvalol | a day ago

Ok, that should be fixed and live now if you want to try again

jmtd | a day ago

So are mine: ikiwiki’s comments plugin works this way. The advantage ikiwiki has here, I think, is it’s had an optional dynamic component from day 1. (One of the disadvantages these days is it’s a setuid C wrapper to run Perl as the user who owns the source files, which is a lot of stuff you don’t need in the container era). Oh, and incremental builds.

wmurra | a day ago

I prefer a page that sometimes forgets to a page that sometimes fails

no widget, no iframe, no tracker, and no third-party script

No script, no cookie, no request on pageview

Reading is static. Writing is dynamic. That is the whole idea

hoistbypetard | a day ago

In the comments, they said they "do often get a draft from AI." It looks likely that this post falls into that bucket.

[OP] jvalol | a day ago

It does, yes. Guilty as charged. In my defense, if you'll afford me one, I'm mostly just playing. I make no money from this. It costs basically nothing. To quote Marge Simpson "I just think it's neat".

wmurra | a day ago

Where is the defense? I still think it’s a bit rude to post writing like this without a disclaimer.

[OP] jvalol | a day ago

Well, the defense is right there. I'm having fun. I'm sorry I didn't include a disclaimer. I didn't know that was the norm.

ale | a day ago

>i store comments in a database and render the HTML on the server

lol what in the world is this crap