Fork me on GitHub
#clojure
<
2022-08-22
>
Empperi12:08:37

Please tell me there is a good Headless CMS implementation done with Clojure. I'm going absolutely nuts with these nodejs based implementations which all suck monkeyballs in one way or another and I'm getting sick of it. I'm more than happy for a library solution that gives me bunch of stuff for free and I can work from there

augustl12:08:40

thanks for the mention, @U07FCNURX! Back-end is typescript and AWS only at the moment.. and it’s very (very) beta 😿 And I’m not sure if it covers the category “headless CMS”, as there are no tables and schema, it’s more of a “google docs with react components” type situation partyparrot

Empperi12:08:55

Then it isn't unfortunately suitable for my use case, but thanks anyway 🙂

Empperi12:08:37

Need a proper database, need (preferably) graphql endpoint and need to be able to run it on google cloud 🙂

Empperi12:08:37

I have a feeling I should do this myself but unfortunately I do not have time for that

augustl12:08:39

yeah, that makes sense! Most people seems to mean tables and data structures with automated GUI when they say “Headless CMS”

Empperi12:08:05

Yeah. This is a proper use case for a headless CMS with multiple delivery channels and so on

augustl12:08:07

there’s always the #1 in this space, Sanity. Not self-hostable though, but people have great success with web hooks that lets you store final output locally

Empperi12:08:27

Currently working with Keystone

Empperi12:08:42

Evaluated about a dozen differnent alternatives before I went with that

Empperi12:08:48

But that too is proving to be... Sucky

Empperi13:08:19

The fact that it doesn't log almost anything (even when setting their logging settings to something sensible) doesn't really increase confidence for production usage

augustl13:08:37

what use case lead you to the requirement of it being written in Clojure? In my experience, a headless CMS is usually a black box that you get data from via APIs and the implementation language is not really relevant

Empperi13:08:50

No other use case but I work fastest with Clojure

Empperi13:08:03

And I need to modify stuff heavily

Empperi13:08:10

...when we go forward

augustl13:08:19

I suppose headless CMS is many things… I’m not that familiar with the node library versions of this. You’re looking for something with a programmatic API that you can embed in your own system?

Empperi13:08:19

Well, the story is a slightly more complex. Naturally, there's a tight(ish) deadline and need to get stuff out live by then. There's specific feature set that needs to be finished. Then there's the future vision and what is needed there

augustl13:08:34

(I’m just asking for my own curiosity now, and not really making any attempt whatsoever at helping you find a good CMS 😇)

Empperi13:08:54

My current plan is to take a headless CMS and use that for the time being but most likely we'll write everything from scratch a bit later when we have more resources and time

Empperi13:08:37

GraphQL endpoint is preferable due to it's flexibility especially if one takes a blackbox kind of CMS implementation

Empperi13:08:01

But naturally it's not a hard requirement

Empperi13:08:49

This is a bit of a rant from my side and I guess I'll keep on working with Keystone for the time being but if there had been a really great alternative for Clojure I would have been tempted 🙂

augustl13:08:52

sanity + webhooks is definitely worth looking into, at least! The CMS itself is a black box, but all changes gets posted to a webhook, where you can write any code you want in your preferred programming langauge, and extract data from Sanity through its APIs, and store locally in your own system whatever you need

Empperi13:08:25

I did look at sanity and didn't go with it, can't remember anymore what was the main reason for it

Empperi13:08:24

One of the things that bugs me a lot with all these nodejs implementations is their insistence on creating their own CLI tools for running those. Why? It's not like they are being setup by software development imbecils? Have they ever heard of IaC?

Empperi13:08:37

I do not want stuff like xxxx deploy heroku

Empperi13:08:18

All of this brings me bad vibes from ORMs where they make easy things even easier and hard things impossible

Empperi13:08:40

Simple Made Easy. They do not do that

augustl13:08:57

haha yeah, having a good CLI UX and being fancy etc seems to be something the Node crowd enjoys 😄

Empperi13:08:32

Configurability should be the king

Empperi13:08:46

So that the product they are creating doesn't have to try to solve all use cases

Empperi13:08:24

You want to store images somewhere? Great. Provide out-of-the-box providers for S3 for example. But also provide an easy way to plug your own provider there that you can write if you have a different need

maleghast13:08:21

#xtdb + #juxt-site from #juxt may be of assistance - it's a GraphQL resource server that can be used as a headless CMS

Empperi13:08:47

I actually looked at that combo with interest

Empperi13:08:01

