In my search for a notebook tool that is easy to organise, I came across Obsidian[1] after some time. A big advantage of it is that the notes are stored as Markdown files and can thus be edited with almost any text editor. Another advantage is the customisability through various plugins and themes.
My installation
So far, I've only opted for a visual spruce-up with the wonderful AnuPpuccin[2] theme. With the help of the Style Settings[3] plugin, the theme can then be set up wonderfully. And this is what the whole thing looks like:
Since version 0.8.122 of the Core[1] of Yellow, there is the group() function with which pages can be grouped according to their settings and output in an array. You can see what this can be useful for in the archive[2] of this page, for example.
This is what maintainer Mark wrote on GitHub, for the specific example of an archive like mine:
The method pages->group() is available in the Yellow API[3] now, it supports custom date formats[4].
pages->group("published", false, "Y") = group content by publication year with descending date pages->group("published", false, "Y-m") = group content by publication month with descending date pages->group("published", false, "Y-m-d") = group content by publication day with descending date
I am currently playing around with Yellow quite a lot. I create code snippets for extensions that don't end up being extensions, make adjustments to themes that don't end up being used and customise layout files only to undo the changes. And those are the things I don't publish. Neither here, nor on Github or in a Gist. But all this still helps me, because I learn something. So it seems to be code nonsense, but it never is! In this context, I would like to recommend this blog post by Nicole Tietz: "Write more "useless" software".
This is an RSS-only post. It's a secret! Read more about RSS Club.
Tomorrow, two weeks of holiday on the Danish North Sea coast will be over, and 'normal' everyday life will return. But what is normal these days? Armed conflicts are on the rise in the world, fascist parties are experiencing a high all over Europe, and we are all also grappling with a fatal climate change. I can hardly think straight, my children constantly on my mind.
In the face of these circumstances, it feels wrong to pretend that everything is fine. As I contemplate the prospect of returning to work on Monday, my stomach turns. I've noticed how I've been increasingly isolating myself for months, yearning for solitude to find some inner peace.
These tumultuous times have left me wondering about the state of the world and my place in it. It's not easy to carry on as if everything is business as usual. In the midst of these challenges, it's important to reflect and consider how we can make a positive impact on the world around us.
Wish me luck in finding a way to make this work for me.
Twitter (X) is history thanks to Elon Musk. That's a shame, but it's also an opportunity. An opportunity for other providers to do better.
A subjective explanation
Thanks to X's more or less open API and Musk's more than questionable policies, it has become a den of bots, fascists and conspiracy believers.
Mastodon
Mastodon has these currents as well. In contrast to X, however, you don't have to block every single user, but can block the entire server if it turns out to be a gathering place for dubious characters and bots. A clear advantage over X.
Bluesky
Bluesky is currently still in a beta phase and only allows registration with an invite code. Although the API can then also be used to post content as a quasi bot, it is currently still the case that politically extreme accounts are blocked.
What do I use?
I have accounts on all three platforms. I will not delete the X account. This is partly for sentimental reasons, as I opened it in July 2007, and partly because I don't want anyone to steal my handle and mess things up.
On Mastodon, I appreciate the unagitatedness of the users as well as the topics. In my eyes, it is an oasis of information gathering that is easy on my blood pressure.
On Bluesky, on the other hand, it's like on X. The riotous big accounts have already landed and are thundering through the timeline. I occasionally find that good, because linguistically they often choose the words I can't think of, even if I don't really like the habitus.
Conclusion
What you use doesn't matter as long as it makes you feel good. Nor do I have mutuals on X that can't be found on any other network. And...
Oh, I don't know. Musk has turned something great into a big pile of shit and two alternatives are one too many. Anyone who wants to follow me (my content there is mainly in German) is welcome to do so:
I‘ve been working with Yellow[1] for over a year now and early on, I saw a great synergy with Pico.css[2]. Initially, I manually integrated Yellow's default templates with a semantic foundation to harness Pico's capabilities for each new project. Recognizing the inefficiency, I decided to create a Yellow theme. Understanding that others might share my perspective, I submitted a pull request to Yellow's extension repo on GitHub[3], which was accepted after some adjustments.
Currently, only the file pico.css is included, but my future plan is to incorporate the entire Pico repo as a submodule. This way, developers will always have access to the latest version of Pico.css, including the SASS files. I'm in the process of discussing the feasibility of this with Yellow's maintainers.
I am currently contemplating whether I should incorporate a link preview here. I was inspired by yellow-meta[1]. I am thinking of adding the link preview as a tooltip to the links in the footnotes. Let’s see how it goes.
However, I have no intention of formatting my content for Twitter Cards. Thanks to Elon Musk, the platform has transformed into a breeding ground for racists, Nazi sympathizers, and proponents of conspiracy theories…
I have set up a link on the start page so that people who are interested can also contact me by email. But I wanted to avoid having my email address in plain text in the source code.
So it was clear that an extension was needed. And one in which I can also display icons. Which is somehow logical, since it makes no sense to hide the address in the source code for mailto: links and then display it in plain text in the frontend.
After my first excursion[1] into extension development for Yellow, it was much easier for me to get started this time. It was so much easier that I decided to add a few language default settings.
// Handle initialisation
public function onLoad($yellow) {
$this->yellow = $yellow;
$this->yellow->system->setDefault("MaillinkAddress", "Insert your desired email address or remove this string");
$this->yellow->language->setDefaults([
"Language: it",
"MaillinkText: Lasciatemi un messaggio",
"Language: de",
"MaillinkText: Schreib mir ein paar Zeilen",
"Language: en",
"MaillinkText: Drop me a line",
"Language: sv",
"MaillinkText: Skriv till mig",
"Language: fr",
"MaillinkText: Contactez-moi",
]);
}
The main challenge was that the texts for MaillinkTextweren't written to the yellow-language.ini file by the extension code. I copied the code from several extensions and adapted it to my values. Always in vain...
I then reached out to the community[2], and the initial suggestion for solving the problem was the key: I had previously written MailLinkText and MailAdress and had not kept to the name of the extension (Maillink). After I had changed this, it worked.
Oh boy, that was a lot of gibberish again. Anyway, here's the extension: yellow-maillink. And if you have any questions, you now know where to find my email address :wink:.
I was eager to incorporate those stylish „hashtags“ that offer a permalink to each section when hovering over the headings, so I embarked on a quest to discover an elegant way to create them.
However, that felt a bit complicated for me, as I don’t have the markdown syntax memorized. So, I initially inquired in the community[1] if there was a solution for Yellow. Since patience isn’t one of my strong suits, I continued my search and stumbled upon a helpful online guide[2]. I adapted the instructions from there and successfully implemented it.
The solution
Up until that point, I was content with my solution. Considering the narrow layout of this page and thinking about mobile users, I opted for using links behind the headlines. While I only discovered anchor.js later, it turned out to be a blessing in disguise. Shortly after I shared my solution on GitHub, Mark came up with this statement:
„First make it work, then make it better :grinning:“
With that, he had me hooked, albeit subconsciously. Following that moment, it took me nearly two days before I felt ready to attempt my first extension for Yellow. And here it is: yellow-anchor
I’m somewhat proud of it, although I’m aware that there might be more elegant solutions.
Recently, I’ve become increasingly attentive to image captions, a feature that, unfortunately, isn’t very elegantly supported by the Image extension. Additionally, I desired a lightbox functionality for my images. My initial thought was to utilize the gallery-extension[1] since it provided both features. However, it turned out to be implemented in a rather complex manner: captions needed to be added to the languages.ini file and were only visible within the lightbox. In search of an alternative to the Images extension, I eventually found what I was looking for.
The extension
A highly recommended substitute for Yellow’s image-extension is Giovanni Salmeri’s figure-extension[2]. This extension encapsulates the <img> tag within a <figure> tag and includes a <figcaption> for it.
In my article on Nova, I aimed to incorporate a lightbox feature and integrate it using JavaScript. To accomplish this, I initially searched for a Vanilla JS lightbox script and found the solution I needed in fslightbox[3], which I seamlessly integrated into the header section of my layout. To wrap the <img> within an <a> tag, I implemented the following code in my theme.js file:
document.querySelectorAll('figure img').forEach($imgSource => {
//get source from img
var src = $imgSource.getAttribute('src')
//create an anchor
var $lbAnchor = document.createElement('a')
$lbAnchor.setAttribute('data-fslightbox', '')
$lbAnchor.className = 'lightbox'
$lbAnchor.href = src
//wrap img with link
$imgSource.parentNode.replaceChild($lbAnchor, $imgSource);
$lbAnchor.appendChild($imgSource);
})
It subsequently generates the <img> tag enclosed within an <a> tag:
Today, I’d like to introduce you to a web development tool I’ve been using: Nova[1]. It’s developed by Panic[2], known for their software products, and serves as the successor to the popular but sadly discontinued Coda editor.
Having been a user of Coda, it was only natural for me to give Nova a try when it was released. Nova’s capabilities quickly won me over. Admittedly, I continued to use Coda for a while because I found the idea of working on live files appealing. However, in reality, it had its drawbacks that I won’t delve into further.
Let’s leave the past behind and have a look on Nova. Firstly, it’s worth noting that Nova is not open-source and comes with an initial price of $99. However, you can opt for automatic updates at $49 per year by subscribing.
Settings
Nova has a familiar look and feel, somewhat akin to Atom, which is certainly a positive aspect. Like Atom, Nova can also be expanded with additional extensions, and I’ll introduce some of the plugins I use later on. But first, let’s take a look at how I set up a project, after we’ve settled on the desired color for the project folder. I chose pink because, to be honest, I don’t really care about the folder’s color.
One really useful feature is the automatic indexing of files, which greatly aids in auto-completion. However, if you happen to be working with node.js and have a sizable node modules folder, you can add it to the list of ignored files. This prevents Nova from indexing 10,000 or more files, which can have a detrimental impact on performance.
After initializing a new project, my first step is to establish a connection with the project’s remote server. The websites I maintain don’t require the use of trendy technologies like node.js, Vue, React, etc. Instead, they consist of HTML5, CSS, and plain JavaScript.
The server list in the dropdown menu above is imported from Transmit[3], which is Panic’s FTP software. By enabling the Use Publishing option, modified files are conveniently listed in the publishing sidebar and can be transferred to the web server with a single click. You also have the flexibility to specify individual files or entire folders to the Ignored Files list, ensuring they won’t be uploaded to the web server. In the context of a flat file CMS like the one I use[4], this could be a ‘drafts’ folder, for example.
In the following image, you can see the settings for the SASS[5] extension. To use it, SASS must be installed on your system, and this can be easily accomplished through Homebrew[6]. Most of the settings here are self-explanatory. Occasionally, I need to reference the update path and output path settings, but it’s a relatively straightforward process. Essentially, the Update Path designates where your SCSS files are located, and the Output Path specifies where your CSS files will be written to. In my case, I don’t need to adjust the Executable Path because the extension automatically uses the path /usr/local/bin/sass, which is correct for my setup. If you’ve installed SASS in a different location, you will need to manually set the correct path here.
You want to write comfortably about the settings and - poof! - you end up with the extensions. Well, if that's where we've arrived, we might as well get on with it.
Extensions
I would like to introduce four extensions that I frequently use as examples. These are:
I use a few more extensions, but I don’t want to spoil the fun of exploring and discovering the extensions that can simplify your developer life. And now, let’s get started with…
SASS
As I mentioned earlier, I utilize the SASS extension, and to be honest, you don’t need to know more than what was explained in the preceding paragraph. When you save an SCSS file, it compiles a combination of all SCSS files and generates a CSS file. The compression of the output CSS file depends on your chosen setting.
Another widely used extension is the renowned Emmet[7]. If you’re not already familiar with it, Emmet allows you to swiftly generate HTML code. For instance:
With Advanced New File, you can effortlessly create new folders and files in no time. Just press Option (⌥), Command (⌘) + N, type in the desired folder or file name, press Enter, and it’s done. Folders that don’t yet exist will be created automatically.
Beautify ensures that your code is legible and well-structured. It integrates JS-Beautify[8], which you might be familiar with from beautifier.io[9], into Nova. This allows you to format JavaScript, TypeScript, JSON, CSS, SCSS, LESS, HTML, and XML with ease. With a simple click of a button, it transforms your code into a clean, organized format like this:
nav.tags_nav {
justify-content: stretch;
ul {
flex-wrap: wrap;
}
li {
padding: calc(var(--nav-element-spacing-vertical) * 0.825) calc(var(--nav-element-spacing-horizontal) * 0.825);
}
}
into this
nav.tags_nav {
justify-content: stretch;
ul {
flex-wrap: wrap;
}
li {
padding: calc(var(--nav-element-spacing-vertical) * 0.825) calc(var(--nav-element-spacing-horizontal) * 0.825);
}
}
I primarily utilize two of the many available sidebars: „Files“, which displays the files and folders within the project I’m currently working on, and „Publish“, which highlights the modified files and can be uploaded to the web server with a simple click.
There’s also a sidebar that illustrates the hierarchical structure of the currently open file, a Git sidebar that facilitates actions like commits, pushing, and pull requests, among many others, which I have yet to explore.
I made an attempt to work with VSCode, but the overwhelming number of seemingly identical extensions from various developers raised doubts about the overall quality. For instance, try searching for an Emmet extension; you’ll find it surprisingly challenging to locate one. I also explored Neovim, but I found myself needing to memorize an excessive number of keyboard commands, which hindered smooth workflow. Nevertheless, it remains an excellent solution for making quick adjustments via SSH while on the go.
What truly captivates me about Nova is its overall package. I appreciate its seamless integration with macOS, including the utilization of native keyboard shortcuts. The process of customizing Nova was incredibly swift, and I adore the flexibility it offers through extensions, which genuinely fulfill your specific needs, as opposed to being just another generic syntax highlighter. In my experience, this editor simply excels in delivering what it’s designed for: intuitive usability.
As previously mentioned[1], Yellow can be superbly customized to suit one's specific requirements through the use of extensions. Occasionally, though, it becomes necessary to tweak these extensions to seamlessly align with the desired design.
In my case, I had to make adjustments to the Previousnext[2] extension by Anna Svenson. The reason for this was that the default method of linking to the previous and next articles was accomplished using...
or through the shortcode [previousnext] within the article's content. However, I aimed to avoid this approach, as it created the impression that these links were directly related to the article's content, which wasn't always the case.
So, what did I do? To begin with, I inquired whether it was feasible to customize the extension[3], perhaps by incorporating its own layout file, similar to what had been done with pagination. Since this feature wasn't available at the time, I decided to modify the extension file[4], hoping that this adjustment would safeguard my design from being disrupted by future updates. Well, at least that's the idea. :see_no_evil:
class YellowPreviousnext {
// const VERSION = "0.8.18";
const VERSION = "0.9.18";
Next, I integrated the extension into my layout using the following code to provide me with a preview of what needed adjustments and how to achieve them.
Now, I was ready to tackle the design. I wanted the links to be styled as buttons, aligned both to the right and left, ensuring the 'Next' button is always on the right, even for the first post. To achieve this, I made changes in previousnext.php starting from line 26 onward. I removed the enclosing paragraph tags, assigned the role="button" attribute, and added the CSS class outline via JavaScript:
/* Styling for the previousnext buttons */
document.addEventListener("DOMContentLoaded", previousnextClassesAndStuff);
function previousnextClassesAndStuff() {
var list = document.getElementsByClassName("previousnext");
for (var i = 0; i < list.length; i++) {
var content = list[i].innerHTML;
content = content.replace("<p>", ""); // remove opening p tag
content = content.replace("</p>", ""); // remove closing p tag
list[i].innerHTML = content;
var links = list[i].getElementsByTagName("a");
for (var j = 0; j < links.length; j++) {
links[j].classList.add("outline"); // add class outline
links[j].setAttribute("role", "button"); // add role button
}
}
}
In line 30, I created a paragraph with dummy content that is only inserted if there's no Previous Post:
After years of working with WordPress, I yearned for something different and more streamlined. That’s when I stumbled upon flat-file CMSs. I explored several options, including Grav[1], Automad[2], and Kirby[3], but my attention was unexpectedly drawn to Datenstrom’s Yellow[4].
I opted for Datenstrom Yellow over other software because it just felt like the right fit. It’s lightweight and boasts a small yet highly agile community[5]. The individuals involved with Yellow, both in development and support, are incredibly friendly and exceptionally helpful.
Extend it
Furthermore, there is an ample selection of extensions[6] available, allowing you to tailor your installation to suit nearly any situation. Here are a few of the extensions I use:
Headinglink - Add anchor links next to headings in the content.
Readingtime - Show estimated reading time for page content.
However, as previously mentioned, there are many more available.
The Design
I borrowed the design, to the best of my abilities, from Hugo’s[7] PaperMod[8] theme. Why did I do this? Why did I boldly emulate a design? Well, because, on one hand, I genuinely appreciate the simplicity of the theme. More importantly, I simply lack the skills of a designer.
To implement this design, I employed Pico.css[9]. In case you’re not familiar with it, Pico is among the minimal CSS frameworks but stands out with its integrated dark mode, SASS source files, and a plethora of elegant styles for all native HTML elements without requiring .classes. With Pico, it’s entirely feasible to design a website without delving into extensive stylesheets.
For this particular page, I made slight adjustments to the spacing between HTML elements, all in the name of maintaining a clean and uncluttered design.