Meandering Soul

This day is done, I'm going home.
eFranes Penguin Avatar

Fountain Update 0x01

19
Oct 2024

Remember how I proclaimed “I want my own CMS and it’s going to be magical?” Yeah.

Since then, I have done a lot of thinking. As established, there’s a grand vision to Fountain that has been meandering through my head for years already. As said before, I could go back through my old repos and notebooks and find the exact time and date I first started sketching and thinking about the system architecture. But what good would that do? After all, as any financial advisor will tell you at least five times a day, past results are no indicator for future success.

To future success

The thing that held me back most in the past is wanting to write the whole thing to then replace my current setup. While an admirable approach, it’s prone to slow down to a halt as soon as the initial excitement wears out.

The solution, hopefully, now is to break down the big idea into small, usable milestones. Knowing me, there will still be large gaps and massive changes of interest or needs along the way so what I will not do is sit down and make a full plan.

So what’s been happening?

As some of you may know, I worked on a Vala based version of Fountain for a while. Also with long hiatuses but still, it was quite usable in the end. It could deliver content on a fefe-style website and was fully git-driven, meaning there was a separate content repository that was pulled by the server and used to generate the websites. Since I didn’t quite feel comfortable enough with continuing this project in Vala I eventually stopped working on it. That may also just have been the aforementioned excitement drop-off.

For a while now, Vapor has been on my radar as a pretty stable, well maintained base framework for possibly doing the same thing in Swift. However, as I said above, I want usable milestones. Therefore, I need to find a way to move the current setup for this website here from Hugo to Fountain. Time to do a small architecture comparison:

HugoFountain
Static Site GeneratorFull CMS
Everything in one RepositoryMultiple repositories, at least content and styling separable
No builtin commentingIntegrates with Fediverse
Can run offsiteNeeds runtime on server

Fountain is different from Hugo. In many ways very different. I am not writing another static site generator. There’s enough of those and their existence has it’s place in the stack forest but they’re not what I want. I miss the olde days of blogging but - for now even more reasons - I don’t want to go back to Wordpress. What I do want to contribute to is the ease of use and simplicity Blogger, Wordpress, and even Tumblr used to provide. That is a longterm goal. Working towards that leads to the above architecture requirements.

Fountain needs to be able to react. Its content needs to be openly accessible and modifiable - even Wordpress to this day is a closed ecosystem, you can only modify the site content within the software.

It needs to be versatile - content comes in way more different forms than it used to. We don’t just have articles with categories and tags anymore. The widespread proliferation of easy to use static site generators enabled people to think less about structuring everything into (blog) posts and more about how to group things. Historically, hyperlinking and deep structuring were the Webs’ greatest powers. Todays siloing content aggregators, Facebook, Twitter X, Instagram, and the likes are very focused on people staying on their sites as long as possible. This works because we’re used to the limited forms of content we can provide and consume there. However, I don’t want to be in a Web that discourages offsite hyperlinks and limits and controls the creative output. I want to be in a Web that thrives on content, not ad-revenue increase. I believe that Web is still possible and just needs a little technology push. The true social network is not one place, but a network of places.

Fountain therefore needs to be interconnecting with the world. Back in the day, we mostly used Comments, RSS or Atom Feeds and later Pingbacks and Tracebacks for that. Those worked great at the time to foster communities. However, back in the day we weren’t centralised. Yes, there was already huge hosting players like Blogger and later also Wordpress and Tumblr, but, crucially, the content and moderation wasn’t centralised. Decentralisation is the key to reclaiming not only the web, but in my opinion also the generally lost diversity in opinion we as a people desperately need to thrive. This is where the Fediverse comes in like a knight in shining armour. I don’t just want comments or links to your blog. I want you to be able to write about my content wherever they want to but I want there to be a thread. Let’s weave this thing together again.

