1. 26
    1. 6

      Gave this a quick try – I’ve been looking to move off of a Hugo-based setup for my personal website as there’s too much friction between thinking of writing something, and actually pushing things out. Couple of thoughts:

      • Domain idea is pretty cool, especially where per-domain CSS customization comes into play.
      • Being able to customize the base CSS would be great (currently it’s embedded in the header.html template).
      • Having a mixed public/private wiki is awesome, but wondering if there’s a way of running this as a purely private CMS (there’s a -private switch, but I still seem to be able to write public notes and create domains; perhaps a bug?)

      I’ll give this a more thorough review, thanks for posting!

      1. 2

        Author here - the custom CSS will apply to everything (except the search, but thats a bug).

        As to your other comments - I will say there are a lot of CMS out there and this one has limitations. I think the lack of custom domain is the biggest, and I can’t think I would use this to make a website that needs a custom domain.

        However, I’ve made a lot of CMS’s - offlinenotepad, cowyo, i.rwtxt to name a few…but rwtxt is what I always come back to for just personal notes. I’ve used it every day for years now and it does a great of job of storing all sorts of notes (and attachments!) that are instantly searchable. There’s something to be said for a really good and stable personal online notes. The best thing about rwtxt is that if I ever need a new feature I can implement one right away (versus using something from big G etc).

    2. 3

      I’d be sold, if the published part was static.

      1. 5

        Well, sqlite is almost as static as your journal filesystem.

        1. 5

          My static webserver disagrees.

      2. 3

        you trade that for having all of the data being in sqlite.

        1. 3

          I think the design choice is sqlite can store tons of small files in a single file with FTS.

          1. 2

            yes, you get full text search now, but sqlite has loads of benefits over plain files.

        2. 2

          Why does this have to be a trade?

          The CMS and the resulting website do not need to both be dynamic and stored in sqlite.

          I’d personally prefer running the CMS somewhere private, and hosting the (static) website just about anywhere.

          1. 5

            Then go use something like Hugo, etc. This lets you edit live, that’s a non-trivial task when the files are 100% static. There is a trade-off for this.

            Personally I just use Fossil-scm for websites anymore. I can host files, edit locally or remotely (live or not), sync changes, etc. It also is just a sqlite file.

            1. 3

              There is a trade-off for this.

              There doesn’t have to be. There’s no need for the CMS to actually dynamically render the resulting website for the public.

              An export button that creates a static website would be good enough. An automatically updated export would be excellent.

              1. 3

                I can’t imagine go + sqlite not being fast enough for almost all websites in the world that would ever use something like this just doing the rendering every page load.

                I haven’t looked at how this is coded, but if that is required for load reasons, then a cache would probably be a better solution.

                But you are right, one could store in sqlite the rendered version (or even out on temp disk), for example.

                But you are correct, technically. sure. I don’t see any reason to bother with the added complexity.

                Just turning on your nginx caching option(or other front-end handling the TLS cert) would almost certainly be 99% easier and achieve basically the same effect.

                1. 5

                  I can’t imagine go + sqlite not being fast enough for almost all websites in the world that would ever use something like this just doing the rendering every page load.

                  Static is simpler.

                  I don’t see any reason to bother with the added complexity.

                  Again, static is simpler.

                  Just turning on your nginx caching option

                  Now that’s insane. A cache frontend for a backend that’s dynamically-rendering static content.

                  Instead of just serving the static content directly.

                  99% easier

                  Than serving static content? You can’t be serious.

                  1. 3

                    yes, static content is simpler, but is it simpler for this project, the way it’s implemented currently? I’d argue no.

                    You have to render the content at some point. You have effectively 2 choices, you can render @ save time, and create , effectively, a static site, or you can render it at load time.

                    You seem to think rendering at save time is the better choice, Then you would save both copies, the raw MD file and the rendered HTML, put them both in your sqlite DB. Then at HTTP GET time, you can simply stream from the sqlite file the rendered version. (alternatively you could store the rendered content out in some file somewhere I guess… complicating the code even further. sqlite is often faster than open() anyway, so I’d argue that point also..

                    The problem is, it’s easy to have cache and sync issues. If you do it at save time, and there is exactly 1 way to edit, then the cache and sync issues basically go away.. but there is more than 1 way to edit, you can edit using any thing that can speak sqlite or calling sqlite CLI directly.. or using the web interface. The big feature of this code base is the ‘live edit’ feature of the CMS, so one could punt the problem, and save 2 copies in sqlite, the raw MD and the rendered version, and if you are so inclined to do it outside of the live edit session, then it’s your problem to update the cache also.

                    Alternatively, do it at read time(HTTP GET), and save yourself the headache of cache and sync issues. This is the simpler version. Seriously, it is. It was one sentence, vs a paragraph for rendering @ save time.

                    Complication matters. Static seems simpler, but is it really?? not always.

                    1. 2

                      sqlite is often faster than open() anyway,

                      Sure, but reading from sqlite is dynamic. Whereas any static webserver can serve a plain file. I prefer static webservers, as they are the simplest. This means low LoC count, which means easy to understand/audit/sandbox.

                      Specifically, I use openbsd’s httpd, and I would like to eventually move away from UNIX for my for public services whenever possible (e.g to a component system on top of seL4). A static website served from plain files is best.

                      1. 1

                        Changing the goalposts again, that’s fine I can meet your goalpost here too :)

                        Reading from a static sqlite file isn’t any more dynamic than open() on a file. They are both reading effectively static content in the above scenario of rendered content.

                        I agree from a security point of view, something like seL4 will be more secure, for some definitions of secure.. but at some point we are just messing around and not actually solving problems.

                        What is the security risks you are trying to protect from? Without identifying the risks, it’s very hard to mitigate them. Otherwise we are just playing security theatre games, for zero benefit.

                        What’s the worst case scenario here, that someone manages to get into a static content web server? Given proper permissions.. nothing. if they get in, rootkit and get write access, the situation is worse, but again, given static content the likes of a personal project, the consequences are equally trivial I imagine.

                        Anyways, you didn’t refute any of my statements above, so I’m glad we finally agree, static is not always better, or even simpler.

                        Like I mentioned way up thread, I like live-edit and I’m very lazy. I just use Fossil-scm for my websites. They are technically dynamic now, but it’s amazingly easy to make them go, I even get a built in forum and bug-tracking for feedback, email notifications, etc. I get 100% revision and history control and is audit-able, off-line sync capable, live edit capable, etc. Plus deployment is super easy, a single binary that does everything and backups are equally trivial as it’s a single sqlite file. Because of offline capabilities, I generally have a few copies laying about anyways and it’s all cross-platform.

                        1. 2

                          Reading from a static sqlite file isn’t any more dynamic than open() on a file. They are both reading effectively static content in the above scenario of rendered content.

                          My webserver doesn’t support serving from static sqlite files. Dynamic as in, I’d have to run cgi code in addition to my webserver.

                          Like I mentioned way up thread, I like live-edit and I’m very lazy.

                          Me too, thus I’d love a CMS. It’s just, while dynamic is good for me (the one writing articles), it is unnecessary for viewers. I currently use a static site generator, which takes Markdown as input.

                          I do not wish to change the setup of my public site, which is a static site.

                          What is the security risks you are trying to protect from? Without identifying the risks, it’s very hard to mitigate them. Otherwise we are just playing security theatre games, for zero benefit.

                          On my (public) personal sites, I simply want to minimize complexity, which should mitigate a broad range of security risks. It’s a win/win strategy.

                          1. 0

                            Your webserver could support serving from sqlite files, if it so chose. that’s basically all rwtxt is doing.

                            Anyways, I feel like we aren’t having a productive conversation anymore. I already covered your supposed complexity in a previous comment.

                            edit: also in this thread, but in a different comment chain, I commented on security analysis, which also applies here.

        3. 2

          you could spider the dynamic version of the site quickly with httrack or something to produce a static version.

          1. 1

            Just turning on your nginx caching option(or other front-end handling the TLS cert) would almost certainly be 99% easier and achieve basically the same effect.

            1. 3

              In terms of the security analysis it’s a completely different thing to have a dynamic application running exposed to the internet, even if you cache it.

              1. -1

                OK, I think I get your point(that in security complexity hurts you), but I think we have very different understandings of security analysis, so I’m going to write some stuff here.

                You can’t talk about security mitigation’s without talking about specific risks you are trying to eradicate.

                Nginx is dynamic. openbsd’s HTTPD is dynamic. any “static webserver” is dynamically taking inputs (HTTP GET requests) and mapping them to files out on a filesystem. Nothing is stopping nginx from serving /etc/shadow or /home/rain1/mysupersecretthinghere. Except some configuration(and hopefully) some file permissions.

                This is no different than program X taking an HTTP get, opening a sqlite file and serving the results out of a column. It’s totally doable and equally “dynamic” for the most part.

                I think what you are trying to say is, if rwtxt(since we are in the rwtxt thread) happens to be compromised(and I get complete control of it’s memory) I can convince rwtxt to render to you whatever I want.

                Except the same is true of any other webserver. If I compromise nginx serving files from a filesystem(in the same way above), I can also have it render to you whatever I want.

                There is basically no difference from a security analysis point of view. between rwtxt and a sqlite file and nginx and a html file. Both files can be read only from the web server perspective; of course then rwtxt’s live edit will not work, but hey, we are trying to be SECURE DAMMNIT! lol.

                The difference here, from a security analysis perspective is, nginx is way way way more popular than rwtxt(today, who knows about tomorrow), so the chances of finding a complete compromise of nginx is, one hopes, much much harder than rwtxt, a tiny project mostly(completely? – didn’t look) written by one person. Of course the opposite is also true, way more bad people are looking at how to compromise nginx, then rwtxt, there is something to be said for security through obscurity, in a vague sort of hand-wavy way… as long as you are not an active target of bad people.

                Hence why we go back to: You can’t talk about practical security mitigation’s without talking about specific risks you are trying to eradicate.

                So mostly your sentence makes no sense from a security analysis perspective.

                OK soap box over.

      3. 1

        You may be able to get most of the benefits of static publishing by putting a CDN/caching layer in front of the CMS.

        1. 3

          That’d make hosting the actual website more complicated, rather than easier. Adding layers isn’t the solution.

          I do not wish to expose the CMS to the general public. The CMS is relevant to webmasters (authors) only.

          I just need an export button I can press anytime to get a static site.

      4. 1

        Why is that important for you?

    3. 2

      This is great.

      As others have pointed out, an export button would be great. Support for images would also cover a lot of use cases.

      But let.s not miss the beautiful simplicity of this self contained solution. Even installing or configuring nginx, simple as it might be, is not free.

      This is great for intranets, hackatons, or even small temporary websites exposed to the web.

      1. 2

        There is an “Download Data” button that points at: https://rwtxt.com/DOMAIN/export, but it exports markdown files, not HTML as some commenters wished for.

    4. 2

      Where is the line between CMS and file manager?

    5. 0

      yeah right