Show HN: XRss – RSS Reader and web stack demo (xrss.infogulch.com)
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?
48 comments
[ 3.6 ms ] story [ 122 ms ] threadHow do you use votes?
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)
PRs welcome. :)
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.
- 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 :)
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.
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.
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. :)
Also try out my reader: https://catnip.vip
> 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.
I feel like there's a case still to be made for that answer!
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.
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/
https://htmx.org/docs/#view-transitions
for now css transitions are more widely supported though:
https://htmx.org/docs/#css_transitions
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.
What do you think about: https://htmx.org/essays/locality-of-behaviour/
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.
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.
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?
You can also see my previous project, go-htmx for a previous version of the idea, though its missing some features.
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.
Passing the parameters from the handler to the template could be left to the user of the library.