And, finally, it needs to be able to be run standalone with moderate technical expertise. Wordpress did and still does that perfectly. Fountain won’t be able to achieve that ease of use in a very long time if ever just because Wordpress was one of the biggest drivers for the pervasiveness of PHP hosting solutions. Not choosing PHP but Swift automatically leads to more requirements on a setup. I am fully aware of that but the benefits of a compiled modern language completely outweigh the drawbacks. And, with Docker and other container solutions, a lot of the hassle can be automated away.

A first milestone

Laying the foundation of Fountain. That sounds kinda precocious, doesn’t it? Extrapolating from the above architecture comparison and brief project history excerpt, it’s “obvious”, that I’m starting with a Git(Hub) communication server.

  1. I already have a running website. It is currently auto-deployed on push via GitHub Actions which works flawlessly.
  2. I need a reason to deploy a fountain server, that is, it needs to be something useful and I need it to be up and running rather sooner than later so that I don’t loose interest in the project.
  3. I want to separate content from code.

These three requirements mingle quite well:

  • I can easily extract the content with git subtree and push it into a separate repository
  • I can send push events for that subtree repository to Fountain
  • I can have Fountain trigger a pull and merge workflow on the main repository

I am fully aware that none of these requirements need the elaborate setup the result will end up being. Not delulu. Yet. Starting a project like this needs a solid foundation. After this, I will have gained some experience with Vapor, rekindled my acquaintance with the GitHub API and deployed a first little running server which will start to give me insights into ever simplifying the setup in the future.

Visibility

I did and do a lot of open source software development. So far, this was focused on small-ish libraries, the odd Vue component and the likes. Historically, my communication around these efforts has been very sparse to say the least. At best, I did open issues on GitHub containing some of my plans but still, there generally was silence aside from commits.

This I want to change. So here’s a different approach for Fountain: I will open source most of it. Why not everything? I don’t want to say all of it and later regret that decision. In my wildest dreams I will eventually put everything out in the open. Importantly however, I want to make all parts of Fountain open that are required for what I - or maybe at some point a community - consider core functionality. I simply do not know what that will entail yet.

Additionally, I want to keep making these posts. I am not ready to put a schedule on them yet, but they keep me accountable and at the very least force me to plan one step ahead.

At the moment, these posts are everything there is to see publicly. I am currently implementing the first milestone and once that is working satisfactorily for me I will consider flipping the switch on the repository. I may also decide to keep it closed until it is a somewhat self-sufficient platform. Setting up the communication server is a great first step for me, but at this moment it feels wrong to publish that as a software.

But don’t you just want to make money off of this in the end?

Yes. I do. At least I hope to. Making money of software is kind of my vocation. Here’s the thing: I think there’s a sweet spot between making (part of) a living from something and still contributing to the greater good.

There’s also different options. Of course there’s the almighty SaaS/PaaS construct looming in the distance. But there’s also just good old GitHub Sponsors and other reward systems. We’ll see.

For the time being, this is not my aim for this project. My aim is to keep going and find out if I can even get it to move towards the direction I’m dreaming of.

This is a post about Fountain. Fountain is a new kind of web publishing software I am working on. If you want to keep up with news about the development journey please don’t hesitate to subscribe to the Atom feed at https://meanderingsoul.com/stmfd/index.xml.

  • Published on October 19, 2024
  • 1605 words

Introducing Fountain

01
Apr 2024

The Problem

The distance between being motivated to write here again and actually writing here again could not be greater as it is. I’ve been telling people I have reactivated this site and I want to write more again. But I don’t. And the only reason is that I dread creating new posts. Which is ironic because the whole reason this site looks very different from a couple of months ago is that I redesigned and - to some extent reprogrammed - the whole thing in Hugo to have a fresh start. So, in an effort to dig down on what is stopping me, here goes nothing:

The structure

Having built this on Hugo, there’s tons and tons of nested folders. Which is okay because content that goes content/stmfd/2024/04/my-post-title does make sense in my head. What throws me off when setting out to write is that right next to that all of the logic and layout of the site are situated. A simple solution here might be to only open the content folder and leave all the others alone.

