Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: XRss – RSS Reader and web stack demo (infogulch.com)
144 points by infogulch on Sept 2, 2023 | hide | past | favorite | 42 comments
XRss is a simple RSS reader web app built to showcase xtemplate, a new web development tool based on Go's html/template and Caddy server.

The entire site UI for XRss comes from a single HTML template file. This index.html includes everything from SQL queries and route definitions and handlers to htmx state transition attributes and tailwindcss classes, and developing it requires zero build steps (amortized).

Check out the source which manages to be at once banal and gnarly: https://github.com/infogulch/xrss/blob/master/templates/inde...

xtemplate preloads the whole template structure into memory and builds the router at startup, so responses to matching requests are rendered after a single lookup. Combined with direct queries to sqlite makes for a very snappy experience typically responding in less than 5ms. (Fingers crossed.)

There are various places where XRss could be improved (PRs welcome!), but it already delivers on its purpose of demonstrating the plausibility of xtemplate. See the xtemplate readme for an overview of what you can do with it. I think of it as 'PHP but the syntax looks like Go templates'.

https://github.com/infogulch/caddy-xtemplate

Let me know what you think! Does remaking PHP from scratch out of Go templates make me a lunatic? (yes) Is it a good idea anyway? (yes) What kind of web application do you think would be a good fit for a platform like this?




Some background for late viewers:

I found htmx recently and it's exciting to me because its potential to vastly simplify website development experience without compromising on user experience. One design principle that htmx is based on, Locality of Behavior, is particularly eye-opening. ( https://htmx.org/essays/locality-of-behaviour/ ) Yet despite htmx simplifying the frontend, actually writing the matching backend is still messy because existing tools funnel developers to separate concerns rather than co-locate behaviors.

xtemplate was written out of spite from being forced to jump between half a dozen files just to add simple backend functionality: define a new route, code up yet another repository, fight the ORM's stupid query generator, create a new handler, manually wire it up to a template, blah blah blah. Screw it, what if you just put everything in the damn html? I happen to be familiar with Go's template modules, and it turns out they are naturally suited to htmx apps because of their flexibility and the ease of defining and reusing inline template fragments.

So I ran with it and tried it with a todomvc-style app in the now archived `go-htmx` repo. Eventually I stumbled on Caddy's template module, and realizing that I could skip all the web server-related feature development by integrating with Caddy I rebased onto it to get a head start. The next thing it needed was a consuming project, small enough it could be completed in a reasonable time, but not so small that it's not useful. So XRss was born.


This is an excellent demo of what htmx can do to a web skeptic like myself. Everything just works as you’d expect!

Looking at the source I’m not sure I like the conceit of creating routes and programming in comments like that. But this feels closer to a simple RAD web framework than most stuff I’ve seen. Keep hacking away and you might have something great on your hands.


Definitely didn't work as I expected, but mostly just because I'm on mobile. I had to do a lot of extra clicks to do what I'd expect. HOWEVER, aside from UX it's functionally sufficient and that's more of the point, I think.

But just as a suggestion to OP: in mobile, clicking a feed should take you to that feed. Currently you click a feed, there isn't any confirmation of that selection being applied, and you have to close the menu to see the feed again.


oh yeah, same. definitely felt broken to me. had to read this comment then do landscape mode and i can see the problem is the menu takes up the whole screen on mobile.


"web skeptic". I'm pretty skeptical of embedded code in markup. Throughout the years my experience has been that the less code you have embedded in your HTML, the better. Optimally just stick with standards based HTML templates and you will always be forward compatible.


A nit, routes are defined by template name, not by comment strings. Though I get your point that overloading things can be a bit smelly. I comport that the smell is just like a nicely ripening cheese.

I had to look up the acronym, but a RAD web framework is exactly what I'm aiming to deliver. Thanks for the kind words. :)


I think there’s a bug on mobile: the user is initially promoted with a list of feeds, but nothing happens when they select one. It looks like there’s a button at the top right of the screen that you need to press to actually view your selection?