But it is maybe a bit too much work right now. But I am going to take another look later when I hopefully have more time for this

cjohansen14:08:48

We’ve had great success with Sanity and a Clojure backend

cjohansen14:08:11

We treat Sanity like a database with a really good editing interface, like @U0MKRS1FX mentioned

didibus17:08:45

I was going to say https://www.hyperfiddle.net/ but I think it's still in development.

Daniel Tan12:08:18

+1, currently I'm stuck with strapi because it has two main features: user login connectors and the ability to modify everything in the codebase per instance, aka I can white label strapi or add functionality easily. This is not available from Supabase etc

Daniel Tan12:08:38

However it would be great if there's one in clojure so I can just use clojure instead of NodeJS

Adam Helins16:08:01

I sometimes wonder about the idea of writing changelogs for Clojure libs and apps in EDN. When properly formatted, EDN remains quite human readable and maybe it could lead to interesting tooling. E.g. A helper function that filters and outputs only known breaking changes. Does it make any sense? Or does it sound like crazy talk?

⬆️ 3
isak16:08:28

It would be easier to extend the normal markdown changelog conventions with more metadata than to make custom visualizers and/or editors for this new markdown format. So it doesn't seem worth it to me.

respatialized16:08:53

The only reason we use plaintext files for this kind of thing is because git is file centric and doesn't allow you to store structured data in it

respatialized16:08:20

I would much prefer to store changes to structured metadata about the code alongside the code; I wrote a bit of a rant about this a while back https://respatialized.net/against-metadata.html

isak16:08:42

In github markdown you can also add tables, diagrams, etc: https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/

respatialized16:08:42

IMO we should stop storing important information about our code and its history in flat file formats where composition is impossible, consistency is not enforced, and you have no query capabilities, so I'd argue that EDN doesn't go far enough

respatialized16:08:24

But it's still an improvement over endless "update README.md" commits

vemv16:08:59

It sound to me like too much effort that will result in little adoption anyway You can use the fanciest changelog format and still screw up :) i.e. it all comes from a human. In the end there a couple things that don't lie: • Diffs, e.g. I post https://github.com/seancorfield/next-jdbc/compare/v1.2.780...v1.2.796 when suggesting an upgrade at work • Specs/Schemas (sadly there's nothing even close to standarization in clj... so no automated tooling would shine today)

vemv17:08:36

It wouldn't be too crazy to build today a tool that compared the ASTs (or kondo analyses, w/e) of $lib v1 and v2. It could tell basic things like var changes, arglist changes.

javahippie17:08:45

I am afraid @U04V15CAJ beat us to that, again 🙂 https://github.com/borkdude/api-diff

🎉 1
Ben Sless18:08:16

What I'd like to have to support that is semantic diffs,think next level from structural diffs ala edit script

Drew Verlee03:08:03

The clojure deps tool "outdated" will link to a github diff range of it can. I was thinking about trying to find and add change log data to that.

Drew Verlee03:08:20

Edn would be an improvement, but not by much because that information is meant for humans to read mostly.

Drew Verlee03:08:51

Like others have said, structural diffs would be the truest way to know changes, but that's too much effort for most users to go through to read. So your still going to want to have a high level overview.

Adam Helins10:08:41

Thanks for your opinions, very interesting I guess that beyond EDN, what I was really looking for is just better programmability and your answers go towards that.

domparry19:08:23

Are there know “known” patterns for the kind of use cases where you would add meta data to a map, but where transients are used for performance purposes? Playing around in the repl, (with-meta (transient {:foo "bar"})) {:my-meta "foo"}) throws an error, and I can’t find any docs for adding meta data to transients.

hiredman19:08:15

I have not used metadata on transients, but clojure has 2 ways to attach metadata

hiredman19:08:02

One for mutable things (identities, references) and one for immutable values

hiredman19:08:19

transients are mutable

domparry19:08:06

Ah. Thanks. I’ll hunt down the with-meta equivalent for mutable things. That’s a good steer. Thanks!

hiredman19:08:17

I also suggest considering the alternative to transients and metadata, things are usually better without them

domparry19:08:07

I usually don’t use transients. This is a performance sensitive use case though, and it’s a significant penalty to use a plain map here.

hiredman19:08:49

If you look at into, it turns the collection into a transient, pours the values in, makes it persistent, then copies metadata

domparry19:08:17

That’s what I’m doing now too, but I need to gather the metadata during a reduce where the accumulator is a transient.

emccue22:08:03

Why not have the accumulator be a pair of the transient and the metadata?

domparry13:08:24

That’s actually a great idea….