That however is only half of the pain relief.

The real pain is that my brain doesn’t compute writing blog entries or stories the same way it does code. The above mentioned path makes perfect sense in my code brain. It’s well structured, it contains all the required information, everything is about this is reasonable. But. Everything about this path disturbs my creative mind. Beginning with the fact that I even have to think about it. Like post titles. Why, in higher-being-of-your-choice name do I have to think about the title of something I’m just in that moment pouring out of my mind?

The editor

This one is more tricky. As I am writing this, I am typing into Obsidian, which for better or worse is currently the tool for my second brain. That works. Obsidian feels non-code enough to lift my mind out of looking at everything all the time all at once mode into admiring the donut and taking a step back. Unfortunately, this isn’t the final home for this text. In Hugo, like in pretty much every static site generator, content is kept alongside the configuration. That, for better or worse, triggers my coding brain. The beauty of Apples products isn’t so much that they look good on the outside. The beauty of Apples products is that they are designed well down to the PCB. I – conditionally, but that is an other post – love Apples products. I love the philosophy. I feel good in a clean environment, offline like online. Writing text in one place only to temporarily escape the implications of the other feels wrong.

Now, I don’t want to get to a point where I can comfortably write posts in VS Code. While being a mediocre modern replacement for the forever missed Sublime Text 2, it is by design not a prose editor. You might venture to say Obsidian also ain’t. True. We’ll get to that.

The format

Markdown is by far the most versatile Hypertext reduction format out there. Yes, reStructuredText is easier to write, yes WikiText is much more powerful, yes. All of those are standalone formats however. Markdown isn’t. Markdowns’ whole original premise was to convey semantics without obstructing the content even if visual formatting fails. That, again, works fine for my coder brain. And in part, no thanks to Obsidian, it works well enough for my creative brain too. And it is fast to write, once internalised.

It is in any case not pleasurable. Not as editing experience, not while looking at it on git diffs. Not ever. It looks like code, because, in a way, it is code. A dumbed down, prose-accomodated version of code, but nevertheless, it’s code.

My issue isn’t so much with the formatting indicators. Obsidian especially has a very nice way of dealing with those. Just showing them when actively in their context keeps the disruption to the required minimum. On the contrary, I would even go so far as to say that Markdowns formatting indicators are its greatest strength and should be part of every text editor’s core behaviour. I mean, even Google added it to Docs, albeit in a oftentimes strangely behaving way.

My issue is with the writing experience feeling technical. I cannot quite put a finger on what I mean by that. Some pointers would be other editing programs I’ve used in the past. First and foremost Scrivener, but also WriteRoom. The latter sadly not having been updated in more than a decade. There’s a fun way to be reminded of one’s own aging.

The solution

A little bit of history

There’s a (private) repository on my GitHub where the first commit says Date: Sun Feb 12 12:56:45 2017 +0100. That is a while ago. There is other repositories on backups, some of those burned DVDs (remember burning CDs and DVDs, if not, you’re too young for this section of the post, but welcome!) that date back years before that. What’s in it? Attempts to fix the above I abandoned for various reasons.

For many years, the answer was Wordpress. Wordpress was and is arguably the Platzhirsch for single or (small) team web publishing. Wordpress also very much doesn’t make me happy. I will not bash it, but I also won’t use or recommend it ever again.

What’s the alternative? Or, more precisely, why is this post in the devlog section and not on the main blog? Well, for as long as I can remember, I have been dreaming about building my own CMS. Fortunately, in the beginning I was young enough to not realise the amount of effort that would take. Out of that dream, the most relevant remaining tidbit is content editing and publishing that doesn’t have too much but grows with the needs.

That repository I mentioned is named Fountain. Fountain was supposed to be my solution. Since I am not stupidly young anymore, I reduced the scope from a full blown CMS to something more akin to a blog slash static site manager. I have a pretty clear vision of what that thing should be and do and what it shouldn’t be. I made one mistake: I started writing it in Vala. Now, don’t get me wrong. Vala is a great programming language and I will likely continue to use it where applicable. But it is also very much married to Linux even though GTK as it’s basically required foundational library tries very hard not to be Linux-limited. Using Vala hindered me more than I want to admit and lead to the slow death of the project. Well, no, the patient is not dead. Let’s go with a cryo-chamber frozen until needed by the world again sort of situation. That feels less harsh.

Fountain is supposed to be my solution.

Going with Hugo was and is only intended as an intermediary step. The previous setup was, for several reasons, not maintained for a couple of years so a refresher was necessary anyway. I had waited for Fountain to get to a point of being ready to be that successor and to be fair, in many ways it is, but in many other ways it isn’t.

Is the solution to just not write until that magical Fountain is finished? Most definitely not! (Most defiantly not?!)

The solution is multi-faceted:

  1. I need to code a few things that are likely technically more throw-aways onto the Hugo setup but nevertheless necessary for peace of mind:

  2. Fountain needs a rebirth

Making things bearable

The goal for now is to make my current setup work for my mind. To allow myself to pour my thoughts into writing despite not being at peace with the publishing system.

This means I will likely invest a little time here and there to write little helper scripts and stuff. This section of this post exists to give me permission to whatever time is required for this into a system I do not intend on keeping longer term.

This is what we do as programmers. We create things, than we are unhappy with them and we throw them away and create something new. “Beauty is terror”, Donna Tartt once wrote. Such is the way we code. Everything made from nothing must become nothing again.

Fountain, again

In the spirit of the luck throwing money into Fontana di Trevi is supposed to be bestowed onto the beholder, I want to throw some quite radical change at fountain: A rewrite.

A good rewrite starts with boiling down the requirements to what is actually necessary. This time, to keep myself accountable, I will do a lot of that in public from the beginning. Maybe not the code, but at least regular rapports and maybe even discussions of some form somewhere.

So, long story short: I am lowkey starting a side project again I have been in a co-dependency with for the past six to ten years. Stay tuned. I promise it’s not yet another static site generator. It’s also not a CMS. Remember? I’m unhappy with the status quo. More on this next time – whenever that will be. At some point, I might set a schedule for updates and ponderings, right now, I don’t see myself able to.

  • Published on April 01, 2024
  • 1559 words

Creating efrane.com Or how to inline styles with Jigsaw and TailwindCSS

25
Jul 2020

Recently, I finally got around to designing something of a portfolio website for me. There really is never time to do these, is there? You can head over to GitHub to view the source if you want, no need to keep it private. 

The general setup is a Jigsaw-based static site using TailwindCSS as style framework. The whole site does not have a single line of JavaScript in production which – surprise! – massively simplifies the setup! (Also, like, loading times are amazeballs.)

Decisions

Before deciding on the frameworks to use, I set up some constraints for the design and more so for the technical foundation of the site:

  • Graceful degradation on older browsers
  • Very good accessibility
  • Responsive-ish layout
  • Fast
  • Low-barrier content modification

Along came also some quirky demands like wanting to use flexbox for layout and having Twig or Blade as a Template Engine as I am most comfortable thinking template logic in those. I also wanted to write as little as possible server or generation code as this site will – for the foreseeable future – not have any dynamic content. Nevertheless, some kind of content editing that can be easier than always writing everything in HTML was added as a nice-to-have.

In my toolbox, these requirements form a straight path towards static site generators. Among these, since I am well-versed in Laravel, Jigsaw is the obvious choice for me. One never knows if there’s any modifications to be made and it always helps to know ones way around the underlying architecture.

Choosing TailwindCSS as a style framework was a no-brainer. It is a wonderfully simple solution and I find myself clicking with the utility-only approach.

Getting it done

Jigsaw provides several events to modify and extend the build process. Since my goal was to add content to the resulting HTML files after all other build steps, I opted for adding a handler on the afterBuild event:

1
2
3
4
// in Jigsaw's bootstrap.php

/** @var $events \TightenCo\Jigsaw\Events\EventBus */
$events->afterBuild(InlineStyles::class);

The Inline Styles event handler is of course where the magic happens. First, all built html files need to be gathered, Symfony’s Finder component is great at that:

1
2
3
4
$htmlFilesFinder = Finder::create()
            ->in($jigsaw->getDestinationPath())
            ->name('*.html')
            ->files();

Then, we can fetch the compiled CSS and inject it into a style tag in the head using SimpleXML:

1
2
3
4
5
6
7
8
9
$htmlFile = simplexml_load_file($htmlFilePath);

        $cssPath = $jigsaw->getDestinationPath() . (string)$htmlFile->head->style['data-src'];

        $cssContents = file_get_contents($cssPath);

        $htmlFile->head->style = $cssContents;

        file_put_contents($htmlFilePath, $htmlFile->asXML());

The full code is available on GitHub: http://github.com/eFrane/efrane.com.

  • Published on July 25, 2020
  • 419 words

A mermaid.js Plugin for Vuepress

16
Oct 2019

Since the last time I wrote about integrating Mermaid with Vuepress the latter matured to version 1.0. With that came a much more refined plugin interface - or maybe that existed before and I just didn’t notice it in the docs. In the meantime, I have been implementing that previous approach in a growing number of documentation sites and figured that having this as a plugin to a) reduce the hassle of getting it to work to basically zero and b) stop copying a bunch of code around would be a good idea.

So, without further ado I present vuepress-plugin-mermaidjs. When you do the search on npm, you will unfortunately find another package named very similar (vuepress-plugin-mermaid). One might ask now, “eFrane, why didn’t you just contribute to that one instead, wouldn’t that have been the healthier choice for the ecosystem?” Yes, it would have. Alas, the GitHub Repository for that plugin is empty and it doesn’t have a readme and wasn’t updated in over a year. All in all, that feels like an abandoned package to me. So that’s why I decided to publish my take as a package. 

NPM Package: https://www.npmjs.com/package/vuepress-plugin-mermaidjs
GitHub Repo:https://github.com/eFrane/vuepress-plugin-mermaidjs

  • Published on October 16, 2019
  • 194 words

Symfony Console Additions v0.6.0

21
Sep 2019

I released [efrane/console-additions](https://packagist.org/packages/efrane/console-additions) v0.6.0 today. More than a year after the last bigger release this probably could have been a v1.0. However, I still feel like there’s some fundamentals I do with Symfony’s Console component in my everyday work which I would like to extract into a reusable form in this library.

So, what’s changed?

For one, this development episode was focused on reorganising the code. There’s still very few files in the repository but that doesn’t mean that there wasn’t room for optimisation. The result of this is, that the tests folder now resemble the folder structure of the src folder, thus making it easier to find the corresponding test file.

The bigger change is a partial rewrite of command batches. Before, the Batch class internally managed every possible action as a combination of strings and weird arrays. This type-conglomerate lead to a quite a few ugly places in the code which felt like they might break at a moment’s notice. Since this version, Batch internally relies on Action classes which know how to handle themselves. This also means, that Batch just became that much more powerful since all Batch wants to know about them is how to represent them as a string and a way to start their execution:

1
2
3
4
5
interface Action
{
    public function execute(OutputInterface $output): int;
    public function __toString(): string;
}

Usable actions are now:

  • StringCommandAction - This handles executing console commands given a full command signature
  • InstanceCommandAction - No need to do string parsing of a signature? Pass a command instance to this one!
  • MessageAction - This is your basic echo action. Especially when PHP-izing former shell scripts, this can come in quite handy
  • ProcessAction - Pass a configured Process from the Symfony Process component to this one
  • ShellAction - Just want to execute a shell command and don’t feel like configuring the process yourself? This one is there for your convenience!

All of the built-in actions have convenience methods on Batch, e.g. $batch->addProcess() or $batch->addMessage().

Along with these internal updates came the jump to PHP 7.0 or newer as a language dependency and Symfony Components 3.4 or newer are required to work with this library now. The latter also means that string parsing for commands in $batch->addShell() has been deprecated and will be removed in the next release. I highly encourage any user of this library to switch to the array-Syntax.

  • Published on September 21, 2019
  • 403 words

Adding mermaid.js support to Vuepress

22
May 2019

I recently set up Vuepress for the first time to create a documentation for a new library I am working on (more on that in a future post). Since that library will do a few things that might appear sort of magical it seems like a good idea to add a few explanatory graphs to the documentation.

Now, what tool combines markdown-friendliness with creating graphs? Yep, you guessed it: Mermaid.js.

There are numerous ways of making Vuepress do things it can’t by default:

  • You can overwrite the whole theme
  • You can add Markdown-It plugins for additional markdown processing
  • You can add global components

The long story here would be to elaborate on why overwriting the theme is not an option and the plugin route didn’t pan out. But let’s not bore ourselves with that story. So yeah, I created a new global component in .vuepress/components/Mermaid.vue and worked away. However, it’s unfortunately not exactly that simple. Since Vuepress is a SPA or rather even an PWA, rendering works a little bit different. Which in short means that it’s very easy to get something to show up on first load of a component but there’s a little work involved in having things work after navigation. The technical background to this can be referenced in the vue-router Documentation.

What I ended up with is rendering the mermaid graphs to SVG and then rendering the SVG in the component’s render() Function:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import mermaid from 'mermaid/src/mermaidAPI'

let graphIdCounter = 0

export default {
  name: 'Mermaid',
  data() {
    return {
      svg: undefined,
      graph: this.$slots.default[0].text
    }
  },
  render(h) {
    return h('div', { domProps: { innerHTML: this.svg }})
  },
  mounted() {
    mermaid.initialize({ startOnLoad: true })

    let renderDiv = document.createElement('div')
    document.body.appendChild(renderDiv)

    mermaid.render(
      'mermaid' + ++graphIdCounter,
      this.graph,
      (svg) => {
        this.svg = svg
        document.body.removeChild(renderDiv)
      },
      renderDiv
    )
  }
}

Alas, this was not quite the end of it. I would have hoped that I’d be off to the races with yarn add mermaid. That’s not even close. Here’s the full list of dependencies you’ll have to add:

  • mermaid
  • sass-loader
  • node-sass

After this, adding mermaid graphs anywhere in the documentation markdown is as easy as

1
2
3
4
5
<mermaid>
graph TD
mermaid-->isAwesome
isAwesome-->mermaid
</mermaid>

Which then renders to:

Update (2019-10-16): I published an npm package that provides the <mermaid>-Component.

  • Published on May 22, 2019
  • 387 words

Get the number of days in a month with moment.js

09
Dec 2015
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var date = moment();
var currentMonth = date.month();

var daysInMonth = 31;         // Every month has 31 days
if (currentMonth % 2 == 1) {  // except every other month
    if (currentMonth == 1) {  // and then there is februrary
        if (date.isLeapYear()) { 
            daysInMonth = 29; // which has 29 if it's a leap year
        } else {
            daysInMonth = 28; // and 28 if it isn't.
        }
    } else {
        daysInMonth = 30;
    }
}
  • Published on December 09, 2015
  • 79 words

Using Git Hooks for code style fixes

16
Oct 2015

Pretty much every modern language has an established Coding Style Guide. For PHP, this is PSR-2. As with other style guides of this sort, there is a tool for automatically applying the appropriate fixes to one’s code

I only recently finally switched to using PSR-2 and to make sure I wouldn’t accidentally miss running the style fixer, I added this little snipped to my .git/hooks/pre-commit-Hook:

1
2
3
4
5
6
modified_php=$(git ls-files --modified | grep "\.php$")

for f in $modified
do
    php-cs-fixer fix --level psr2 $f
done
  • Published on October 16, 2015
  • 84 words