Yes the mobile view could be better. The buttons at the top should toggle between the feeds list and the items after you select a feed (it shows All Feeds by default). Ideally it would switch views for you.

PRs welcome. :)


I love the idea! I think htmx occupies a very interesting skill-set/use-case niche and I think an RSS reader is a cool example of that.

One piece of feedback: the UI would feel more snappy if there was a way of applying optimistic updates/signalling to the user the loading state. I'm not an htmx expert but I think you can do that with alpine.

Example:

When I click on the feed item, there's a short delay before the UI updates itself with page content. Sometimes the delay can take a few seconds.

Ideally, I'd see a simple loading indicator or an animation signalling the loading state, even greying out the element would be enough.

(In that particular case you could probably cheat a bit with CSS, by styling the :active state of the list item element, and then adding a very slow transition. But, that doesn't solve the general issue)

Edit:

Thanks @anyone explaining that this is achievable with `hx-indicator`. I never learn by just reading the docs so I guess I need to build sth with htmx.


you can use hx-indicator for a spinner:

https://htmx.org/attributes/hx-indicator/

depending on how aggressive you want to get, you can use the preload extension to make the responses snappier:

https://htmx.org/extensions/preload/


Nice, I didn't know about this. Thanks! I can imagine this could probably work quite well with View Transitions.


yeah, you can toggle on view transitions in a swap via an hx-swap option:

https://htmx.org/docs/#view-transitions

for now css transitions are more widely supported though:

https://htmx.org/docs/#css_transitions


I'm using view transitions (have to use Chrome to see it), basically just copy-pasted the example from the htmx site. I'd like to do a sliding-opening animation, but I haven't figured out how to do that yet.


HTMX actually has a built-in way to show loading states. You just have to add a child element with the class "htmx-indicator" and HTMX will fade that element in while it's waiting for a response.


Thanks! Now I'm looking for excuses for new side project to build with htmx


Nice, my RSS reader uses HTMX but the UI is really different, I usually see one article at a time that i vote up or down.


I based this design off of newsblur and google reader before it.

How do you use votes?


Use them train a recommender model; all the docs as processed with SBERT, I use k-means clustering to find 20 clusters and in each cluster it picks out the top 15 scoring articles on “what is the probability i will like this?” using the probability-calibrated SVM on the last 40 days of judgements. I also look at some other lists of articles like: most likely to be voted on HN, most likely to get a lot comments on HN, etc.

I used to run it on a 24 hour cycle and would get around to looking at maybe half of the 300 articles I picked out. Lately I just look at all 300 when I can and then it picks out another 300. So it is showing me better scoring stuff but not so fast to process it.

It ingested maybe 6500 articles this time so it is showing me the “best 5%” while the clustering makes sure I get some articles about sports, some arXiv papers on recommender systems (of course) and other topics.

If you look at what I submit to HN all of it was selected by YOShInOn first and secondly by me so that’s a good sample of what I see except I am into a few things that don’t play on HN (e.g. Premier league football)


Nice work and glad to hear that! If you ever want to chat RSS, please reach out.


Am I the only person for whom this looks like horrible, over-complex, write-only spaghetti code?


Probably not, but I personally disagree. It's a fully featured application in ~500 lines, with a proper database, web server, and simple yet extensible backend and frontend. Imagine how many more dependencies and complexity you would have to introduce to implement something like this in the traditional way.

Sure, you likely wouldn't want to maintain a more complex project with this stack, but IMO it's perfectly suited for an RSS reader. To me this is a prime example of solid full-stack web development, and I applaud the effort. Kudos to the author for choosing the right technologies to balance the features/simplicity, and integrating them so well.


The jury is out. Fwiw I found it surprisingly easy to add new features. My intuition is that there's a complexity asymptote that the code naturally reaches over time, and it won't get any worse.

What do you think about: https://htmx.org/essays/locality-of-behaviour/


Locality of behaviour is, on the whole, a good thing.

I say "on the whole" because there are always counterexamples to any maxim. The article realises this and mentions 2: DRY and SoC.

Writing good software is often a matter of taste.


Thanks for sharing!

I liked the idea of defining the handle path in the name of the template and the auto-reloading on change functionality.

I wish this was a stand-alone library that I could use in my custom Golang server. Do you know if something like this exists?


I'm considering factoring it out into a general library, it should be rather easy. Would you be interested?

You can also see my previous project, go-htmx for a previous version of the idea, though its missing some features.


Yes, that would be useful. Basically, what you have in https://github.com/infogulch/caddy-xtemplate/blob/master/tem... - but without Caddy dependencies and with a way to use any router library (I use gorilla/mux).

I would make the templates library take a callback function for every public template: func(method, path string, template).

Then the user could add any custom logic to register the route handler and execute the template with any application specific inputs.


I'll have to think about that. It currently uses path parameters from the julienschmidt/httprouter router implementation, which I think are pretty important. How would you expect to define and receive path parameters?


gorilla/mux supports parameters in the path as well. For example: "/posts/{id:[0-9]+}"

Passing the parameters from the handler to the template could be left to the user of the library.


Love it. Maybe not because of showcasing the power of htmx. I've been finding myself doing kitchensink projects in go (purely for fun) and integrating newer ideas is just so regarding! Where are you hosting this btw?


Thanks. :) I'm hosting on a cheap linode server.


