<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en-US">
	<title type="text">Flo Kosiol</title>
	<subtitle type="text">Web developer from Mainz/Germany</subtitle>
	<updated>2026-03-01T21:10:00+01:00</updated>
	<id>https://flokosiol.de</id>
	<author>
		<name>Flo Kosiol</name>
		<uri>https://flokosiol.de</uri>
	</author>
	<link rel="alternate" type="text/html" href="https://flokosiol.de" />
	<link rel="self" type="application/atom+xml" href="https://flokosiol.de/rss" />

	<entry>
		<title type="html"><![CDATA[The legendary Marble Machine]]></title>
		<id>https://flokosiol.de/@/page/ciD8rhbH6fMrH6dt</id>
		<updated>2026-03-01T21:10:00+01:00</updated>
		<published>2026-03-01T21:10:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/the-legendary-wintergatan-marble-machine" />
		<category term="Inspiration" />
		<category term="Music" />
		<content type="html" xml:base="https://flokosiol.de/articles/the-legendary-wintergatan-marble-machine"><![CDATA[<div class="text">
	<p>I dont' know how it came to my mind, but I recently remembered the legendary <a href="https://www.youtube.com/watch?v=IvUU8joBb1Q" target="_blank">Marble Machine video</a> by the swedish band <a href="https://wintergatan.net/" target="_blank">Wintergatan</a>. I decided to watch the video once again to see if it still amazes me like back in the days. And damn yes, it did! </p><p>→ If you don't know what I am talking about, please stop reading and watch the <a href="https://www.youtube.com/watch?v=IvUU8joBb1Q" target="_blank">video</a> now.</p><p>Of course, the video was already several years old. But I couldn't remember exactly when it was released. So I looked it up and saw that it happened to be almost exactly 10 years ago. A perfect opportunity to write about it and publish the blog post on its 10th anniversary*. I am pretty sure, many of you remember it and hopefully the rest is as impressed as I was back in the days. </p><p><em>* Depending on your time zone, YouTube will show a different date, but in one of the videos </em><a href="https://en.wikipedia.org/wiki/Martin_Molin" target="_blank"><em>Martin</em></a><em> mentions March 1, 2016, as the date of publication.</em></p></div>
<h2 class="text-h2">
	<a id="it-s-perfectly-imperfect" href="#it-s-perfectly-imperfect" tabindex="-1">
		It's perfectly imperfect	</a>
</h2>
<div class="text">
	<p>I find it incredible how much work and perseverance went into this machine. I love how you can hear the jerking and how the timing after the pause in the middle section isn't perfect because the machine has to pick up speed again. Or how it slowly comes to a stop at the end. It's so beautifully authentic. Especially in this age of AI, a little authenticity and craftsmanship really does a world of good. It's the playful details and the many little things that make the Marble Machine so special in my opinion.</p></div>
<blockquote>
  „The heart of the project is playfulness“    <footer>
    Martin Molin – <a href="https://www.youtube.com/watch?v=BpJYqC4PWEw&amp;list=PLLLYkE3G1HEBoueYkV5-HrcI-rUKfNeiO" target="_blank">YouTube</a>  </footer>
  </blockquote>
<h2 class="text-h2">
	<a id="there-s-even-more" href="#there-s-even-more" tabindex="-1">
		There's even more …	</a>
</h2>
<div class="text">
	<p>I usually spend almost no time on YouTube. That's probably why I didn't notice how much there is to see in the Marble Machine universe over the years. There's a <a href="https://www.youtube.com/@Wintergatan/playlists" target="_blank">playlist</a> with videos showing how it was <a href="https://www.youtube.com/playlist?list=PLLLYkE3G1HEA_68q46Xk1MvK-zGqjLBmA" target="_blank">built</a>, as well as an extensive series about the successor model, <a href="https://www.youtube.com/playlist?list=PLLLYkE3G1HED6rW-bkliHbMroHYFf4ukv" target="_blank">Marble Machine X</a>, which, to my knowledge, was <a href="https://www.youtube.com/watch?v=WN90HYiFpAw" target="_blank">never actually completed</a>. Instead, <a href="https://www.youtube.com/playlist?list=PLLLYkE3G1HEBoueYkV5-HrcI-rUKfNeiO" target="_blank">Marble Machine 3</a> seems to be in the works. The latest videos provide insights into the <a href="https://www.youtube.com/watch?v=ATj41HxVveE" target="_blank">technical planning</a>. Let's see what else is coming in the future...</p><p>Move <s>fast</s> as fast or slow as you like and <s>break</s> build things!</p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://wintergatan.net/">https://wintergatan.net/</a></li><li><a href="https://en.wikipedia.org/wiki/Wintergatan">https://en.wikipedia.org/wiki/Wintergatan</a></li><li><a href="https://www.youtube.com/@Wintergatan">https://www.youtube.com/@Wintergatan</a></li><li><a href="https://www.youtube.com/watch?v=IvUU8joBb1Q">https://www.youtube.com/watch?v=IvUU8joBb1Q</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Use your fucking brain.]]></title>
		<id>https://flokosiol.de/@/page/xLzgaAq3VgntZ1fl</id>
		<updated>2025-12-31T16:30:00+01:00</updated>
		<published>2025-12-31T16:30:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/use-your-fucking-brain" />
		<category term="Inspiration" />
		<content type="html" xml:base="https://flokosiol.de/articles/use-your-fucking-brain"><![CDATA[<div class="text">
	<p>I can't remember when I first saw a picture of <a href="https://www.hackinggutenberg.berlin/imager/uploads/Produkte-Legacy/3284/PO_040-new_fc190f0657827a28ca61d73b10ef9f1e.webp" target="_blank">this print</a>. Maybe as a slide in a talk at a beyond tellerrand conference!? I don't remember, but I kept in my mind ever since. </p><p>With all the things happening in the world right now it still totally fits.</p><p>Thanks to those who already follow this principle. ❤️ And now … let’s get back to a positive attitude. All the best for 2026!</p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://www.hackinggutenberg.berlin/">https://www.hackinggutenberg.berlin</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Sync Kirby’s content folder with rsync]]></title>
		<id>https://flokosiol.de/@/page/eKhAU5ywiKncFE2e</id>
		<updated>2025-11-11T08:00:00+01:00</updated>
		<published>2025-11-11T08:00:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/sync-kirby-content-folder-rsync" />
		<category term="Kirby" />
		<category term="Helper" />
		<content type="html" xml:base="https://flokosiol.de/articles/sync-kirby-content-folder-rsync"><![CDATA[<div class="text">
	<p>This is primarily a note to myself. Nevertheless, it might help others.</p><p>I write my blog posts directly online in the Kirby backend. With <a href="https://getkirby.com/docs/reference/panel/fields/blocks">Kirby Blocks</a> and all the keyboard shortcuts and navigation options it offers, I can work quite quickly here. When testing in my local development environment, I often just create stupid test pages with “Lorem ipsum” content. To have the current status of the <code>content</code> folder locally from time to time, I use <code>rsync</code>. Unlike <a href="https://maurice-renck.de/en/blog" target="_blank">Maurice</a>, who uses a very sophisticated system to <a href="https://maurice-renck.de/en/learn/built-with-kirby/obsidian-kirby-sync" target="_blank">synchronize between his Kirby installation and Obsidian</a>, this simple one-way backup function is sufficient for me.</p></div>

<pre class="phiki language-bash github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="bash"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">#!</span><span class="token" style="color: #8b949e;">/usr/bin/env bash</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token">rsync -chavzP --delete --stats my-ssh-alias:/var/www/html/my-kirby-website/content /path/to/local-websites/my-kirby-website
</span></span></code></pre><div class="text">
	<table>
				<thead>
		<tr>
							<th>Option</th>
							<th></th>
					</tr>
		</thead>
		<tbody>
					<tr>
									<td>-c</td>
									<td>--checksum</td>
							</tr>
					<tr>
									<td>-h</td>
									<td>--human-readable</td>
							</tr>
					<tr>
									<td>-a</td>
									<td>--archive</td>
							</tr>
					<tr>
									<td>-v</td>
									<td>--verbose</td>
							</tr>
					<tr>
									<td>-z</td>
									<td>--compress</td>
							</tr>
					<tr>
									<td>-P</td>
									<td>--progress</td>
							</tr>
					<tr>
									<td></td>
									<td>--delete</td>
							</tr>
					<tr>
									<td></td>
									<td>--stats</td>
							</tr>
				</tbody>
	</table>
</div>
<div class="text">
	<p>The <code>--delete</code> flag removes all test content locally which does not exist on the server. In this way I don’t have to clean up by myself. In addition <code>--stats</code> gives a nice summary at the end about how much data has been transferred.</p><p>There are <a href="https://download.samba.org/pub/rsync/rsync.1#OPTION_SUMMARY" target="_blank">a million more options</a> for <code>rsync</code> which makes it a really powerful tool.</p></div>
<h2 class="text-h2">
	<a id="script-file" href="#script-file" tabindex="-1">
		Script file	</a>
</h2>
<div class="text">
	<p>Of course, I don't type this command into the terminal over and over again. I put it into a file, made it executable and reuse it whenever I want. Here’s a nice overview <a href="https://hackr.io/blog/how-to-create-linux-commands" target="_blank">how to create custom scripts</a>. It refers to Linux, but is also valid for MacOS.</p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://tldr.inbrowser.app/pages/common/rsync" target="_blank">TLDR; explanation</a></li><li><a href="https://download.samba.org/pub/rsync/rsync.1" target="_blank">https://download.samba.org/pub/rsync/rsync.1</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[It‘s the rests what makes the groove!]]></title>
		<id>https://flokosiol.de/@/page/j6KzfUJahFJqh60i</id>
		<updated>2025-10-12T09:00:00+02:00</updated>
		<published>2025-10-12T09:00:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/it-is-the-rests-what-makes-the-groove" />
		<category term="General" />
		<category term="Inspiration" />
		<category term="Music" />
		<content type="html" xml:base="https://flokosiol.de/articles/it-is-the-rests-what-makes-the-groove"><![CDATA[<div class="text">
	<p><a href="https://matthiasott.com/" target="_blank">Matthias</a> recently published a blog post which really resonates with me. Starting from a musical point of view, he wrote about <a href="https://matthiasott.com/notes/making-space" target="_blank">making space</a>. Space is limited, so …</p></div>
<blockquote>
  “… think about what the quality is you want to amplify and then try to identify what you can <em>take away</em> to reveal more of that quality.”    <footer>
    Matthias Ott  </footer>
  </blockquote>
<div class="text">
	<p>His initial example was about mixing music. Instead of making an instruments in a mix louder because it can't be heard sufficiently, it might be better to turn all the other ones a bit down. I would like to add that this approach is even more important when equalizers come into play to shape the sound of all the instruments (or voices). The audible frequency range is limited and every instrument needs to find its place within this range – and finally it’s place in the mix.</p><p>Perhaps you've had the opportunity to listen to individual tracks of a song mix. I am always amazed how limited they sound on their very own. Only when they're mixed together it’s that these puzzle pieces come together and produce a clear sound. If you would instead mix each instrument so that it sounds good on its own, the song would end up sounding muddy. If you are interested in music production, you will probably find plenty of videos on the web about this topic and a lot of great examples. </p><p>As Matthias states, this is true not only for music but also for other things in life.</p></div>
<h2 class="text-h2">
	<a id="less-is-more" href="#less-is-more" tabindex="-1">
		Less is more?	</a>
</h2>
<div class="text">
	<p>Expressions such as “less is more” or “keep it simple” are well known. But taking it to an extrem is not what this is all about. Minimalism at any cost is not what is this about. It’s about removing all <em>unnecessary</em> things while keeping all the relevant stuff. But in the end it‘s probably a matter of taste, too. </p></div>
<blockquote>
  “Perfection is not achieved when there is nothing more to add, but when there is nothing more to take away.”    <footer>
    Antoine de Saint-Exupéry  </footer>
  </blockquote>
<div class="text">
	<p>I was fortunate enough to gain a very good musical education. As some of you know, I have a Bachelor degree in jazz/popular music. Back in the days at university we there was a big band. At one of their performances, it was my friend Johannes who played several solos with his incredible saxophone playing. After each song, the conductor (the very entertaining Ed Partyka) mentioned the soloists. And after Jo’s first solo he said something like: “Ladies and gentlemen, the man who performed this variety of notes on the saxophone – Johannes!” This made the audience laugh (in a friendly way), because the solo was indeed very virtuosic. But Johannes seized the opportunity and drastically reduced his second solo in one of the next songs. He played just a very few carefully selected notes and everybody knew that this was best response he could give and it was an amazing solo as well.</p><p>A few years later I saw Helge Schneider performing live with Jimmy Woode and Pete York. It was not one of his comedy shows but an awesome jazz concert. I remember him playing a one-finger-piano-solo in which he stretched his arm out as far as he could without falling off the piano stool. Every time when he moved his arm in slow motion back to the piano keys he pressed a single one with just one finger. It was amazing because the selection and the timing was incredible.</p></div>
<h2 class="text-h2">
	<a id="but-what-about-the-rests-and-the-groove" href="#but-what-about-the-rests-and-the-groove" tabindex="-1">
		But what about the rests and the groove?	</a>
</h2>
<div class="text">
	<p>This is one of the many great musical advices my (bass) teacher gave me back then. And it instantly came to my mind while reading Matthias’ blog post. Especially a bass player, who teams up with the drummer to build the foundation of the band, needs to take care of the groove. The rhythm section is the part of the group which lets the soloist shine. And it‘s not about playing as many notes as possible …</p></div>
<blockquote>
  “It‘s the rests what makes the groove!”    <footer>
    Ralf Cetto  </footer>
  </blockquote>
<div class="text">
	<p>So. True. </p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://matthiasott.com/notes/making-space" target="_blank">Making Space</a> (Matthias Ott)</li><li><a href="https://de.wikipedia.org/wiki/Ed_Partyka#" target="_blank">Ed Partyka</a> (Wikipedia DE)</li><li><a href="https://de.wikipedia.org/wiki/Ralf_Cetto" target="_blank">Ralf Cetto</a> (Wikipedia DE)</li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Read code!]]></title>
		<id>https://flokosiol.de/@/page/0sl5kEcJWFWEDhJi</id>
		<updated>2025-10-05T17:26:00+02:00</updated>
		<published>2025-10-05T17:26:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/read-code" />
		<category term="General" />
		<category term="Drupal" />
		<category term="PHP" />
		<category term="CMS" />
		<content type="html" xml:base="https://flokosiol.de/articles/read-code"><![CDATA[<div class="text">
	<p>It might sound obvious, but reading code is extremely helpful. And sometimes it is necessary! But first things first. Here’s a little story …</p></div>
<h2 class="text-h2">
	<a id="how-it-started" href="#how-it-started" tabindex="-1">
		How it started	</a>
</h2>
<div class="text">
	<p>I recently set up <a href="https://www.drupal.org/project/content_moderation_notifications" target="_blank">Content Moderation Notifications</a> for Drupal. The purpose of this module is to send mail notifications when a workflow status of a page changes. This is very helpful when you want to set up some kind of information or approval process. Relevant for this blog post are two options. You can send a mail to the author of the page as well as you can add other mail addresses (so called “Adhoc Emails”) manually. While the last ones are static values, the author will be found dynamically by Drupal. That’s neat. Both settings are optional.</p><p>I had two different workflows for two different page types – news and pages.</p></div>
<h3 class="text-h3">
	<a id="news" href="#news" tabindex="-1">
		News	</a>
</h3>
<div class="text">
	<p>The workflow for news is pretty simple. Authors start with creating an unpublished <strong>draft</strong> and when everything is ready they release it by themselves by changing the status to <strong>published</strong>. This change triggers a mail to a shared mailbox to inform other people involved. Since authors handle all status changes on their own, it is not necessary to send them an email, too.</p></div>
<div class="text">
	<table>
				<thead>
		<tr>
							<th>Status</th>
							<th>Email Author?</th>
							<th>Adhoc Emails</th>
					</tr>
		</thead>
		<tbody>
					<tr>
									<td>Draft</td>
									<td>No</td>
									<td>–</td>
							</tr>
					<tr>
									<td>Published</td>
									<td>No</td>
									<td>shared@mailbox.local</td>
							</tr>
				</tbody>
	</table>
</div>
<h3 class="text-h3">
	<a id="page" href="#page" tabindex="-1">
		Page	</a>
</h3>
<div class="text">
	<p>The workflow for global pages is slightly different. In addition to <strong>draft</strong> and <strong>published</strong>, there’s an additional <strong>review</strong> step in between. The idea is to let a second person check the content and release the page afterwards. Therefore an email should be sent to the author when the page has been published, but not again to the shared mailbox.</p></div>
<div class="text">
	<table>
				<thead>
		<tr>
							<th>Status</th>
							<th>Email Author?</th>
							<th>Adhoc Emails</th>
					</tr>
		</thead>
		<tbody>
					<tr>
									<td>Draft</td>
									<td>No</td>
									<td>–</td>
							</tr>
					<tr>
									<td>Review</td>
									<td>No</td>
									<td>shared@mailbox.local</td>
							</tr>
					<tr>
									<td>Published</td>
									<td>Yes</td>
									<td>–</td>
							</tr>
				</tbody>
	</table>
</div>
<div class="text">
	<p>While the adhoc email of the news workflow worked like expected, the one for the page workflow didn’t and I couldn’t get my head around it. I was pretty sure the only difference was the status name!? But I was wrong. Of course. </p></div>
<h2 class="text-h2">
	<a id="debugging" href="#debugging" tabindex="-1">
		Debugging	</a>
</h2>
<div class="text">
	<p>First, I double-checked all the configurations (there are more than shown in the tables above). No differences. I started to change things here and there in a more or less structured way. In the end, I added the adhoc email address to the published status for testing purpose and then it worked. <em>Now</em> there were no differences anymore. </p><p>But I still had the problem that the mails for the review status didn’t work. I added an additional review status to the first (news) workflow, too. And this mail didn't work either. Alright, but why can adhoc emails only be sent for the last status? That’s a bug!</p></div>
<h2 class="text-h2">
	<a id="finding-the-bug-that-wasnt-one" href="#finding-the-bug-that-wasnt-one" tabindex="-1">
		Finding the bug that wasn’t one	</a>
</h2>
<div class="text">
	<p>I had a look at the known issues for this module and found a few that were about emails. But these issues didn’t fit. <strong>So I had a look at the code. And I should have done this much earlier!</strong></p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">anonymous_access</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">entity</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">access</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">view</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #79c0ff;">User</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">getAnonymousUser</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">adhoc_emails</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> Attempt to find a user matching this email.</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email_accounts</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #79c0ff;">$</span><span class="token" style="color: #79c0ff;">this</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #e6edf3;">entityTypeManager</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">getStorage</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">user</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">loadByProperties</span><span class="token">(</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token">[</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">status</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">1</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">mail</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email</span><span class="token">]</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">  </span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email_account</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #79c0ff;">reset</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email_accounts</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">  </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email_account</span><span class="token"> </span><span class="token" style="color: #ff7b72;">&amp;&amp;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">entity</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">access</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">view</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email_account</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">    </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">data</span><span class="token">[</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">to</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">]</span><span class="token">[</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">  </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">  </span><span class="token" style="color: #ff7b72;">elseif</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">anonymous_access</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">    </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> Send adhoc emails if anonymous users can view the entity.</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="14"><span class="token">    </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">data</span><span class="token">[</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">to</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">]</span><span class="token">[</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">email</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">  </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token">}</span><span class="token">
</span></span></code></pre><div class="text">
	<p>The module tries to check if the owner of the adhoc email has access to the page for the current status. If there’s no Drupal user account associated with the mail address, it assumes that it’s an anonymous user. That was the case for the shared mail account. There is even an explicit comment in the code:</p><p><code>// Send adhoc emails if anonymous users can view the entity.</code></p><p>Since the last status in both workflows included the publication of the content, the pages were accessible for anonymous. But that was not the case for all previous steps. This is why the module did not send the email notifications. </p><p><strong>It’s not a bug, it’s a feature! 🎉</strong></p><p>From my point of view it should be the user's choice if an email is sent or not. But regardless of whether I think that's a useful feature, it should definitely be documented for editors somewhere (and not only in the code). Maybe adding a hint to the input field of the configuration? “Make sure the owner of this email address has access to the content otherwise no email will be sent!” </p></div>
<h2 class="text-h2">
	<a id="reading-code-helps" href="#reading-code-helps" tabindex="-1">
		Reading code helps	</a>
</h2>
<div class="text">
	<p>It’s not only about finding bugs or solving problems. It’s very helpful to dig into other peoples code to learn new things. I am sure that just like reading a lot of different books (or blog posts) makes you a better writer, reading code makes you a better developer.</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[#FIXME! git pre-commit hook]]></title>
		<id>https://flokosiol.de/@/page/AZXvwn3ahk32votK</id>
		<updated>2025-08-31T23:05:00+02:00</updated>
		<published>2025-08-31T23:05:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/fixme-git-pre-commit-hook" />
		<category term="Git" />
		<category term="General" />
		<category term="Helper" />
		<content type="html" xml:base="https://flokosiol.de/articles/fixme-git-pre-commit-hook"><![CDATA[<div class="text">
	<p>I use <code>#FIXME</code> comments all the time in my code and I am sure you do, too. Some of these comments stay for a really long time until they finally get fixed. But sometimes there are temporary changes in my code which <strong>definitely must not go live!</strong> </p><p>For example, when you have a method in your code which checks access for something and you want to test both cases –&nbsp;access denied and access granted. The easiest way is to hard code a return value of <code>FALSE</code> or <code>TRUE</code> without using the real logic. Easy to do, but also easy to forget. And after the next deployment access is granted all the time …&nbsp;or never, because you forgot to remove the temporary code after your test.</p></div>
<h2 class="text-h2">
	<a id="git-hook" href="#git-hook" tabindex="-1">
		Git hook	</a>
</h2>
<div class="text">
	<p><a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">Git hooks</a> are great way to execute scripts at a certain time in your git workflow. And to avoid the situation described above, I thought about using a <code>pre-commit</code> hook. </p></div>
<blockquote>
  The <code>pre-commit</code> hook is run first, before you even type in a commit message. It’s used to inspect the snapshot that’s about to be committed, to see if you’ve forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code.    <footer>
    <a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks</a>  </footer>
  </blockquote>
<div class="text">
	<p>My idea was to use <code>#FIXME!</code> (with an exclamation mark) to emphasize the changes which must not go live at any circumstances. The git hook should check, if the latest changes contain a <code>FIXME!</code>  and exit before committing. I ended up with these few lines I found somewhere on the internet (long before AI was a thing) changed to my needs.</p></div>

<pre class="phiki language-bash github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="bash"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">#!</span><span class="token" style="color: #8b949e;">/bin/sh</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token" style="color: #8b949e;">#</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> Check for FIXME!</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">
</span></span><span class="line" data-line="5"><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> Test whether the repository has a valid HEAD without printing anything</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token" style="color: #ff7b72;">if</span><span class="token"> git rev-parse --verify HEAD </span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">/dev/null </span><span class="token" style="color: #ff7b72;">2&gt;&amp;1</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token" style="color: #ff7b72;">then</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token" style="color: #e6edf3;">against</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">H</span><span class="token" style="color: #a5d6ff;">E</span><span class="token" style="color: #a5d6ff;">A</span><span class="token" style="color: #a5d6ff;">D</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token" style="color: #ff7b72;">else</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">  </span><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> If it&#039;s the first commit, diff against an empty tree object</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">  </span><span class="token" style="color: #e6edf3;">against</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">4</span><span class="token" style="color: #a5d6ff;">b</span><span class="token" style="color: #a5d6ff;">8</span><span class="token" style="color: #a5d6ff;">2</span><span class="token" style="color: #a5d6ff;">5</span><span class="token" style="color: #a5d6ff;">d</span><span class="token" style="color: #a5d6ff;">c</span><span class="token" style="color: #a5d6ff;">6</span><span class="token" style="color: #a5d6ff;">4</span><span class="token" style="color: #a5d6ff;">2</span><span class="token" style="color: #a5d6ff;">c</span><span class="token" style="color: #a5d6ff;">b</span><span class="token" style="color: #a5d6ff;">6</span><span class="token" style="color: #a5d6ff;">e</span><span class="token" style="color: #a5d6ff;">b</span><span class="token" style="color: #a5d6ff;">9</span><span class="token" style="color: #a5d6ff;">a</span><span class="token" style="color: #a5d6ff;">0</span><span class="token" style="color: #a5d6ff;">6</span><span class="token" style="color: #a5d6ff;">0</span><span class="token" style="color: #a5d6ff;">e</span><span class="token" style="color: #a5d6ff;">5</span><span class="token" style="color: #a5d6ff;">4</span><span class="token" style="color: #a5d6ff;">b</span><span class="token" style="color: #a5d6ff;">f</span><span class="token" style="color: #a5d6ff;">8</span><span class="token" style="color: #a5d6ff;">d</span><span class="token" style="color: #a5d6ff;">6</span><span class="token" style="color: #a5d6ff;">9</span><span class="token" style="color: #a5d6ff;">2</span><span class="token" style="color: #a5d6ff;">8</span><span class="token" style="color: #a5d6ff;">8</span><span class="token" style="color: #a5d6ff;">f</span><span class="token" style="color: #a5d6ff;">b</span><span class="token" style="color: #a5d6ff;">e</span><span class="token" style="color: #a5d6ff;">e</span><span class="token" style="color: #a5d6ff;">4</span><span class="token" style="color: #a5d6ff;">9</span><span class="token" style="color: #a5d6ff;">0</span><span class="token" style="color: #a5d6ff;">4</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token" style="color: #ff7b72;">fi</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">
</span></span><span class="line" data-line="14"><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> Check if diff contains a FIXME! as a whole word but ignoring case</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token" style="color: #e6edf3;">VAR</span><span class="token" style="color: #ff7b72;">=</span><span class="token">$(</span><span class="token">git diff --cached </span><span class="token" style="color: #ff7b72;">|</span><span class="token"> grep -iw </span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">fixme!</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">)</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">[</span><span class="token"> </span><span class="token" style="color: #ff7b72;">!</span><span class="token"> </span><span class="token" style="color: #ff7b72;">-z</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">VAR</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token">]</span><span class="token">
</span></span><span class="line" data-line="17"><span class="token" style="color: #ff7b72;">then</span><span class="token">
</span></span><span class="line" data-line="18"><span class="token">  echo </span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">You&#039;ve left a #FIXME! in one of your files! Aborting commit...</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">
</span></span><span class="line" data-line="19"><span class="token">  </span><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> Exiting non-zero from this hook aborts the commit</span><span class="token">
</span></span><span class="line" data-line="20"><span class="token">  exit 1
</span></span><span class="line" data-line="21"><span class="token" style="color: #ff7b72;">fi</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="git-config" href="#git-config" tabindex="-1">
		Git config	</a>
</h2>
<div class="text">
	<p>But where to put the script? You can add hooks to the local <code>.git</code>  folder in your project. In this case <code>.git/hooks/pre-commit</code>  would be the correct file. Since I don't use project related hooks, I decided to add the script as a g<strong>lobal hook</strong> which will work for every existing and new project. You can use any directory on your computer to store your custom hooks, but you have to tell git where to find it in the global <strong>git config</strong> file.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">[core]
</span></span><span class="line" data-line="2"><span class="token">    hooksPath = /my/custom/gitconfig/hooks
</span></span></code></pre><div class="text">
	<p>To verify, you can run the following command which lists all your global configs.</p></div>

<pre class="phiki language-shell github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="shell"><code><span class="line" data-line="1"><span class="token">git config --global -l
</span></span></code></pre><h2 class="text-h2">
	<a id="one-more-thing" href="#one-more-thing" tabindex="-1">
		One more thing …	</a>
</h2>
<div class="text">
	<p>Just for the record. You can bypass the <code>pre-commit</code> hook by using <code>git commit --no-verify</code>. But don't do it!</p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks">https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks</a></li><li><a href="https://floatingoctothorpe.uk/2017/empty-trees-in-git.html">https://floatingoctothorpe.uk/2017/empty-trees-in-git.html</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Kirby Meetup Mainz #3]]></title>
		<id>https://flokosiol.de/@/page/WxuffEjxy0vSV37P</id>
		<updated>2025-07-29T23:30:00+02:00</updated>
		<published>2025-07-29T23:30:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/kirby-meetup-mainz-3" />
		<category term="Kirby" />
		<category term="Event" />
		<category term="CMS" />
		<category term="General" />
		<content type="html" xml:base="https://flokosiol.de/articles/kirby-meetup-mainz-3"><![CDATA[<div class="text">
	<p>Last Wednesday some folks of the <a href="https://getkirby.com/meet" target="_blank">Kirby community</a> joined us once again to chat about <a href="https://getkirby.com" target="_blank">Kirby CMS</a> and other more or less web related topics. We met at the <a href="https://www.3st.de" target="_blank">3st kommunikation</a> office in Mainz for the third time and almost exactly one year after the first event. It was very nice to meet some of the regular guests again, but also to get to know new people in a relaxed atmosphere with cool drinks, snacks, and pizza. Sonja and Bastian from the Kirby core team came around, too.</p></div>
<figure data-ratio="auto">
    <img src="https://flokosiol.de/media/pages/articles/kirby-meetup-mainz-3/030e391fe0-1753823865/kirby-meetup-3.jpg" alt="The attendees of the 3rd Kirby meetup in Mainz sit together and talk about web stuff. ">
  
  </figure>
<h2 class="text-h2">
	<a id="work-in-progress" href="#work-in-progress" tabindex="-1">
		Work in progress	</a>
</h2>
<div class="text">
	<p>After a short introduction, I took the chance to get some feedback on the latest Kirby hacking stuff I did recently. Based on the <a href="/@/page/nn0FSGvIY5k0iTCq">custom view modes with content representations</a>, I created some more view mode variants including fields, files and even page collections. I was <s>a bit</s> completely unprepared due to time constraints but the others were forgiving. I'll try to sort things up and put everything into a new blog post. Nevertheless the feedback was very helpful for me.</p><p>Afterwards, <a href="https://bastianallgeier.com/" target="_blank">Bastian</a> talked about how a database could be (optionally) included into Kirby. It sounds strange at first, since Kirby is a file based system. But if you have huge amounts of custom data it could be really handy. There are several problems to solve to have a straight forward and Kirby like experience in the panel in the end. But it was very interesting to discuss different ideas all together. And I’m sure, Bastian got some helpful feedback, too.</p></div>
<h2 class="text-h2">
	<a id="company-culture" href="#company-culture" tabindex="-1">
		Company culture	</a>
</h2>
<div class="text">
	<p>It had happened quite spontaneously that Jonas Pasche, the founder of <a href="https://uberspace.de/en/" target="_blank">Uberspace</a>, joined. Thanks again <a href="https://nilsmielke.me" target="_blank">Nils</a> for the great idea to ping him on Mastodon. We took the chance not only to talk about hosting stuff, but also about company culture. Jonas shared some insights and (suprise, suprise) we discovered that there were many similarities between Uberspace and Kirby from a company/business perspective. Thanks Bastian and Jonas for this “behind the scenes”.</p></div>
<h2 class="text-h2">
	<a id="ai-is-everywhere" href="#ai-is-everywhere" tabindex="-1">
		AI is everywhere	</a>
</h2>
<div class="text">
	<p>AI is currently the dominant topic – it’s everywhere. We exchanged views on the use of AI support in our daily (programming) work, discussed the risks and concerns we have in general, and learned how Uberspace has gradually attempted to protect itself against the excessive traffic generated by AI bots. If you are interested, there’s a <a href="https://blog.uberspace.de/2024/08/bad-robots/" target="_blank">Uberspace blog post from August 2024</a> which is still somehow valid.</p></div>
<h2 class="text-h2">
	<a id="see-you-next-time" href="#see-you-next-time" tabindex="-1">
		See you next time	</a>
</h2>
<div class="text">
	<p>The next meetup will probably take place in <strong>January 2026</strong>. What now feels like an eternity will be here sooner than you think. That's the impression pretty much all of us had this time. Would be awesome to see you there! Let me know if you are interested or join the <a href="https://chat.getkirby.com/" target="_blank">Kirby Discord</a> server to find new meetup events or chat about Kirby in general.</p><p>Thank you to everyone who participated. Thanks Bastian for the pizza. And a special thank you to 3st kommunikation for making such events possible by providing rooms and by sponsoring drinks.</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Building a component based style guide for Kirby (3)]]></title>
		<id>https://flokosiol.de/@/page/yWDtXOGzsrQWLFTn</id>
		<updated>2025-06-10T17:00:00+02:00</updated>
		<published>2025-06-10T17:00:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-3" />
		<category term="CMS" />
		<category term="Kirby" />
		<category term="PHP" />
		<content type="html" xml:base="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-3"><![CDATA[<div class="text">
	<p>This is the third (and for now the last) part of a series. Please read the first blog post to learn more about the concept of <a href="/@/page/KpQCdRfGBPwMmWCq">frontend components</a> and the second article about <a href="/@/page/ITeU3dicn6suiBzh">how the style guide was set up</a> in general. </p><p>Today I want to demonstrate how to build individual pages for each component, which can be used to add additional content or component variations and shouldn’t be part of the <a href="/@/page/ITeU3dicn6suiBzh">overview page</a>.</p></div>
<h2 class="text-h2">
	<a id="routing" href="#routing" tabindex="-1">
		Routing	</a>
</h2>
<div class="text">
	<p>To be able to access every component at its own URL we have to create a second route. In the end we will be able to visit <code>mydomain.com/styleguide/my-module</code> to see the details page. Since we handle routing outside the <code>index.php</code> file of our plugin, we have to add the new route there.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/plugins/styleguide/routes.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> see previous blog post for first (main) route</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">  </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">pattern</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide/(:any)</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">method</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">get</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">action</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">      </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d2a8ff;">kirby</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">user</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">        </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #ff7b72;">new</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Page</span><span class="token">(</span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">slug</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">template</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide_module</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">parent</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">kirby</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">site</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">homePage</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">content</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="17"><span class="token">            </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">module</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">esc</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="18"><span class="token">          </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="19"><span class="token">        </span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="20"><span class="token">      </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="21"><span class="token">      </span><span class="token" style="color: #ff7b72;">die</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="22"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="23"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="24"><span class="token">]</span><span class="token">;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>With <a href="https://getkirby.com/docs/guide/routing#patterns">Kirby route patterns</a> you can register routes with dynamic parts. In this case, the <code>(:any)</code> placeholder represents the selected frontend component. It will be stored in the <code>$module</code> variable and passed to the page template. There it will be available as a new content method <code>$page-&gt;content()-&gt;module()</code>.</p></div>
<h2 class="text-h2">
	<a id="template" href="#template" tabindex="-1">
		Template	</a>
</h2>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/plugins/styleguide/templates/
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">layout/html</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #ffa657;">slots</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #79c0ff;">true</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">section</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">module</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">upper</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide/</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">.</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">module</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">value</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">section</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">
</span></span><span class="line" data-line="8"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">endsnippet</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>With the <code>layout/html</code> snippet we include the basic header and footer template, just like we did for the <a href="/@/page/ITeU3dicn6suiBzh">style guide overview</a> page. The additional <code>styleguide</code> class can be used to add style guide specific CSS rules. Of course, you are free to use any HTML code you like.</p><p>In this example we add the name of the component as an uppercase headline. Afterwards we call the <a href="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-2#snippets">style guide component snippet</a> with the dummy content we already used for the over view page dynamically.</p></div>
<h2 class="text-h2">
	<a id="extending-the-style-guide-snippet" href="#extending-the-style-guide-snippet" tabindex="-1">
		Extending the style guide snippet	</a>
</h2>
<div class="text">
	<p>The last step is to extend this snippet with additional content.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">sites/snippets/styleguide/teaser.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">component/teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">modifier</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser--featured</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">headline</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">This is a Teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">image</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&lt;img src=&quot;https://placehold.co/600x400&quot; alt=&quot;Placeholder image&quot; width=&quot;600&quot; height=&quot;400&quot; &gt;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">text</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">Et quis cillum Lorem irure eu. In irure officia labore Lorem irure esse adipisicing proident.</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">url</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">#</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">
</span></span><span class="line" data-line="11"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">module</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">isNotEmpty</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">h2</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #79c0ff;">Additional</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Content</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">h2</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">p</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #79c0ff;">Here</span><span class="token"> </span><span class="token" style="color: #79c0ff;">you</span><span class="token"> </span><span class="token" style="color: #79c0ff;">can</span><span class="token"> </span><span class="token" style="color: #79c0ff;">add</span><span class="token"> </span><span class="token" style="color: #79c0ff;">additional</span><span class="token"> </span><span class="token" style="color: #79c0ff;">content</span><span class="token"> </span><span class="token" style="color: #ff7b72;">for</span><span class="token"> </span><span class="token" style="color: #79c0ff;">the</span><span class="token"> </span><span class="token" style="color: #79c0ff;">details</span><span class="token"> </span><span class="token" style="color: #79c0ff;">page</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #79c0ff;">because</span><span class="token"> </span><span class="token" style="color: #79c0ff;">the</span><span class="token"> </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">code</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">module</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">code</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">field</span><span class="token"> </span><span class="token" style="color: #79c0ff;">is</span><span class="token"> </span><span class="token" style="color: #79c0ff;">empty</span><span class="token"> </span><span class="token" style="color: #79c0ff;">on</span><span class="token"> </span><span class="token" style="color: #79c0ff;">the</span><span class="token"> </span><span class="token" style="color: #79c0ff;">overview</span><span class="token"> </span><span class="token" style="color: #79c0ff;">page</span><span class="token" style="color: #ff7b72;">.</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">p</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>To make sure this content will only be visible on the detail page, we check if <code>$page-&gt;content()-&gt;module()</code> is not empty. Everything else will also be shown on the overview page.</p></div>
<h2 class="text-h2">
	<a id="more-snippets" href="#more-snippets" tabindex="-1">
		More snippets?	</a>
</h2>
<div class="text">
	<p>Another option would be to move the additional content in another snippet and to call this snippet in the <code>styleguide-module</code> template dynamically, too. </p><p>Or if you want to show several variations of the teaser and re-use them elsewhere you could separate them into different snippets as well. There are no (snippet) limits. </p><p>Maybe I will pick up these ideas in another part of this series?! We’ll see.</p></div>
<h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://getkirby.com/docs/guide/routing#patterns">Kirby route patterns</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Building a component based style guide for Kirby (2)]]></title>
		<id>https://flokosiol.de/@/page/ITeU3dicn6suiBzh</id>
		<updated>2025-05-22T13:45:00+02:00</updated>
		<published>2025-05-22T13:45:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-2" />
		<category term="CMS" />
		<category term="Kirby" />
		<category term="PHP" />
		<content type="html" xml:base="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-2"><![CDATA[<div class="text">
	<p>In the <a href="/@/page/KpQCdRfGBPwMmWCq">first part</a> of this series I wrote about the concept of <a href="/@/page/KpQCdRfGBPwMmWCq">frontend components</a> and how they can be used in Kirby templates. But this was just the basis and nothing really new. In this second part I want to show how to build a style guide overview page on top of it.</p><p>There will be another follow up blog post about how to extend it furthermore to have single pages for each component with additional information.</p></div>
<h2 class="text-h2">
	<a id="plugin" href="#plugin" tabindex="-1">
		Plugin	</a>
</h2>
<div class="text">
	<p>To keep all the code organized we create a <a href="https://getkirby.com/docs/guide/plugins/custom-plugins">custom plugin</a>. The first step is to add a new folder with an <code>index.php</code> file to the plugins directory.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/plugins/styleguide/index.php
</span></span></code></pre><h2 class="text-h2">
	<a id="routing" href="#routing" tabindex="-1">
		Routing	</a>
</h2>
<div class="text">
	<p>To ensure that the style guide can be reached at <code>mydomain.com/styleguide</code> , we need to register a route. This can be done in the plugin definition inside the <code>index.php</code> file. But to keep this file clearly organized, the route itself is defined in a separate <code>site/plugins/styleguide/routes.php</code> file. Nevertheless Kirby's static <code>Kirby::plugin()</code> method needs to know about it. </p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #79c0ff;">Kirby</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">plugin</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">flokosiol/styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token">  </span><span class="token" style="color: #ff7b72;">require_once</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes.php</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>The <code>routes.php</code> file contains a single <a href="https://getkirby.com/docs/guide/routing">custom route</a>. This file is later filled with additional content, but for now this is sufficient. We also check for a logged in user to keep the content private. Of course you can omit this check if you want to keep it open to everyone.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/plugins/styleguide/routes.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">pattern</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">method</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">get</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">action</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token"> </span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">      </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #d2a8ff;">kirby</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">user</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">        </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #ff7b72;">new</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Page</span><span class="token">(</span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">slug</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">template</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">parent</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">kirby</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">site</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">homePage</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">          </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">content</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">        </span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">      </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token">      </span><span class="token" style="color: #ff7b72;">die</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="17"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="18"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="19"><span class="token">]</span><span class="token">;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="template" href="#template" tabindex="-1">
		Template	</a>
</h2>
<div class="text">
	<p>The route definition above instructs Kirby to use the <code>styleguide</code> template. Since it does not exist yet, we have to add it to our plugins folder and extend our plugin definition in the <code>index.php</code> file accordingly.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #79c0ff;">Kirby</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">plugin</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">flokosiol/styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token">  </span><span class="token" style="color: #ff7b72;">require_once</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes.php</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">templates</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">__DIR__</span><span class="token"> </span><span class="token" style="color: #ff7b72;">.</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">/templates/styleguide.php</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>The basic structure of the template file can pretty much look the same as every other template file in your installation. Personally, I like to use a <code>snippets/layout/html.php</code> file which holds the markup for header and footer and a <a href="https://getkirby.com/docs/guide/templates/snippets#passing-slots-to-snippets">slot</a> for the content. If you work with Kirby regularly this will probably look familiar to you.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/plugins/styleguide/templates/styleguide.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">layout/html</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #ffa657;">slots</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #79c0ff;">true</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">section</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #79c0ff;">Style</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Guide</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">!</span><span class="token" style="color: #ff7b72;">--</span><span class="token"> 
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;">FIXME: some kind of navigation</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;">FIXME: preview of all components</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="9"><span class="token">  </span><span class="token" style="color: #ff7b72;">--</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">
</span></span><span class="line" data-line="11"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">section</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">
</span></span><span class="line" data-line="13"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">endsnippet</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>The HTML structure inside this template is totally up to you and your needs. I like to wrap everything in a <code>styleguide</code> CSS class. It allows me to make style adjustments which are limited to the style guide without any side effects to the “real“ frontend components.</p><p>We should now be able to visit <code>mydomain.com/styleguide</code> and see the template in action. But not more than that.</p></div>
<h2 class="text-h2">
	<a id="snippets" href="#snippets" tabindex="-1">
		Snippets	</a>
</h2>
<div class="text">
	<p>Oh no, more snippets!? Yes! Before we can add the missing parts in our template, we have to add some style guide content. Let’s create a snippet folder inside the regular Kirby folder structure (outside of the plugin) and use the <code>teaser</code> frontend component from <a href="/@/page/KpQCdRfGBPwMmWCq">the first part of this series</a>. </p><p>Why outside of the plugin? These snippets are coupled tightly to the project but we want to keep the plugin reusable and keep custom code away if possible. The template file from above is already something which needs to be adjusted for every project. But the plugin won’t work without it, so we have to include it. In contrast, the snippets can be easily separated.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/snippets/styleguide/teaser.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">component/teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">modifier</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">headline</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">This is a Teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">image</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&lt;img src=&quot;https://placehold.co/600x400&quot; alt=&quot;Placeholder image&quot; width=&quot;600&quot; height=&quot;400&quot; &gt;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">text</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&lt;p&gt;Et quis cillum Lorem irure eu. In irure officia labore Lorem irure esse adipisicing proident. Nulla fugiat pariatur sunt nostrud nostrud.&lt;/p&gt;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">url</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">#</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>By using static content here, it is possible to build the <a href="/@/page/KpQCdRfGBPwMmWCq">frontend components</a> and the style guide before any Kirby backend logic or CMS content exists. If you already have access to some real data stored in Kirby, you can of course query and use that as well.</p></div>
<h2 class="text-h2">
	<a id="static-snippets" href="#static-snippets" tabindex="-1">
		Static snippets	</a>
</h2>
<div class="text">
	<p>There are use cases in my setup where I don’t use frontend components. One is the <strong>styling of rich text</strong> which comes from an editor field of the CMS and includes only basic HTML elements. I just wrap these elements inside a <code>.text</code> class so there’s no need for a dynamic component.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/snippets/styleguide/text.php
</span></span></code></pre>
<pre class="phiki language-html github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="html"><code><span class="line" data-line="1"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">div</span><span class="token"> </span><span class="token" style="color: #79c0ff;">class</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">text</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">h1</span><span class="token">&gt;</span><span class="token">Headline 1</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">h1</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">  </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">p</span><span class="token">&gt;</span><span class="token">Lorem ipsum dolor, sit amet consectetur adipisicing elit. </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">a</span><span class="token"> </span><span class="token" style="color: #79c0ff;">href</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">#</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">Link</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">a</span><span class="token">&gt;</span><span class="token"> assumenda </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">strong</span><span class="token">&gt;</span><span class="token">bold</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">strong</span><span class="token">&gt;</span><span class="token"> voluptatum </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">em</span><span class="token">&gt;</span><span class="token">italic</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">em</span><span class="token">&gt;</span><span class="token"> nulla modi repellat earum necessitatibus! Fugit autem debitis, dolore perspiciatis, ex explicabo delectus laboriosam vitae reiciendis, dolorum temporibus quas soluta!</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">p</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">ul</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">Veniam aliqua tempor cillum amet exercitation minim incididunt ipsum.</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">In mollit commodo magna id magna fugiat culpa dolor culpa laboris cillum. Deserunt enim cillum non pariatur in aute sint nostrud cupidatat. Anim do aliqua nulla minim officia ad consectetur ea sit commodo reprehenderit sit laborum quis.</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">Magna sunt exercitation et labore veniam. Incididunt tempor qui eu consectetur ullamco reprehenderit aliqua exercitation sit reprehenderit pariatur.</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">ul</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">  </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">ol</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">    </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">...</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">li</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">  </span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">ol</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">  </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">h2</span><span class="token">&gt;</span><span class="token">Headline 2 (maybe with additional text to force a line break)</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">h2</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">  </span><span class="token">&lt;</span><span class="token" style="color: #7ee787;">p</span><span class="token">&gt;</span><span class="token">And so on …</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">p</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">  </span><span class="token" style="color: #8b949e;">&lt;!--</span><span class="token" style="color: #8b949e;"> and so on ... </span><span class="token" style="color: #8b949e;">--&gt;</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">div</span><span class="token">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>The second use case for a static style guide snippet could be the preview of <strong>buttons</strong>. In my opinion, it makes no sense to build an abstracted frontend component, as experience has shown that this tends to complicate matters. Especially, if you want to style anchor elements as well as button elements. But I know developers who like to use a component here as well. Your choice!</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/snippets/styleguide/button.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">buttons</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">primary</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">Primary</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">secondary</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">Secondary</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">
</span></span><span class="line" data-line="8"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">buttons</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">variant</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">div</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">a</span><span class="token"> </span><span class="token" style="color: #79c0ff;">href</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">#</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">button button--&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">variant</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Link</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">a</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">button</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">button button--&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">variant</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Button</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">button</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">button</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">button button--&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">variant</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">disabled</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">Button</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #79c0ff;">disabled</span><span class="token">)</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">button</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">div</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endforeach</span><span class="token">;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Of course, this could be extended to several sizes or other button variations.</p></div>
<h2 class="text-h2">
	<a id="detecting-the-snippets-automatically" href="#detecting-the-snippets-automatically" tabindex="-1">
		Detecting the snippets automatically	</a>
</h2>
<div class="text">
	<p>All snippets inside the <code>site/snippets/stylegiude/</code> folder should be detected and fetched automatically and listed on our style guide page. Therefore we create a <a href="https://getkirby.com/docs/reference/plugins/extensions/site-methods">custom site method</a>. Like before, we keep the code out of the index.php file as well and collect all custom methods in a separate folder.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #79c0ff;">Kirby</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">plugin</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">flokosiol/styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token">  </span><span class="token" style="color: #ff7b72;">require_once</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes.php</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">siteMethods</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">require_once</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">methods/site.php</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">templates</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">__DIR__</span><span class="token"> </span><span class="token" style="color: #ff7b72;">.</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">/templates/styleguide.php</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre>
<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/plugins/styleguide/methods/site.php
</span></span></code></pre>
<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguideModules</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">modules</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token">[</span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">moduleFiles</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Dir</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">read</span><span class="token">(</span><span class="token" style="color: #d2a8ff;">kirby</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">roots</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">snippets</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">.</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">/styleguide</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">moduleFiles</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">fileinfo</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">      </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">filename</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #79c0ff;">F</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">name</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">fileinfo</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">      </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">modules</span><span class="token">[</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">filename</span><span class="token">]</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Str</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">upper</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">filename</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">    </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">    
</span></span><span class="line" data-line="13"><span class="token">    </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">modules</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">  </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">]</span><span class="token">;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>With Kirby’s <code>Dir::read</code> method we can scan the folder of the style guide snippets and find all the files in alphabetical order. The <code>F::name</code> method removes the file extension and the name of every snippet is pushed into an array which looks like this:</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">modules</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> ...</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="3"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">button</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">BUTTON</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">TEASER</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">text</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">TEXT</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> ...</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="7"><span class="token">]</span><span class="token">;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="add-the-missing-parts-to-the-template" href="#add-the-missing-parts-to-the-template" tabindex="-1">
		Add the missing parts to the template	</a>
</h2>
<div class="text">
	<p>The newly created site method can then be used to generate the overview of all components based on the example content of the style guide snippets. As soon as the list of components grows, a little jumpmark navigation at the beginning of the page can increase the usability significantly.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">layout/html</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #ffa657;">slots</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #79c0ff;">true</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">div</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">styleguide</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #79c0ff;">Style</span><span class="token"> </span><span class="token" style="color: #79c0ff;">Guide</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> jumpmark navigation </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">styleguideModules</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">site</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">styleguideModules</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">ul</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">styleguideModules</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">li</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">        </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">a</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">button</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">href</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">#&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">a</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">li</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endforeach</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">ul</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token">;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token">
</span></span><span class="line" data-line="17"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> list of all components based on the style guide snippets </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="18"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">site</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">styleguideModules</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">title</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="19"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">a</span><span class="token"> </span><span class="token" style="color: #79c0ff;">href</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">#</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">id</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">tabindex</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">-1</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">a</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="20"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">styleguide/</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">.</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">module</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="21"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endforeach</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="22"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">div</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="23"><span class="token">
</span></span><span class="line" data-line="24"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">endsnippet</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Depending on the layout of your site it is important to decide wether to add the markup of a container/wrapper element to the template (which will affect the whole page) or to each style guide snippet individually. The latter is the better choice if you have components which go full width and other which don’t.</p></div>
<h2 class="text-h2">
	<a id="whats-next" href="#whats-next" tabindex="-1">
		Whats next?	</a>
</h2>
<div class="text">
	<p>In the <a href="/@/page/yWDtXOGzsrQWLFTn">next part of this series</a> I demonstrate how to set up <strong>individual pages for each component</strong>, which can be used to add additional content or component variations.</p></div>
<h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://getkirby.com/docs/guide/plugins/custom-plugins">Custom plugin</a></li><li><a href="https://getkirby.com/docs/guide/routing">Routing</a></li><li><a href="https://getkirby.com/docs/guide/templates/snippets#passing-slots-to-snippets">Snippets with slots</a></li><li><a href="https://getkirby.com/docs/guide/templates/basics">Templates</a></li><li><a href="https://getkirby.com/docs/reference/plugins/extensions/site-methods">Custom site methods</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Building a component based style guide for Kirby (1)]]></title>
		<id>https://flokosiol.de/@/page/KpQCdRfGBPwMmWCq</id>
		<updated>2025-05-12T23:15:00+02:00</updated>
		<published>2025-05-12T23:15:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-1-frontend" />
		<category term="CMS" />
		<category term="Kirby" />
		<category term="PHP" />
		<content type="html" xml:base="https://flokosiol.de/articles/component-based-styleguide-kirby-cms-1-frontend"><![CDATA[<div class="text">
	<p>Some time ago, <a href="https://medienbaecker.com/">Thomas</a> published an article, in which he described how he creates an overview of UI components used in a project to test them in different constellations. He calls it <a href="https://medienbaecker.com/articles/kirby-playground">Kirby Playground</a>. It reminds me a lot of my custom style guide module, which I originally developed for Drupal a few years ago. But I use the same system for Kirby projects as well for quite a long time now. I would like to take this as an opportunity to explain my approach.</p><p>As the topic is very extensive, I am dividing it into several parts. Otherwise I would probably never finish the blog post. And Thomas insisted on this as we met at <a href="/@/page/0sHw2mnrXLkPYH5f">Beyond Tellerrand</a>.</p></div>
<h2 class="text-h2">
	<a id="the-goal" href="#the-goal" tabindex="-1">
		The goal	</a>
</h2>
<div class="text">
	<p>In the end we want to get an overview page of all the components (<a href="#frontend-components">see below</a>) used in the web project. This allows all components to be visually tested at a glance. It's a quick check if the frontend is working as expected and could be automated with Cypress or similar tools. This overview also makes it easier for several developers to work together, as well as to coordinate with the designers.</p><p>In addition we want a single page for every component, which can be used to add further instructions. Additional variants of the component, which would possibly overload the overview page, can be shown there as well. Optionally, the HTML source code or the implementation of the Kirby snippet can be displayed, which facilitates later integration into the CMS templates. We will cover this in the following parts of this series.</p></div>
<h2 class="text-h2">
	<a id="frontend-components" href="#frontend-components" tabindex="-1">
		Frontend components	</a>
</h2>
<div class="text">
	<p>The basis of the entire system is the use of frontend components. By this I mean the various ways used to display content on a website. These are, for example, banners, teasers or boxes – but also smaller elements such as buttons or simple text elements. </p><p>To keep every component separated, there is a directory <code>site/snippets/component/</code> in which all components are collected as <a href="https://getkirby.com/docs/guide/templates/snippets">Kirby snippets</a>. If you follow the <a href="https://bradfrost.com/blog/post/atomic-web-design/">atomic design</a> principle, you can of course define further subfolders. For my part, I get along well with a single directory.</p><p>These snippets provide the HTML structure. The aim is to ensure that this HTML does not have to be used anywhere else. This is not always feasible for all modules. Particularly with very small components such as buttons, I have found that a central snippet with all the variations often complicates matters. However, we can ignore this for the time being.</p><p>Example: A snippet for a teaser component would go into the <code>site/snippets/component/teaser.php</code> file and could look like this: </p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">article</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">teaser &lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">modifier</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?? &#039;&#039; ?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #ff7b72;">!</span><span class="token" style="color: #79c0ff;">empty</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">headline</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">h1</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">teaser__headline</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">headline</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">h1</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #ff7b72;">!</span><span class="token" style="color: #79c0ff;">empty</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">image</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">div</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">teaser__image</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">image</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">div</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #ff7b72;">!</span><span class="token" style="color: #79c0ff;">empty</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">text</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">p</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">teaser__text</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">text</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">p</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="17"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #ff7b72;">!</span><span class="token" style="color: #79c0ff;">empty</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">url</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="18"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">a</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">teaser__link</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">href</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">url</span><span class="token" style="color: #a5d6ff;"> </span><span class="token" style="color: #a5d6ff;">?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="19"><span class="token">      </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">t</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser.more</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">More</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="20"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">a</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="21"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="22"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">article</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p><strong>Each variable inside a component snippet is considered a string. This is important.</strong> There are no things like Kirby objects which makes it possible that we can easily pass simple static content to it. We come back again to this later. To avoid empty HTML elements we need a lot of <code>if</code> statements. If you don’t care about empty HTML elements (you should!) or if you make sure that every teaser comes, e.g. with a headline you could use <code>&lt;?= $headline ?? '' ?&gt;</code> instead and omit the <code>if</code> statement around.</p><p>The structure of HTML and CSS is totally up to you, of course. In this example we use the <a href="https://getbem.com/introduction/">BEM</a> system which separates the component styles strictly from each other. Every component has a matching SCSS/SASS file with the same name, e.g. <code>/src/styles/component/teaser.scss</code> .  This makes it very easy to find the related file in your editor.</p></div>
<h2 class="text-h2">
	<a id="component-snippets-in-action" href="#component-snippets-in-action" tabindex="-1">
		Component snippets in action	</a>
</h2>
<div class="text">
	<p>Now the components are ready to be used like every other Kirby snippet.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> assuming $article is a page object</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">component/teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">modifier</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser--featured</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">headline</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">article</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">title</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">esc</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">image</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">article</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">image</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">text</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">article</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">intro</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">kti</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">url</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">article</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">url</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="one-more-optional-layer" href="#one-more-optional-layer" tabindex="-1">
		One more (optional) layer …	</a>
</h2>
<div class="text">
	<p>You could stop here. But if this code is used in several places, I like to create another snippet. This might be confusing at first, but we need to separate the frontend component snippets (which will later also be used in the style guide) from the Kirby snippets which are tied to the page type. </p><p>One way could be to create a custom snippets folder and name the snippets based on the page type (article) and the component (teaser). In the end there would be a folder structure like this one:</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/snippets/custom/article-teaser.php
</span></span><span class="line" data-line="2"><span class="token">site/snippets/custom/article-card.php
</span></span><span class="line" data-line="3"><span class="token">site/snippets/custom/news-teaser.php
</span></span><span class="line" data-line="4"><span class="token">site/snippets/custom/news-card.php
</span></span></code></pre><div class="text">
	<p>Or if you prefer subfolders, the following structure might fit your needs a bit better.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/snippets/teaser/article.php
</span></span><span class="line" data-line="2"><span class="token">site/snippets/teaser/news.php
</span></span><span class="line" data-line="3"><span class="token">site/snippets/card/article.php
</span></span><span class="line" data-line="4"><span class="token">site/snippets/card/news.php
</span></span></code></pre><div class="text">
	<p>Based on the last structure the article teaser would be used somewhere in your Kirby templates like this and could then easily be re-used elsewhere.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">article</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">kirby</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">collection</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">articles</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">first</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser/article</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">article</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">article</span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">}</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="whats-next" href="#whats-next" tabindex="-1">
		Whats next?	</a>
</h2>
<div class="text">
	<p>In the <a href="/@/page/ITeU3dicn6suiBzh">next part</a> I want to show you, how to set up the routes to get an overview page as well as a detailed page for every component. </p></div>
<h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://medienbaecker.com/articles/kirby-playground">Kirby Playground</a> (Thomas Günther)</li><li><a href="https://getkirby.com/docs/guide/templates/snippets">Kirby Snippets</a> (Kirby Website)</li><li><a href="https://bradfrost.com/blog/post/atomic-web-design/">Atomic Design</a> (Brad Frost)</li><li><a href="https://getbem.com/introduction/">CSS BEM</a></li></ul></div>
<h2 class="text-h2">
	<a id="change-log" href="#change-log" tabindex="-1">
		Change Log	</a>
</h2>
<div class="text">
	<ul><li>12.05.2025 –&nbsp;Added examples how to <a href="#component-snippets-in-action">use frontend component snippets in Kirby templates</a></li><li>30.05.2025 –&nbsp;Added link to the <a href="/@/page/ITeU3dicn6suiBzh">follow-up blog post</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Juggling thoughts and inspiration – #btconf25]]></title>
		<id>https://flokosiol.de/@/page/0sHw2mnrXLkPYH5f</id>
		<updated>2025-05-09T23:25:00+02:00</updated>
		<published>2025-05-09T23:25:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/juggling-thoughts-inspiration-beyond-tellerrand-2025" />
		<category term="Inspiration" />
		<category term="Event" />
		<content type="html" xml:base="https://flokosiol.de/articles/juggling-thoughts-inspiration-beyond-tellerrand-2025"><![CDATA[<div class="text">
	<p>Coming back home from the <a href="https://beyondtellerrand.com/">beyond tellerrand</a> conference in Düsseldorf has always been like being energized and exhausted at the same time. But <a href="https://beyondtellerrand.com/events/dusseldorf-2025">this year</a> I feel like this effect is even stronger.</p><p>Back in <a href="https://beyondtellerrand.com/events/dusseldorf-2015/">2015</a> when I attended <a href="https://mastodon.social/tags/btconf">#btconf</a> for the first time I went there on my very own – on purpose. I was sure that if I would take a colleague or a friend of mine with me, it would prevent me from getting in touch with others. And it worked! I met new people in 2015 and I did so every year. Over time a feeling of <a href="/@/page/VYh22dlbpwqTHZTo">#Klassenfahrt</a> evolved. So I was very much looking forward to seeing all the lovely people again and (of course) meet new ones – spoiler: It worked!</p></div>
<figure data-ratio="auto">
    <img src="https://flokosiol.de/media/pages/articles/juggling-thoughts-inspiration-beyond-tellerrand-2025/57d0ea9aec-1746689667/beyond-tellerrand-2025.jpg" alt="A green-lit stage with a large screen on which “beyond tellerrand” is written in white and green colors. On the right-hand side, a DJ can be seen at a console.">
  
    <figcaption>
    Tobi Lessnow performing live on stage.  </figcaption>
  </figure>
<h2 class="text-h2">
	<a id="atmosphere" href="#atmosphere" tabindex="-1">
		Atmosphere	</a>
</h2>
<div class="text">
	<p>The atmosphere at beyond tellerrand is unique. As soon as you arrive at the location you can feel the positive vibe of this event and the love Marc puts into every single detail. It’s the artwork, the music (live performed by Tobi Lessnow) and so on. In the exhibition you can not only find the sponsors and their booths, but also information about projects for a good cause like <a href="https://www.skate-aid.org/">skate-aid</a>.</p></div>
<h2 class="text-h2">
	<a id="people" href="#people" tabindex="-1">
		People	</a>
</h2>
<div class="text">
	<p>Quite a lot of people attend beyond tellerrand regularly. Over the years you get to know each other and it’s always a pleasure to meet again. But as in 2015, I always try to make new contacts and talk to interesting people. Especially when I meet someone I only knew as avatar from social media or other online communities so far. And I no longer shy away from approaching the speakers and exchanging a few words with them. Which brings me to the …</p></div>
<h2 class="text-h2">
	<a id="talks" href="#talks" tabindex="-1">
		Talks	</a>
</h2>
<div class="text">
	<p>I don’t pay too much attention to the list of speakers and what they will talk about before the event. Marc has always had a good feeling for which speakers he invites and <a href="https://beyondtellerrand.com/blog/creating-the-schedule">how to create a great schedule</a>. In this way it’s kind of a surprise for me. I would like to highlight a few of the talks from this year which I like the most.</p><p>Opening the event is not easy, but <a href="https://www.paulazuccotti.com/">Paula Zuccotti</a> did a great job with her talk “<strong>Every Thing We Touch“</strong>. As part of this project she met interesting people from all over the world who live very different lives. She asked them to bring all the things with them which they touch on a daily basis and arranged it for a nice photo. The talk left me thinking about wich things would be on my photo and if there are other things I would like to use more often!? <br><br><a href="https://tink.uk/">Léonie Watson</a> dealt with the use of AI and all its facets, and also took a critical look at the negative aspects with her talk <strong>“There Is No Spoon“</strong>. If you are familiar with the first Matrix movie, you probably know which spoon she was talking about. From an accessibility point of view AI can definitely be a game changer, especially for blind people like her because image recognition has made a huge process in the last time.</p><p><strong>“Less Thinkering More Tinkering“</strong> was the last talk of day one and it was like a ride in a (pink) rollercoaster. <a href="https://www.jam-factory.com/">Gavin Strange</a> is a designer and director who works at <a href="https://www.aardman.com/">Aardman</a> – the company behind Wallace &amp; Gromit. His energy level and his level of excitement was unbelievable. He showed some of his work and it was so inspiring to see him bringing his stupid (in a very positive way!) ideas to live. If you have an idea and want it to become reality – do it!</p><p><a href="https://matthiasott.com/">Matthias Ott</a> kicks off day two with <strong>“Painting With the Web“</strong>. His calm manner was almost exactly the opposite of how the day before ended. Nevertheless it was very inspiring and a great reminder to use the cool new feature CSS offers. He encourages designers to bypass the limitations of current design tools and instead work directly in the browser when appropriate. It is often sufficient to implement certain functions as a prototype. But developers should also not shy away from dealing with design and thus increasing the intersection between the disciplines. I know Matthias for some time now and was very much looking forward to seeing him on stage. Very well done, Matthias!</p><p>If you know Smashing Magazine or anything else from the Smashing Universe, <a href="https://www.smashingmagazine.com/author/vitaly-friedman/">Vitaly Friedman</a> is a name you already heard for sure. He showed an excerpt of his giant presentation <strong>“Inclusive Design Patterns“</strong> (with over a thousand slides!) and talked about aspects of accessibility which you might not think about in the first place. His enthusiasm for the topic was clear to see, and not just because he stretched the time frame a little and was hard to get off the stage.</p></div>
<h2 class="text-h2">
	<a id="impressions" href="#impressions" tabindex="-1">
		Impressions	</a>
</h2>
<div class="text">
	<p>For more impressions you should have a look at the website of <a href="https://florianziegler.com/">Florian Ziegler</a> and the <a href="https://florian.photo/collection/beyond-tellerrand">beyond tellerand collection</a> of his photo blog. A few photos are already online. Usually there will be an update some days after the event.</p></div>
<h2 class="text-h2">
	<a id="next" href="#next" tabindex="-1">
		Next?	</a>
</h2>
<div class="text">
	<p>It’s hard to organize conferences like beyond tellerrand these days. If you follow Marc on social media you might have noticed already. But just like the independent web or the indie music scene we should try to support independent conferences, too. So do yourself a favor and meet me and the #Klassenfahrt gang next year in Düsseldorf – or grab a ticket for the <a href="https://beyondtellerrand.com/events/berlin-2025">Berlin</a> edition in November!</p><p>Until then, I’ll try to sort all the thoughts and inspiration of the last days which I am still juggling in my head …</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Drowning in tabs?]]></title>
		<id>https://flokosiol.de/@/page/r119UfZBnbxvKOys</id>
		<updated>2025-04-17T17:50:00+02:00</updated>
		<published>2025-04-17T17:50:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/drowning-in-tabs" />
		<category term="General" />
		<category term="Raycast" />
		<content type="html" xml:base="https://flokosiol.de/articles/drowning-in-tabs"><![CDATA[<div class="text">
	<p>How often do I see people clicking around their one million open browser tabs to find the right one?! I don't get it, folks. There are a few options to organize this stuff! I know …</p></div>
<blockquote>
  ”Everybody can handle order, but only a genius can master chaos“    <footer>
    Albert Einstein (probably)  </footer>
  </blockquote>
<div class="text">
	<p>…&nbsp;but to be clear: it’s not about the chaos introduced by this massive amount of tabs –&nbsp;it's about not being able to handle it.</p></div>
<h2 class="text-h2">
	<a id="built-in-tab-search" href="#built-in-tab-search" tabindex="-1">
		Built-in tab search	</a>
</h2>
<div class="text">
	<p>This is probably the easiest strategy. You can still have a trillion open tabs in a single browser window like before. So no need to change this learned behavior. But you can use the built-in search modern browsers provide or use a Raycast Extension (see <a href="#close-it">below</a>).</p></div>
<div class="text">
	<table>
				<thead>
		<tr>
							<th>Browser</th>
							<th>Command (Mac)</th>
					</tr>
		</thead>
		<tbody>
					<tr>
									<td>Firefox</td>
									<td><a href="https://support.mozilla.org/en-US/kb/search-open-tabs-firefox">Some clicks needed</a></td>
							</tr>
					<tr>
									<td>Safari</td>
									<td><code>⇧ + ⌘ + #</code> or <code>⇧ + ⌘ + \</code></td>
							</tr>
					<tr>
									<td>Edge</td>
									<td><code>⇧ + ⌘ + A</code></td>
							</tr>
					<tr>
									<td>Chrome</td>
									<td><code>⇧ + ⌘ + A</code></td>
							</tr>
				</tbody>
	</table>
</div>
<div class="text">
	<p>I don't have a Windows computer or one running Linux, but if someone sends me the shortcuts I will happily add them here.</p></div>
<h2 class="text-h2">
	<a id="tab-groups" href="#tab-groups" tabindex="-1">
		Tab groups	</a>
</h2>
<div class="text">
	<p>(Almost) all modern browsers provide a feature where you can group your tabs together. If you find yourself opening tabs totally unrelated to the one you were originally looking for, consider to group them. In this way all the tabs from an unrelated group are hidden and only the ones of the current group are visible.</p><p>To be honest, the user experience of <a href="https://support.apple.com/en-il/guide/safari/ibrwd0cea393/mac">Safari tab groups</a> is not that great. The groups are organized in the sidebar and can’t be accessed quickly if you don’t want to keep it open all the time.</p><p>Between <a href="https://blog.google/products/chrome/manage-tabs-with-google-chrome/">Chrome</a> and <a href="https://www.microsoft.com/en-us/edge/features/tab-groups?form=MA13FJ">Edge</a> there’s no real difference how tab groups are handled. This is no surprise since Edge is based on Chromium. You can combine multiple tabs, label the group with a custom name and a color which makes it much easier to differentiate between groups. </p><p>At the time of writing the <a href="https://support.mozilla.org/en-US/kb/tab-groups">Firefox tab groups</a> feature is experimental and may not yet be available to all users. But I am confident that this will soon be launched for everyone.</p></div>
<h2 class="text-h2">
	<a id="multiple-browsers" href="#multiple-browsers" tabindex="-1">
		Multiple Browsers	</a>
</h2>
<div class="text">
	<p>This one is my favorite approach. I use different browsers for different purposes. There’s one (Opera in my case) for my web apps like time tracking and things like that. The tabs are all pinned to prevent them from being closed by mistake. </p><p>I (still) use Chrome for development and as soon as my work for a project is done I close all tabs and windows. Even if I plan to come back later this day. In addition I use a separate window for each environment. If one tab is the local copy of the website I can be sure all other tabs of this window are too. For the staging or the production server I use different windows. Switching apps or windows or rearranging them on my screen is done with keyboard commands so having multiple windows open is definitely no problem.</p><p>For regular browsing I use the <a href="https://duckduckgo.com/">DuckDuckGo</a> Browser which is pretty good in terms of privacy protection. All my web search is done with the DuckDuckGo search. </p></div>
<h2 class="text-h2">
	<a id="close-it" href="#close-it" tabindex="-1">
		Close it	</a>
</h2>
<div class="text">
	<p>Yes, it is allowed to close tabs! Bookmarks are a great way to organize URLs for later use. And since they are searchable as well it should be easy to find them again. There a great <strong>Raycast extensions</strong> for that for <a href="https://www.raycast.com/Codely/google-chrome">Chrome</a>, <a href="https://www.raycast.com/crisboarna/mozilla-firefox">Firefox</a>, <a href="https://www.raycast.com/loris/safari">Safari</a> and <a href="https://www.raycast.com/KartikKumarSahoo/microsoft-edge">Edge</a>, and even for <a href="https://www.raycast.com/ron-myers/brave">Brave</a> or <a href="https://www.raycast.com/crisboarna/vivaldi">Vivaldi</a>. Some of them can search for open tabs as well. Do you remember? This was how we started.</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[The Good, the Bad and the Bisect]]></title>
		<id>https://flokosiol.de/@/page/68AF5LlQxkGHIuBs</id>
		<updated>2025-04-04T13:00:00+02:00</updated>
		<published>2025-04-04T13:00:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/the-good-the-bad-and-the-bisect" />
		<category term="Git" />
		<content type="html" xml:base="https://flokosiol.de/articles/the-good-the-bad-and-the-bisect"><![CDATA[<div class="text">
	<p>Lately I had an issue with my Kirby installation. The custom panel fields, introduced by a plugin, threw an error. I was sure that they worked before, but couldn't find the error by myself. Fortunately, I remembered that git has feature to find a commit which introduced a bug by using binary search: <a href="https://git-scm.com/docs/git-bisect">git bisect</a>.</p><p>Since Kirby is all file based, it's easy to check out older commits and test if the panel worked at that point of the git history. And this is exactly how <code>git bisect</code> works.</p></div>
<h2 class="text-h2">
	<a id="preparations" href="#preparations" tabindex="-1">
		Preparations	</a>
</h2>
<div class="text">
	<p>To start the search for the commit which introduced a bug, you have open your terminal and check out a version from the git history which worked. To list all commits you can use the <code>log</code> command. I prefer the shorter <code>--oneline</code> output.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">git log --oneline
</span></span></code></pre><div class="text">
	<p>Copy the hash of a commit before the bug was introduced. And (optionally) one afterwards.</p></div>
<h2 class="text-h2">
	<a id="lets-start" href="#lets-start" tabindex="-1">
		Lets'start	</a>
</h2>
<div class="text">
	<p>Now you have to tell git, that the search can begin.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">git bisect start
</span></span></code></pre><div class="text">
	<p>Afterwards git wants to know which commit was a “good“ one and which was “bad“. Instead of the commit hashes you can also use tags. If you omit the hash or tag for the bad one, git uses the latest commit.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">git bisect good c3e2cd0
</span></span><span class="line" data-line="2"><span class="token">git bisect bad
</span></span></code></pre><div class="text">
	<p>Git responds with the amount of revisions between these commits and roughly estimates how many steps will be necessary to find the “bad“ one.</p></div>
<h2 class="text-h2">
	<a id="good-or-bad" href="#good-or-bad" tabindex="-1">
		Good or bad?	</a>
</h2>
<div class="text">
	<p>Git also checks out a commit in the middle. Now you have to check your project and if the bug is still present you have to tell git that the situation is still bad by using this command:</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">git bisect bad
</span></span></code></pre><div class="text">
	<p>But if the bug is gone you have to use:</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">git bisect good
</span></span></code></pre><div class="text">
	<p>You have to repeat this game until the commit you were looking for was found. In the end, git will present you the commit with all the corresponding files which can now be analysed. If you keep your commits organized with a good commit message and without committing a hundred unrelated files at once there is a good chance to find the bug.</p><p>Finally, you have to stop the bisect mode with:</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">git bisect reset
</span></span></code></pre><div class="text">
	<p>That's it.<br></p></div>
<h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://git-scm.com/docs/git-bisect">git bisect</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Content warnings as HTML standard?]]></title>
		<id>https://flokosiol.de/@/page/BmuvW6jOvIx6qTRH</id>
		<updated>2025-03-21T23:45:00+01:00</updated>
		<published>2025-03-21T23:45:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/content-warnings-html-standard" />
		<category term="HTML" />
		<category term="General" />
		<content type="html" xml:base="https://flokosiol.de/articles/content-warnings-html-standard"><![CDATA[<div class="text">
	<p>I really like the possibility to add content warnings to Mastodon posts. It depends on your Mastodon app or client how this is handled in detail but the idea is to hide sensitive or triggering content initially. After you gave your consent, the content gets revealed. I just thought about, that this could (or better should) become a standard in HTML, too.</p></div>
<h2 class="text-h2">
	<a id="html-meta-tag" href="#html-meta-tag" tabindex="-1">
		HTML meta tag	</a>
</h2>
<div class="text">
	<p>I have absolutely no idea how browsers are built, but the implementations for web developers could be quite easy. In HTML there is a working system of meta tags in the <code>&lt;head&gt;</code> section of a website which could be used.</p></div>

<pre class="phiki language-html github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="html"><code><span class="line" data-line="1"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">meta</span><span class="token"> </span><span class="token" style="color: #79c0ff;">name</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">content-warning</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">content</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">some information or pre-defined categories</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>It’s just a rough idea, but as a first draft it should do the trick. Now the content warning could be shown before you visit a website, just like the security warning if SSL certificates are not available or invalid. </p></div>
<h2 class="text-h2">
	<a id="html-element-attribute" href="#html-element-attribute" tabindex="-1">
		HTML element attribute	</a>
</h2>
<div class="text">
	<p>With an additional attribute for elements it would be possible to mark sensitive content on the page instead of blocking it as a whole.</p></div>

<pre class="phiki language-html github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="html"><code><span class="line" data-line="1"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">section</span><span class="token"> </span><span class="token" style="color: #79c0ff;">content-warning</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">some information or pre-defined categories</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  ...
</span></span><span class="line" data-line="3"><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">section</span><span class="token">&gt;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="from-a-users-perspective" href="#from-a-users-perspective" tabindex="-1">
		From a user’s perspective	</a>
</h2>
<div class="text">
	<p>If the user visits a website with a content warning regularly, one could mark a specific domain as trusted and hide the warning for every page of this website from now on. With a standard for common categories, it would also be possible to block only pages with a specific topic to minimize browser interruptions. </p></div>
<h2 class="text-h2">
	<a id="existing-solutions" href="#existing-solutions" tabindex="-1">
		Existing solutions	</a>
</h2>
<div class="text">
	<p>I did a quick search if something like this already exists and found a <code>category</code> meta tag which I didn’t know before. Unfortunately I still don’t know how it is used? Maybe someone who’s smarter than I am could explain it to me? Is it just for search engines?</p></div>

<pre class="phiki language-html github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="html"><code><span class="line" data-line="1"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">meta</span><span class="token"> </span><span class="token" style="color: #79c0ff;">name</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">category</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">content</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">…</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Furthermore I found an <a href="https://github.com/whatwg/html/issues/10807">open issue</a> on GitHub for the <a href="https://whatwg.org/">WHATWG</a> which suggests pretty much the same thing but has received little attention so far. Of course I am not the first to come up with this idea. But I didn’t found that much information around the topic.</p><p>From my point of view content warnings in HTML could make another small contribution to making the web more secure and inclusive. </p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://github.com/whatwg/html/issues/10807">GitHub issue for content warning</a></li><li><a href="https://whatwg.org/">WHATWG Website</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[A different approach to the Kirby content() method?]]></title>
		<id>https://flokosiol.de/@/page/Yz06PGHsmlq5Sd8p</id>
		<updated>2025-03-15T17:50:00+01:00</updated>
		<published>2025-03-15T17:50:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/different-approach-kirby-content-method" />
		<category term="CMS" />
		<category term="Kirby" />
		<category term="PHP" />
		<content type="html" xml:base="https://flokosiol.de/articles/different-approach-kirby-content-method"><![CDATA[<div class="text">
	<p>If you work with Kirby you are familiar with the concept of creating fields in a page blueprint and accessing it in your <a href="https://getkirby.com/docs/guide/templates/basics#the-page-variable">page template</a>. Usually you end up with something like this:</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">myField</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>As long as your field name does not match a <a href="https://getkirby.com/docs/guide/templates/basics#reserved-words">reserved word</a> you’re fine. But as soon as your field name has the same name as an existing page method you need to make use of the <code>content()</code> method (and everything is fine again).</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">myField</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Since I use custom page methods on a regular basis, I prefer to use the <code>content()</code> method for <em>every</em> page field. No matter if there’s a naming conflict or not. In this way it is easier to me to differentiate between page methods and fields. </p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">url</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">customPageMethod</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">myField</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Unfortunately it requires more typing and (in my opinion) it's a bit harder to read as well.</p></div>
<h2 class="text-h2">
	<a id="introducing-a-content-variable" href="#introducing-a-content-variable" tabindex="-1">
		Introducing a $content variable	</a>
</h2>
<div class="text">
	<p>Lately I had the idea to create a custom <code>$content</code> variable and use it across all page templates. The right place for additional variables for your page template is a <a href="https://getkirby.com/docs/guide/templates/controllers">controller</a>. Every page template can have its own controller. But there is also a <a href="https://getkirby.com/docs/guide/templates/controllers#general-site-controller">general site controller</a> which is useful if multiple templates share the same logic.</p><p><code>/site/controllers/site.php</code></p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">content</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">}</span><span class="token">;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>With this few lines it is now possible to use a <code>$content</code> variable as a replacement of <code>$page-&gt;content()</code> across all page template. The page template example from above can be be changed to the following. It might look unusual at first but I think i’ll give it a try.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">url</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">customPageMethod</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">content</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">myField</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Please be aware that, as soon as you create a custom controller for a single page type, you need to define the <code>$content</code> variable again. Since it’s just a single line of code, I think it’s not a big deal. If you have more variables you want to share, check out this tutorial about how to create a <a href="https://getkirby.com/docs/cookbook/development-deployment/shared-controllers#setting-up-the-shared-controller">shared controller</a> setup by  <a href="https://manuelmoreale.com/">Manu Moreale</a>. By the way, with Kirby 5 the shared controller setup will no longer be necessary because the general site controller will automatically be merged.</p></div>
<h2 class="text-h2">
	<a id="one-more-thing" href="#one-more-thing" tabindex="-1">
		One more thing …	</a>
</h2>
<div class="text">
	<p>As <a href="https://fvsch.com/">Florens</a> mentioned on <a href="https://hachyderm.io/@fvsch/114171841539924136">Mastodon</a>, this approach only works while <code>$page</code> represents the current page, because the variables defined within the controller are only available in the corresponding page template. That’s a valid point you have to keep in mind. </p><p>But in combination with <a href="/@/page/nn0FSGvIY5k0iTCq">custom view modes</a> it still might be a way to go because if you use these view modes consequently it will probably reduce the amount of situations where <code>$page</code> is not the current page. I will try both in combination and might come back with a report of my findings.</p></div>
<h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://getkirby.com/docs/guide/templates/basics#the-page-variable">Kirby $page variable</a></li><li><a href="https://getkirby.com/docs/reference/objects/panel/page/content">Kirby page content() method</a></li><li><a href="https://getkirby.com/docs/guide/templates/controllers">Kirby controllers</a></li><li><a href="https://getkirby.com/docs/cookbook/development-deployment/shared-controllers#setting-up-the-shared-controller">Shared controllers</a></li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Use Kirby content representations for custom view modes]]></title>
		<id>https://flokosiol.de/@/page/nn0FSGvIY5k0iTCq</id>
		<updated>2025-02-17T00:00:00+01:00</updated>
		<published>2025-02-17T00:00:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/kirby-content-representations-custom-view-modes" />
		<category term="CMS" />
		<category term="Kirby" />
		<category term="PHP" />
		<category term="OpenSource" />
		<content type="html" xml:base="https://flokosiol.de/articles/kirby-content-representations-custom-view-modes"><![CDATA[<div class="text">
	<p>With <a href="https://getkirby.com/docs/guide/templates/content-representations">content representations</a> Kirby has a powerful way to display the content of a page in a <a href="https://getkirby.com/docs/guide/templates/content-representations#examples-for-using-content-representations">different way</a>. Usually, this refers to a single page when it is requested at a specific URL. I also work a lot with Drupal and I  appreciate the concept of view modes where the content of a page type is prepared for different views, but is not linked to a specific URL like with content representations. The classic example is the teaser view, i.e. how a page is displayed as a teaser within another page. </p><p>My idea is to use the existing system of content representations for view modes. In the end, I would like to be able to write something like this in my template:</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">kirby</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">collection</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">different-teaser-pages</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">teaser</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">teaser</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">viewMode</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endforeach</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Afterwards the different page types are rendered in the “teaser” view mode, whereby each type defines how this should look like by itself. This can be very similar to each other, but also completely different.</p><p>By the way, how to collect pages using the <code>collection()</code> method like in the example can be found in the <a href="https://getkirby.com/docs/guide/templates/collections">Kirby collections guide</a>.</p></div>
<h2 class="text-h2">
	<a id="content-representations" href="#content-representations" tabindex="-1">
		Content representations	</a>
</h2>
<div class="text">
	<p>Let's start simple. Content representations are usually used to display the content of a page in a different format, for example as JSON, XML, PDF, ... you name it. If you are not yet familiar with this, you should take a closer look at the following link. It also describes how the additional templates must be named and via which URL they can then be accessed. This is important for the further procedure.</p><p><a href="https://getkirby.com/docs/guide/templates/content-representations">Kirby content representations guide</a></p><p>To create a template for a teaser variant of a page, we create a separate file in the template directory for each page type. Let's use “news” and “event” as example.</p></div>

<pre class="phiki language-text github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="text"><code><span class="line" data-line="1"><span class="token">site/templates/news.teaser.php
</span></span><span class="line" data-line="2"><span class="token">site/templates/event.teaser.php
</span></span></code></pre><div class="text">
	<p>We can now define the markup for the “teaser” view mode in this template with the same possibilities as in any other <a href="https://getkirby.com/docs/guide/templates/basics">page template</a>. You can use snippets or simplify the code with the help of <a href="https://getkirby.com/docs/guide/templates/content-representations#representation-controllers">representation controllers</a> which are based on general <a href="https://getkirby.com/docs/guide/templates/controllers">controllers</a>.</p><p>An example template for the news teaser would be …</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> site/templates/news.teaser.php</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> 
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #d2a8ff;">snippet</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">card</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">title</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">title</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">text</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">introtext</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">kti</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">url</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">url</span><span class="token">(</span><span class="token">)</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">  </span><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>For an event we use a different template.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">#</span><span class="token" style="color: #8b949e;"> site/templates/event.teaser.php</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="2"><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">section</span><span class="token"> </span><span class="token" style="color: #ff7b72;">class</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">event-teaser</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">h2</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #d2a8ff;">t</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">Event</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">h2</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">p</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">content</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">text</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">kti</span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">p</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">ul</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">foreach</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">categories</span><span class="token">(</span><span class="token">)</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">split</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">|</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">as</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">category</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">li</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">category</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">li</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">    </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endforeach</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">ul</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">section</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>The markup is of course only an example. However, it is important that the template is <strong>not</strong> a complete HTML document with <code>&lt;head&gt;</code> and <code>&lt;body&gt;</code>, but only contains the markup of the component. After all, it is to be output later within an existing page.</p></div>
<h2 class="text-h2">
	<a id="custom-page-methods" href="#custom-page-methods" tabindex="-1">
		Custom page methods	</a>
</h2>
<div class="text">
	<p>Now we need to be able to use the templates we have just created. With <a href="https://getkirby.com/docs/reference/plugins/extensions/page-methods">custom page methods</a>, Kirby offers an extremely flexible tool for extending the page object with your own methods. We want to use this to call our view modes. For this, we need to create our own <a href="https://getkirby.com/docs/guide/plugins/custom-plugins">plugin</a> with at least an <code>index.php</code> file.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #79c0ff;">Kirby</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">plugin</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">flokosiol/viewmode</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">pageMethods</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">viewMode</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">viewMode</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">      </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">html</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">      </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #ff7b72;">!</span><span class="token" style="color: #79c0ff;">empty</span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">viewMode</span><span class="token">)</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">        </span><span class="token" style="color: #ff7b72;">try</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">          </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> render the page as a $viewMode content representation</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="8"><span class="token">          </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">html</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #79c0ff;">$</span><span class="token" style="color: #79c0ff;">this</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">render</span><span class="token">(</span><span class="token">[</span><span class="token">]</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">viewMode</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">        </span><span class="token">}</span><span class="token"> </span><span class="token" style="color: #ff7b72;">finally</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">          </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">html</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">      </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">      </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">html</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">    </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="16"><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Now we are able to use the new <code>viewMode()</code> method for our <code>$page</code> object as mentioned at the very beginning. If we call a view mode which doesn't exists, the page method will return an empty string to prevent any errors.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">viewMode</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="route-blocking" href="#route-blocking" tabindex="-1">
		Route blocking	</a>
</h2>
<div class="text">
	<p>Content representations are by design accessible via their URL. This is intended! Otherwise they wouldn't make any sense. But since we use it for a different purpose, we might want to block these pages. For example, if the regular page is <code>https://mydomain.com/news/my-latest-article</code> a view mode <code>teaser</code> would be accessible via <code>https://mydomain.com/news/my-latest-article.teaser</code>.</p><p>To block all URLs for the <code>teaser</code> view mode we need to set up a custom route which blocks all URLs ending on <code>.teaser</code>. Obviously you should double check, that no regular page ends with this pattern!</p><p>We need to extend our plugin a little bit to achieve this. Multiple route patterns can be combined as an array. The following example shows another route blocking pattern for an “event“ view mode.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #79c0ff;">Kirby</span><span class="token" style="color: #ff7b72;">::</span><span class="token" style="color: #d2a8ff;">plugin</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">flokosiol/viewmode</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">pageMethods</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> see above</span><span class="token" style="color: #8b949e;">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">  </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">routes</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">kirby</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="6"><span class="token">    </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token">      </span><span class="token">[</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">        </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">pattern</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token">[</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">(:all).teaser</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">(:all).event</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">        </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">action</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #ff7b72;">function</span><span class="token"> </span><span class="token">(</span><span class="token">)</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="10"><span class="token">          </span><span class="token" style="color: #ff7b72;">return</span><span class="token"> </span><span class="token" style="color: #79c0ff;">false</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="11"><span class="token">        </span><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="12"><span class="token">      </span><span class="token">]</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="13"><span class="token">    </span><span class="token">]</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="14"><span class="token">  </span><span class="token">}</span><span class="token">,</span><span class="token">
</span></span><span class="line" data-line="15"><span class="token">]</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="ready-to-use-plugin" href="#ready-to-use-plugin" tabindex="-1">
		Ready to use plugin	</a>
</h2>
<div class="text">
	<p>To make this feature ready to use for everyone, I wrapped everything in a plugin.</p><p><a href="https://github.com/flokosiol/kirby-viewmode">https://github.com/flokosiol/kirby-viewmode</a></p></div>
<h2 class="text-h2">
	<a id="links" href="#links" tabindex="-1">
		Links	</a>
</h2>
<div class="text">
	<ul><li><a href="https://github.com/flokosiol/kirby-viewmode">Kirby View Mode Plugin</a> (GitHub)</li><li><a href="https://getkirby.com/docs/guide/templates/content-representations">Content Representations</a> (Kirby Guide)</li><li><a href="https://medienbaecker.com/articles/content-representations">Content Representations</a> (Medienbäcker)</li><li><a href="https://www.drupal.org/docs/drupal-apis/entity-api/display-modes-view-modes-and-form-modes">Drupal View Modes</a> (Drupal.org)</li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Four years of #DeleteWhatsApp]]></title>
		<id>https://flokosiol.de/@/page/jowUTNeDUIjp7XLX</id>
		<updated>2025-02-01T23:59:00+01:00</updated>
		<published>2025-02-01T23:59:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/4-years-without-whatsapp" />
		<category term="OpenSource" />
		<category term="Inspiration" />
		<content type="html" xml:base="https://flokosiol.de/articles/4-years-without-whatsapp"><![CDATA[<div class="text">
	<p>Exactly 4 years ago, I deleted WhatsApp from my phone and it will definitely stay that way. Since WhatsApp was acquired by Facebook back in 2014, there have been repeated discussions about user data being shared between these platforms. Although the sharing within the EU was probably not quite as extensive as in the rest of the world, it still existed. I had already deleted my Facebook account in 2017 (when Facebook was still popular) and so I didn't want to allow a new connection here if possible. At the beginning of 2021, a change to the WhatsApp terms of use was announced, which once again led to a lot of media attention. Anyone who did not agree to their data being passed on to Facebook would no longer have access to WhatsApp.</p></div>
<blockquote>
  In January 2021, WhatsApp announced a controversial new Privacy Policy allowing WhatsApp to share data with its parent company, Facebook; users who did not accept by February 8, 2021, would lose access to the app.    <footer>
    <a href="https://en.wikipedia.org/wiki/WhatsApp#Since_2020">https://en.wikipedia.org/wiki/WhatsApp#Since_2020</a>  </footer>
  </blockquote>
<div class="text">
	<p>I had thought about deleting it before, but at that point my motivation was high enough. My last messages on WhatsApp were the information that I would soon no longer be there. I finally deleted WhatsApp from my phone. Would I now miss out on all the important updates, especially from the many group chats?</p><p>When asked what my motives were for taking this insane step, comparing the data protection information in the AppStore was always a good argument. It still is today!</p></div>
<h2 class="text-h2">
	<a id="whatsapp-privacy" href="#whatsapp-privacy" tabindex="-1">
		WhatsApp Privacy	</a>
</h2>
<figure data-ratio="auto">
    <img src="https://flokosiol.de/media/pages/articles/4-years-without-whatsapp/9a07eae4df-1740084872/whatsapp-privacy-appstore.png" alt="Screenshot of the WhatsApp privacy practices on the AppStore showing all the data which may be collected and linked to the user.">
  
    <figcaption>
    Apple AppStore, 01.02.2025  </figcaption>
  </figure>
<h2 class="text-h2">
	<a id="signal-privacy" href="#signal-privacy" tabindex="-1">
		Signal Privacy	</a>
</h2>
<figure data-ratio="auto">
    <img src="https://flokosiol.de/media/pages/articles/4-years-without-whatsapp/122f1ce148-1740084871/signal-privacy-appstore.png" alt="Screenshot of the Signal privacy practices on the AppStore showing only a single data which may be collected but is not linked to the user.">
  
    <figcaption>
    Apple AppStore, 01.02.2025  </figcaption>
  </figure>
<h2 class="text-h2">
	<a id="who-s-in" href="#who-s-in" tabindex="-1">
		Who's in?	</a>
</h2>
<div class="text">
	<p>My family and (almost all) important contacts from my circle of friends were quite quickly willing to use Signal as well as WhatsApp. A few of them, like me, had already been doing so for a while. But even today, there are still some people who “don't want another app” on their phone. I would be interested to know whether they actually pay that much attention to the number of apps installed ... not really an argument for me.</p></div>
<h2 class="text-h2">
	<a id="what-did-change" href="#what-did-change" tabindex="-1">
		What did change?	</a>
</h2>
<div class="text">
	<p>In the beginning, there were no <strong>status</strong> updates on Signal to let other people know what you were doing without having to write a direct message to everyone. As a result, you naturally missed out on a lot of information from your contacts. However, from that day on, I spent much less time on my phone because these status updates were always numerous and took up a significant amount of my time. This feature is now also available on Signal, but it is used by far fewer people and is no longer very important to me. Definitely a win!</p><p>Probably the biggest change was the <strong>group chats</strong>. Signal offered this feature long before I switched, but most people still use WhatsApp as their primary messenger. Fortunately, I was part of only a few groups when I was on WhatsApp, but I miss most of them until now. At school, the question of whether we could also use Signal as a communication channel at least came up this year. In the end, it didn't catch on, but at least it was discussed once. After all.</p></div>
<h2 class="text-h2">
	<a id="all-alone" href="#all-alone" tabindex="-1">
		All alone?	</a>
</h2>
<div class="text">
	<p>Last year there was an information event at my children's school on the subject of media consumption and children's phone use. To get an impression of the audience (parents), the speaker started by asking a few questions on this topic. One of them was: “How many of you don't use WhatsApp?” Of the 250-300 parents present, I was the only one who raised my hand.</p><p>I just realized that <u><a href="https://flokosiol.de/articles/4-years-without-whatsapp/%E2%80%9Chttps://mastodon.social/tags/globalswitchday%E2%80%9D">#GlobalSwitchDay</a></u> was proclaimed today. What a coincidence. There are many open source alternatives for the most popular commercial platforms. Well worth a look.</p><p>I would like to encourage you to take the step and delete WhatsApp from your phone. And if you manage to gradually convince others of the alternatives, then perhaps it will soon be completely normal in your environment.</p></div>
<h2 class="text-h2">
	<a id="support-opensource" href="#support-opensource" tabindex="-1">
		Support OpenSource	</a>
</h2>
<div class="text">
	<p>Signal Messenger is backed by a foundation set up by WhatsApp co-founder Brian Acton. The App is open source and available for free. It is financed by <u><a href="https://signal.org/donate/">donations</a></u>. If you don't want to pay with your data like on other platforms, you should perhaps consider to donate a few bucks every now and then.</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[A simple shortcut to open a page in Kirby Panel]]></title>
		<id>https://flokosiol.de/@/page/dMDVi3VqqPE9EQLZ</id>
		<updated>2025-01-24T00:00:00+01:00</updated>
		<published>2025-01-24T00:00:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/simple-shortcut-open-page-kirby-cms-panel" />
		<category term="Kirby" />
		<category term="PHP" />
		<content type="html" xml:base="https://flokosiol.de/articles/simple-shortcut-open-page-kirby-cms-panel"><![CDATA[<div class="text">
	<p>I use the Kirby CMS for my website. When editing the content, you have to switch regularly from the frontend to the panel to edit the page that has just been called up. A possible solution for this is to use the <a href="https://plugins.getkirby.com/pechente/admin-bar">Admin Bar</a> plugin. However, this was not necessary for my purposes. Since I work a lot with the keyboard, I just wanted a simple shortcut.</p><p>To achieve this, I placed a link on the page and added the <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey">accesskey</a> attribute. This allows an element to be provided with a keyboard shortcut.</p></div>

<pre class="phiki language-php github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="php"><code><span class="line" data-line="1"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">if</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">kirby</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #d2a8ff;">user</span><span class="token">(</span><span class="token">)</span><span class="token">)</span><span class="token" style="color: #ff7b72;">:</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #79c0ff;">a</span><span class="token"> </span><span class="token" style="color: #79c0ff;">href</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">&lt;?= </span><span class="token" style="color: #e6edf3;">$</span><span class="token" style="color: #e6edf3;">page</span><span class="token" style="color: #ff7b72;">-&gt;</span><span class="token" style="color: #e6edf3;">panel</span><span class="token" style="color: #a5d6ff;">()-&gt;url() ?&gt;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">target</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">_blank</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">accesskey</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">p</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token" style="color: #79c0ff;">EDIT</span><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">/</span><span class="token" style="color: #79c0ff;">a</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token" style="color: #ff7b72;">&lt;</span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #79c0ff;">php</span><span class="token"> </span><span class="token" style="color: #ff7b72;">endif</span><span class="token"> </span><span class="token" style="color: #ff7b72;">?</span><span class="token" style="color: #ff7b72;">&gt;</span><span class="token">
</span></span></code></pre><div class="text">
	<p>In this way the link is only displayed to logged-in users and can be fired with a key combination. In my case with  <code>⌃ + ⌥ + p</code>  – but this depends on the browser and operating system. MDN has an <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey">overview</a> of the differences between various browsers.</p></div>
<h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey">accesskey</a> (MDN)</li><li><a href="https://getkirby.com/docs/reference/objects/cms/page/panel">panel page method</a> (Kirby Reference)</li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Dark and light mode with light-dark()]]></title>
		<id>https://flokosiol.de/@/page/S8JWMfUPjf8BME17</id>
		<updated>2024-12-10T00:00:00+01:00</updated>
		<published>2024-12-10T00:00:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/dark-light-mode-with-css-function" />
		<category term="PHP" />
		<category term="HTML" />
		<category term="CSS" />
		<category term="JS" />
		<content type="html" xml:base="https://flokosiol.de/articles/dark-light-mode-with-css-function"><![CDATA[<div class="text">
	<p>As you know, the main purpose of your own website is to try out new things. Dark and light modes are of course not new, but so far I haven't had the pleasure of trying out the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark" title="View documentation on MDN">light-dark()</a> CSS function. I will do so now.</p></div>
<blockquote>
  To enable support for the <code>light-dark()</code> color function, the color-scheme must have a value of <code>light dark</code>, usually set on the <code>:root</code> pseudo-class.    <footer>
    <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark">https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark</a>  </footer>
  </blockquote>
<div class="text">
	<p>Alright, so let's start with some CSS …</p></div>

<pre class="phiki language-css github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="css"><code><span class="line" data-line="1"><span class="token" style="color: #79c0ff;">:</span><span class="token" style="color: #79c0ff;">root</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #79c0ff;">color-scheme</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #79c0ff;">light</span><span class="token"> </span><span class="token" style="color: #79c0ff;">dark</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">}</span><span class="token">
</span></span></code></pre><div class="text">
	<p>Instead of setting a single value for <code>color</code> or <code>background-color</code>  we can now use the <code>light-dark()</code> function and define one color for each mode. As defined in the <code>:root</code> Element, the first one is for light and the second one for dark mode. Of course you can use custom properties as well, but to keep the example more readable, let's stick to hex codes.</p></div>

<pre class="phiki language-css github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="css"><code><span class="line" data-line="1"><span class="token" style="color: #7ee787;">body</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">  </span><span class="token" style="color: #79c0ff;">background-color</span><span class="token">:</span><span class="token"> </span><span class="token">light-dark(</span><span class="token" style="color: #79c0ff;">#</span><span class="token" style="color: #79c0ff;">fff</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #79c0ff;">#</span><span class="token" style="color: #79c0ff;">000</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">  </span><span class="token" style="color: #79c0ff;">color</span><span class="token">:</span><span class="token"> </span><span class="token">light-dark(</span><span class="token" style="color: #79c0ff;">#</span><span class="token" style="color: #79c0ff;">000</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #79c0ff;">#</span><span class="token" style="color: #79c0ff;">fff</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">}</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="that-s-it" href="#that-s-it" tabindex="-1">
		That's it?!	</a>
</h2>
<div class="text">
	<p>Now we have a working light and dark mode, based on the system preferences of the user. But if we want the user to switch between modes, we have to go some extra steps.</p><p>At first we need some buttons which can be used to change the between light and dark mode. I also add one to return back to system default. Each button has a <code>js-</code> class, which we will use to identify the buttons with JavaScript. In addition we add a <a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes" target="_blank">data-attribute</a> which holds the value of the selected mode.</p></div>

<pre class="phiki language-html github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="html"><code><span class="line" data-line="1"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">button</span><span class="token"> </span><span class="token" style="color: #79c0ff;">class</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">js-color-scheme-button</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">data-color-scheme</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">light</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">Light Mode</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">button</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">button</span><span class="token"> </span><span class="token" style="color: #79c0ff;">class</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">js-color-scheme-button</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">data-color-scheme</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">dark</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">Dark Mode</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">button</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">button</span><span class="token"> </span><span class="token" style="color: #79c0ff;">class</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">js-color-scheme-button</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token"> </span><span class="token" style="color: #79c0ff;">data-color-scheme</span><span class="token">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">&gt;</span><span class="token">System Default</span><span class="token">&lt;/</span><span class="token" style="color: #7ee787;">button</span><span class="token">&gt;</span><span class="token">
</span></span></code></pre>
<pre class="phiki language-js github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="js"><code><span class="line" data-line="1"><span class="token" style="color: #e6edf3;">document</span><span class="token">.</span><span class="token" style="color: #d2a8ff;">addEventListener</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">DOMContentLoaded</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token">(</span><span class="token" style="color: #ffa657;">event</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token"> </span><span class="token" style="color: #e6edf3;">{</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="2"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> find the all the buttons based on the js- class</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="3"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #ff7b72;">const</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #79c0ff;">colorSchemeButtons</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">document</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">querySelectorAll</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">.js-color-scheme-button</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="4"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> get previously selected color scheme from localStorage</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="5"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #ff7b72;">const</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #79c0ff;">colorScheme</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">localStorage</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">getItem</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">colorScheme</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">||</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="6"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> find active button based on color scheme</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="7"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #ff7b72;">const</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #79c0ff;">activeButton</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">document</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">querySelector</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">.js-color-scheme-button[data-color-scheme=&quot;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">+</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">colorScheme</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">+</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&quot;]</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="8"><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="9"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #ff7b72;">if</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #e6edf3;">activeButton</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">{</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="10"><span class="token" style="color: #e6edf3;">    </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> add css class to active button to apply different styles via css</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="11"><span class="token" style="color: #e6edf3;">    </span><span class="token" style="color: #e6edf3;">activeButton</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #e6edf3;">classList</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">add</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">is-active</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="12"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #e6edf3;">}</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="13"><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="14"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #ff7b72;">if</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #e6edf3;">colorSchemeButtons</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">{</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="15"><span class="token" style="color: #e6edf3;">    </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> do the same thing for all buttons</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="16"><span class="token" style="color: #e6edf3;">    </span><span class="token" style="color: #e6edf3;">colorSchemeButtons</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">forEach</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #ffa657;">button</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">{</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="17"><span class="token" style="color: #e6edf3;">      </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> listen to the click event (which includes touch as well)</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="18"><span class="token" style="color: #e6edf3;">      </span><span class="token" style="color: #e6edf3;">button</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">addEventListener</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">click</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">,</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ffa657;">event</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">{</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="19"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> get the mode value from the data attribute</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="20"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #ff7b72;">const</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #79c0ff;">colorScheme</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">button</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #e6edf3;">dataset</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #e6edf3;">colorScheme</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">??</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="21"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> remove active class from every button</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="22"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #e6edf3;">colorSchemeButtons</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">forEach</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #ffa657;">btn</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #ff7b72;">=&gt;</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">{</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="23"><span class="token" style="color: #e6edf3;">          </span><span class="token" style="color: #e6edf3;">btn</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #e6edf3;">classList</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">remove</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">is-active</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="24"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #e6edf3;">}</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="25"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> and add it to the selected one</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="26"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #e6edf3;">button</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #e6edf3;">classList</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">add</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">is-active</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="27"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> add selected color scheme it to the html element</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="28"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #e6edf3;">document</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #e6edf3;">documentElement</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">setAttribute</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">data-color-scheme</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">,</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">colorScheme</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="29"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #8b949e;">//</span><span class="token" style="color: #8b949e;"> save the value to local storage to keep the selection on page reload</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="30"><span class="token" style="color: #e6edf3;">        </span><span class="token" style="color: #e6edf3;">localStorage</span><span class="token" style="color: #e6edf3;">.</span><span class="token" style="color: #d2a8ff;">setItem</span><span class="token" style="color: #e6edf3;">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">colorScheme</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #e6edf3;">,</span><span class="token" style="color: #e6edf3;"> </span><span class="token" style="color: #e6edf3;">colorScheme</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">;</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="31"><span class="token" style="color: #e6edf3;">      </span><span class="token" style="color: #e6edf3;">}</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="32"><span class="token" style="color: #e6edf3;">    </span><span class="token" style="color: #e6edf3;">}</span><span class="token" style="color: #e6edf3;">)</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="33"><span class="token" style="color: #e6edf3;">  </span><span class="token" style="color: #e6edf3;">}</span><span class="token" style="color: #e6edf3;">
</span></span><span class="line" data-line="34"><span class="token" style="color: #e6edf3;">}</span><span class="token">)</span><span class="token">
</span></span></code></pre><div class="text">
	<p>To activate the different CSS styles based on the selected color scheme, we have to apply it based on the data attribute of the <code>html</code> element, which we just changed via JavaScript. Now the browser knows which mode is set and which of the two values from the <code>light-dark()</code> method is to be used.</p></div>

<pre class="phiki language-css github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="css"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">/*</span><span class="token" style="color: #8b949e;"> force light mode, if activated by user (via JavaScript) </span><span class="token" style="color: #8b949e;">*/</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token" style="color: #7ee787;">html</span><span class="token">[</span><span class="token" style="color: #79c0ff;">data-color-scheme</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">light</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">]</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">    </span><span class="token" style="color: #79c0ff;">color-scheme</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #79c0ff;">light</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">}</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">
</span></span><span class="line" data-line="6"><span class="token" style="color: #8b949e;">/*</span><span class="token" style="color: #8b949e;"> force dark mode, if activated by user (via JavaScript) </span><span class="token" style="color: #8b949e;">*/</span><span class="token">
</span></span><span class="line" data-line="7"><span class="token" style="color: #7ee787;">html</span><span class="token">[</span><span class="token" style="color: #79c0ff;">data-color-scheme</span><span class="token" style="color: #ff7b72;">=</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token" style="color: #a5d6ff;">dark</span><span class="token" style="color: #a5d6ff;">&quot;</span><span class="token">]</span><span class="token"> </span><span class="token">{</span><span class="token">
</span></span><span class="line" data-line="8"><span class="token">    </span><span class="token" style="color: #79c0ff;">color-scheme</span><span class="token">:</span><span class="token"> </span><span class="token" style="color: #79c0ff;">dark</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="9"><span class="token">}</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="flickering-colors" href="#flickering-colors" tabindex="-1">
		Flickering colors?	</a>
</h2>
<div class="text">
	<p>If you put your Javascript at the end of your HTML document you might notice flickering colors as soon as the selected value in localStorage differs from your system color scheme. This is because the website gets loaded with your system preference and in the end the JavaScript kicks in and changes all the colors. To prevent this, you can add two additional lines of JavaScript to the <code>&lt;head&gt;</code> section of your page. This changes the data-attribute to the one saved to localStorage before the CSS is applied.</p></div>

<pre class="phiki language-html github-dark-default" style="background-color: #0d1117;color: #e6edf3;" data-language="html"><code><span class="line" data-line="1"><span class="token" style="color: #8b949e;">&lt;!--</span><span class="token" style="color: #8b949e;"> additional script for &lt;head&gt; section to prevent flickering </span><span class="token" style="color: #8b949e;">--&gt;</span><span class="token">
</span></span><span class="line" data-line="2"><span class="token">&lt;</span><span class="token" style="color: #7ee787;">script</span><span class="token">&gt;</span><span class="token">
</span></span><span class="line" data-line="3"><span class="token">  </span><span class="token" style="color: #ff7b72;">const</span><span class="token"> </span><span class="token" style="color: #79c0ff;">colorScheme</span><span class="token"> </span><span class="token" style="color: #ff7b72;">=</span><span class="token"> </span><span class="token" style="color: #e6edf3;">localStorage</span><span class="token">.</span><span class="token" style="color: #d2a8ff;">getItem</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">colorScheme</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">)</span><span class="token"> </span><span class="token" style="color: #ff7b72;">||</span><span class="token"> </span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="4"><span class="token">  </span><span class="token" style="color: #e6edf3;">document</span><span class="token">.</span><span class="token" style="color: #e6edf3;">documentElement</span><span class="token">.</span><span class="token" style="color: #d2a8ff;">setAttribute</span><span class="token">(</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token" style="color: #a5d6ff;">data-color-scheme</span><span class="token" style="color: #a5d6ff;">&#039;</span><span class="token">,</span><span class="token"> </span><span class="token" style="color: #e6edf3;">colorScheme</span><span class="token">)</span><span class="token">;</span><span class="token">
</span></span><span class="line" data-line="5"><span class="token">&lt;</span><span class="token">/</span><span class="token" style="color: #7ee787;">script</span><span class="token">&gt;</span><span class="token">
</span></span></code></pre><h2 class="text-h2">
	<a id="sources" href="#sources" tabindex="-1">
		Sources	</a>
</h2>
<div class="text">
	<ul><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark">light-dark()</a> (MDN)</li><li><a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes">data-Attributes</a> (MDN)</li></ul></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[I found a Kirby license]]></title>
		<id>https://flokosiol.de/@/page/5gfjiTdrHEXwo2MW</id>
		<updated>2024-12-03T00:00:00+01:00</updated>
		<published>2024-12-03T00:00:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/i-found-a-kirby-license" />
		<category term="CMS" />
		<category term="Kirby" />
		<content type="html" xml:base="https://flokosiol.de/articles/i-found-a-kirby-license"><![CDATA[<div class="text">
	<p>I found an unused Kirby license which I once bought for the website of my former band. I originally wanted to transform the static HTML pages to Kirby to empower my band mates to make changes on their own. Unfortunately, the Kirby website never went online because the band didn't survive COVID times – but the license did.</p></div>
<h2 class="text-h2">
	<a id="let-s-make-use-of-it" href="#let-s-make-use-of-it" tabindex="-1">
		Let's make use of it!	</a>
</h2>
<div class="text">
	<p>My personal website was a static one, too. It was handcrafted which (you might guess correctly) does not really scale. After dedicating the year 2024 to music, the new year is coming really quickly. So it might be good idea to invest some time into my personal website and turn it into a Kirby driven one.</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Music 2024]]></title>
		<id>https://flokosiol.de/@/page/czbDE1oIqc18Apvg</id>
		<updated>2024-01-01T00:00:00+01:00</updated>
		<published>2024-01-01T00:00:00+01:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/music-2024" />
		<category term="Music" />
		<content type="html" xml:base="https://flokosiol.de/articles/music-2024"><![CDATA[<div class="text">
	<p>In 2024, I would like to spend more time with music in a variety of ways.</p></div>
<h2 class="text-h2">
	<a id="listening" href="#listening" tabindex="-1">
		Listening	</a>
</h2>
<div class="text">
	<p>I love to listen to music. But lately I found myself listening to the same tunes over and over again. I want to breakt with this habit! My goals are …</p></div>
<div class="text">
	<ul><li>to explore <strong>new bands</strong> → <a href="https://mastodon.social/@flokosiol/111630320732052001">recommendations</a> are much appreciated</li><li>dive into <strong>new genres</strong> I usually don't listen to</li><li>to take more time to listen actively (whole albums)</li></ul></div>
<h2 class="text-h2">
	<a id="learning" href="#learning" tabindex="-1">
		Learning	</a>
</h2>
<div class="text">
	<p>My main instrument is the electric bass. I even have a Bachelor's degree in jazz/popular music. And during my studies at university, transcribing songs was a very important exercise. It trains you to listen actively. If you have heard for yourself which notes an instrument plays in a song, you can remember it much better afterwards than if you play it from existing sheet music. And yes, there havn't been free available tabs or notes on the internet back then. So no chance to cheat!</p><p>I want to listen and learn again.</p></div>
<h2 class="text-h2">
	<a id="making" href="#making" tabindex="-1">
		Making	</a>
</h2>
<div class="text">
	<p>A while ago I had a closer look at GarageBand which ships with Mac OS. It's amazing what you can do with this free software. I already started to create music and to produce my own tracks. I want to do more stuff like this and maybe even publish it one day … maybe! We'll see.</p><p>The <a href="/@/page/EZLTRRTlOzMYpfHl">New Years Jam</a> is a little example. Maybe more to come.</p></div>
]]></content>
	</entry>
	<entry>
		<title type="html"><![CDATA[Finally back on #Klassenfahrt]]></title>
		<id>https://flokosiol.de/@/page/VYh22dlbpwqTHZTo</id>
		<updated>2023-04-19T20:32:00+02:00</updated>
		<published>2023-04-19T20:32:00+02:00</published>
		<link rel="alternate" type="text/html" href="https://flokosiol.de/articles/finally-back-on-klassenfahrt" />
		<category term="Inspiration" />
		<category term="Event" />
		<content type="html" xml:base="https://flokosiol.de/articles/finally-back-on-klassenfahrt"><![CDATA[<div class="text">
	<p>After a way too long break, I finally had the opportunity to attend the <a href="https://beyondtellerrand.com/events/dusseldorf-2023">beyond tellerrand</a> conference in Düsseldorf again. The less successful predecessors "event canceled because of COVID" (2020) and "bad feeling because COVID still too widespread" (2021) and "ticket bought, but on time COVID in da house" (2022) had made the anticipation this year skyrocket. So after 2015 to 2019 and the live stream replacement 2022 finally again two days packed with ... well with ... quite a lot ...</p></div>
<h2 class="text-h2">
	<a id="inspiration" href="#inspiration" tabindex="-1">
		Inspiration	</a>
</h2>
<div class="text">
	<p>Of course, it's not just the speakers who provide permanent inspiration on the two days, but they undoubtedly play a significant role. It doesn't matter to me whether the talk has more of an artistic or a technical focus. In general, it's the way they dedicate themselves to a cause, how much passion and time they invest and with what enthusiasm they report on it. It's all incredibly inspiring! For me, it ranges from <a href="https://beyondtellerrand.com/events/dusseldorf-2023/speakers/gemma-o-brien" title="speaker page of Gemma O’Brien at beyond tellerrand in Düsseldorf in 2023">fascination</a> to <a href="https://beyondtellerrand.com/events/dusseldorf-2023/speakers/thomas-thwaites" title="speaker page of Thomas Thwaites at beyond tellerrand in Düsseldorf in 2023">disbelief</a>. Yes, exactly, for example the one with the goat!</p></div>
<h2 class="text-h2">
	<a id="personality" href="#personality" tabindex="-1">
		Personality	</a>
</h2>
<div class="text">
	<p>The fact that beyond tellerrand is a very personal conference is primarily due to <a href="https://marcthiele.com/about" title="personal website of Marc Thile">Marc</a>, the organizer. With his attention to detail and his welcoming and open manner, he creates the perfect setting to feel comfortable on site. Through permanent - but not at all intrusive - hints he motivates the participants to reach out others (“Who already met someone new during the break?”) and also to be open and inviting for others in existing groups, for example by making sure to leave an open space in discussion groups. It's amazing how attentive the community is in this regard and this is quickly becoming a lived practice among everyone.</p><p>All this makes it easier to get in touch with the many interesting people in the field and to exchange ideas, but this does not diminish the amount of inspiration :) In the past years I have made many contacts in this way, some of them very personal. So it's no wonder that a feeling of #Klassenfahrt arises when all the follks make their way to Düsseldorf every year. But not enough, new people are added to the mix who were previously only known via the web or not at all.</p><p>In addition, there are talks, some of which have a very <a href="https://beyondtellerrand.com/events/dusseldorf-2023/speakers/aoi-yamaguchi" title="speaker page of Aoi Yamaguchi at beyond tellerrand in Düsseldorf in 2023">personal topic</a>, are presented with a lot of <a href="https://beyondtellerrand.com/events/dusseldorf-2023/speakers/hugh-elliott" title="speaker page of Hugh Elliott at beyond tellerrand in Düsseldorf in 2023">insights</a> or even <a href="https://beyondtellerrand.com/events/dusseldorf-2023/speakers/emily-anhalt" title="speaker page of Emily Anhalt at beyond tellerrand in Düsseldorf in 2023">involve you directly</a>.</p></div>
<h2 class="text-h2">
	<a id="motivation" href="#motivation" tabindex="-1">
		Motivation	</a>
</h2>
<div class="text">
	<p>The trick is now to retain the many impulses over a longer period of time and not to fall back into the usual daily routine too quickly. There is definitely enough motivation after the conference ... and after all, every day is a day to think outside the box and to take a look beyond your tellerrand!</p><p>I am looking forward to next year!</p></div>
<div class="text">
	<p>“Klassenfahrt” is the german word for “class trip” and a frequently used hastag on social media to emphesize the personal and friendly atmosphere at beyond tellerrand and the joy of meeting each other once a year.</p></div>
<figure data-ratio="auto">
    <img src="https://flokosiol.de/media/pages/articles/finally-back-on-klassenfahrt/e54a906bfb-1740084870/welcome-back.jpg" alt="A stage in an empty thater with a big screen showing the words “welcome back“.">
  
  </figure>
]]></content>
	</entry>
</feed>