This is awesome! I've become preconditioned to seeing slow buggy demos. This is snappy and a great representation of HTMX. Good work!


> Is it a good idea anyway? (yes)

I feel like there's a case still to be made for that answer!


:)


This is actually quite interesting. The whole setup looks like a modern take on PHP - connect your html to a database, all in one file. Except unlike PHP it's interactive html.


It's interesting that people are re-inventing parts of PHP in different ecosystems around this time. There is also the astro framework for example.

PHP has some properties that make it very suited for certain kinds of web development:

- stateless, very easy to reason about from a request/response cycle standpoint

- "serverless" and operationally cheap

- seamless HTML templating

- streams HTML by default

- batteries included

- straight forward and flexible first class data structures (associative arrays) with data literal syntax and value semantics.

- file based routing

Unfortunately, the PHP ecosystem has moved more and more away from that initial value proposition. Instead of cleaning and oiling this wonderfully productive and simple machinery, it wanted to grow into something else.

One can only imagine if PHP instead retained a focus on what made it unique and useful while making it more robust, secure by default and performant.

I wish it had focused on:

- making arrays even more ergonomic and leverage them more in general

- introduced a secure by default (escaping etc.) HTML template syntax

- introduced something like a load.php that can be used to keep some basic, global stuff in memory between requests

- improved on the idea of file based routing

- drastically improved error handling and introspection

As it stands now, it is on other ecosystems or even new languages to pick up the slack and try to capture what made PHP great.


Good summary, I made xtemplate with many of these ideas in mind. For example:

- Uses html/template which escapes content by default. This was already useful; e.g. the author name field is supposed to be a plain string according to the rss spec, but the google blogs include <name><company><department> tags which were automatically escaped by html/template. It's also easy to input raw html if desired, which I do after sanitizing it with the `sanitizeHtml` func (which uses the bluemonday lib) when displaying article content.

- It improves on file-based routing, by yes rendering matching files, but also by allowing you to add templates anywhere to handle any kind of request by matching method and path parameters.

- By default errors abort the request, but you can use the `try` function to get access to an error (if any) and handle it in-template.

- You don't need shared memory if you can query the db in 0.1ms :)


Doesn't seem to work on mobile...

Also try out my reader: https://catnip.vip


Mobile is much better now: https://xrss.infogulch.com/


Works on mobile if you select a feed the click the two arrow button


Very nice. I click on the pricing page and prompts me to log in. Good detail about showing the design system.


i need to register to see the pricing page?


[flagged]


There's the hacker news comment I expected. Everyone else was so nice, I was getting suspicious.

> the site looks like butt

Fair! Feel free to open a PR. :)

> no real benefit of using htmx here

Incorrect.

The xcaddy repo describes how to install it. If you just want to install xtemplate you can download caddy with it from the public caddy download server. Check out the xtemplate repo for details.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: