Log in
Welkom op Seblog, het weblog van Sebastiaan Andeweg. Ik ben een schrijver en nerd uit Nijmegen. Ik ben ook te vinden op Twitter, Instagram en nu en dan op LinkedIn. Als ik code schrijf staat dat op Github en als ik rondjes ren staat dat op Strava. Ik zit stiekem ook weer op Facebook na 2,5 jaar weg te zijn geweest.

#100daysofindieweb

Day 45: receiving reacji

A little while ago I added reacji to my site. Since reacji are just comments who's content contains only one emoji, I did support reacji before the change. I only changed the way I displayed them, when I send them.

One thing I noticed after my return to Facebook, is that the like-button now has several nuances. These love, haha, wow, sad, angry-things are sent by Brid.gy as emoji. Because of this, it didn't took long for me to receive my first reacji via webmention. They just showed up as comments with one emoji.

So today I fixed that:

Note that I already used a heart icon for likes. I want to keep it that way, the emoji looks different enough to distinguish them. If you comment on Facebook with a heart, they display it as a comment with a heart, and I will just show it as a like, like above. But I'm fine with that. You can also reply with other emoji if you like.

Oh, and I fixed the images now too.

Day 44: hooking up Brid.gy

Yesterday I re-activated my Facebook, for the first time since 2.5 years. Still not really sure about this silo-return, but I want to try it again. Facebook is a powerful tool, and with the other tools IndieWeb gave me, I think I can manage my relation to it better than I could 2.5 years ago.

At first sight, it might look as if IndieWeb is about stopping silo's. In that light, a return looks strange. But there is no IndieWeb principle that says you should quit Facebook or Twitter. As long as I POSSE, I own my data, and I can still connect to my silofriends.

I still want to minimise the actual time spent I on their site. So today I made the first few bridges that should make that happen: I hooked up by site to brid.gy/publish and the 'normal' Brid.gy backfeed for Facebook. Now I can post via Micropub to my site and automatically post to Facebook too. Any comments and likes received on the post on Facebook will return to my site as well.

Now I have to make some interesting content to test all this with.

Day 43: The silent return

Okay, I am going something I didn’t expect doing for a long time. I am still uncertain about it, but my curiosity and my love for round numbers won today.

Today exactly 2.5 years ago, I disabled my Facebook account. I did quit for various reasons, varying from ‘omg my privacy’ to ‘I spent too much time on here’ and ‘they have too much control over my newsfeed’ and ‘they will disappear soon anyway’. I still read articles from people struggling with those issues, except for the last one: Facebook still didn’t disappear. (What was I thinking?)

In the past 2.5 years, I had varying levels of FOMO. Most days where fine, especially later on when I got detached enough. But some days, after nights with friends, citing things that happened elsewhere & on Facebook, I felt I missed a lot. The sad thing is that there’s no way to know for sure.

So my FOMO changed from ‘I am missing stuff’ to ‘Am I missing stuff?’ I am not sure, but I probably am. How bad is that?


Quitting Facebook is about taking responsibility for your social life again. You need to track birthdays yourself, you need to actively reach out to people to meet them, you need to discover events for yourself.

I’m not saying I’ve accomplished to do those things myself over the past 2.5 years, but I’m also not saying that I will let Facebook fully handle them again. I’m not even sure Facebook still fills those needs these days. 2.5 years is a long time on the internet. But I am genuinely curious what Facebook does nowadays. (I’ve heard a lot about fake news and filterbubbles. Sounds cool.)

There is another part to returning that I’m not sure about. To get all the ‘benefits’ of being socially connected via Facebook, you have to spend a lot of time on the platform. I actually don’t really want to put in that much work. I know, I will be addicted to the likes and pokes within days, and I won’t notice all the time that goes in. But that was not how I intend to use Facebook over the comming month.

Ideally, I want Facebook to be a box. Or a hole, a well maybe. I want to throw in stuff, and I want to get stuff out, but I don’t want to be in the box/hole/well myself all day. I want to check once a day what happened, via an interface that doesn’t want to drag me in. (I can make one myself, I think.) And I want to post stuff on there like I post things to Twitter now: I just write it on my blog and then click on ‘also to Facebook’. I don’t want to login there to post something and get distracked.

And this is the last dilemma. Facebook gives an external boost to your ego. I could use that sometimes (we all do, right?) but it’s not the healthiest thing. Is it the demanding interface and the addictive notifications that are bad, or is the service itself the harmful thing? Should I want to share my thoughts with other people, or do I need to learn to be content with them myself?

Either way, I’m not back at Facebook in the sense that I’m completely hooked again like I was when I left. Being gone for 2.5 years makes that the interface is completely different. (I have seen it at other peoples computers, of course, so I’m not completely unfamiliar, but I have no personal bond with this layout.) Let’s hope I can contain this beast. And if not, I will simply leave again, because I know the world won’t end if I do.


And now for the action: I’m going to log in, see that it’s enabled again, and leave it like that. The silent return.

Day 42: multi-photo

Yesterday, I went to Den Helder for a day. Besides doing some work, we also made a walk through the dunes. Such walks produce pictures, somehow, and I wanted to post some of them here.

Since I didn't want to create multiple posts, it made sense to create a list of photo's in one post. Instagram also launched a new post type with multiple photo's, and this seemed to be a good match for it.

So yesterday I made a quick foreach loop to be able to post them and today I styled it some more with CSS. It's not as pretty as the Instagram presentation of a multi-photo post, but I didn't want a carrousel like they use. The pro is that the images are viewed one by one, not influencing each other that much, but the con is that it's hard to signal to the user that there are more then one picture behind the post. I like the list as it is now. It's kind of long, but it works.

Day 41: IndieAuth in the toolkit

Today, I moved some existing code from my kirby-micropub plugin to my indieweb-toolkit, and then I rewrote it a bit. It is the code that checks for an Authorization: Bearer xxx header and rejects people that have the wrong token.

At this point, my blog just uses tokens.indieauth.com, as it's token endpoint. So, that is what the toolkit uses now too. This is not ideal, and I plan on adding a token endpoint directly to the toolkit. But, everything in steps!

You can now do the following:

indieauth::requireMe();
indieauth::requireScope('create');

// do stuff!

And then the script will exit if there's no Authorization: Bearer in the header with the proper scope and a 'me' value corresponding with the current URL. (You can also pass in a 'me' to check against.) I am still not sure about some things, so I am putting them out here to think about them some more. Feel free to comment.

  • Is 'IndieAuth' the right name for this static class? I think so, because it uses 'me' and 'scope'. But at this point, it's only checking tokens. And when I add a token endpoint, is that token endpoint still IndieAuth?

  • In my code, I now check url::host($token->me) == url::host($requiredMe)). I only compare hosts, so seblog.nl, which works, because seblog.nl/micropub still has the host seblog.nl. Maybe I should drop this 'use the current URL if the $requiredMe is empty' and only go for explicit 'me'-values.

  • Previously, I threw Errors. Now, I just set the HTTP-header and exit the script. I wonder which way is more elegant. The way I do it now, makes sure the right HTTP status is sent, but the way I did it before allows for more customisation. Both ways exit the script, which is the most important part.

P.S.: to make my 100days more sustainable, I decided to take weekends. The good thing is: today is Day 40, so I'm all lined up for a 5-day-week. See you on Monday again!

Day 40: reverting repost changes

I changed my mind about reposts, again. This is what we call voortschrijdend inzicht in Dutch.

A few days ago, I changed how I display reposts. In an attempt to honor copyright, I only display the first 50 words of a repost. This way, it's more a quote than a full copy of the content, but I can still retweet stuff, since cramming 50 words into 140 characters is doable, but rare.

What's more: I only showed the repost in the feed, not on my permalinked pages. I redirected those permalinks to the original permalink. This way, while I had the original content imported on my site, I wasn't actually re-publishing much of it.


But today I reposted a much reposted post of Aaron, and then it stuck me: I can't send a webmention, in the 'oh look a comment' kind of way, if I don't have a permalinked page with Microformats on it.

In a way, a 302 redirect has the URL of another page on it by using a HTTP Location header, so it does link back to the original page. The question is then: is that a valid link for sending a webmention? And: does a 302 redirect on the source URL to the target URL imply a repost of the target? Not really, I think. It's just a redirect.

So I got rid of the redirect of my permalinks, giving my reposts their page back. I still only display the first 50 words of a repost, making it more a quote than a repost. But aren't reposts just full quotes? It's still the major part of the content of the post. I will keep it that way for now.


Edit 20:17 CET After some discussion on IRC, I decided to also ditch the 50-word-cutoff. Only showing the first 50 words of a repost makes it a quotation, not a repost.

The need for the 50-word-cutoff was born because I felt uneasy reposting a whole article. The solution to that is: don't repost a whole article. The problem was that I already reposted a whole article, because at that time, I found it important to keep it online, in case the original server would collapse under a lot of trafic. The next day, that wasn't a reason to keep it on my site anymore.

So, I changed that single post to a bookmark (replacing only repost-of to bookmark-of in the .txt of my post) and now I'm good again. I removed the code that showed only the first 50 words. If I ever want to quote something, I can use quotation-of, but for now, I'm fine.

Day 39: inquiring about Micropub

I really should get back into #100daysofindieweb again.

Recently I got into writing again, and with writing comes the endless quest for writing apps. My all time favorite is iA Writer, because I use that one since at least 2011 on and off. Another favorite, but newer, is Ulysses. Ulysses is a combination of iA Writers simplicity and Scriveners multi-functionality. (I don't really like Scrivener, however, it's way to much of everything.)

Both iA Writer and Ulysses offer Wordpress and Medium integration from within the app. The sad thing is: I'm not on Wordpress nor Medium.com, so I can't use that feature. I do however support Micropub, which is open and stuff. It would be nice if they did support that.

So today, I wrote both of them an e-mail, asking to add support for Micropub.

I think this barely qualifies for a real Day within the 100days, because I didn't really made stuff, I just talked about things. But I really need to get back at the quest and it's late already. And it would be nice if one of them (or both!) added support for Micropub through this action.

Day 38: multi-like

Yesterday, I was at the presentation of Pim Lammers' Het lammetje dat een varkentje is (‘The little lamb who is a pig’), a childrens book about transgender. I follow Pim on Instagram and today he posted three photo's of yesterday. I saw a few names of friends who already liked all three of the photo's, and I was tempted to do the same.

But, since I'm committed to post my likes on Seblog first, that would require me to make three new posts on my blog. That's a bit much. So I decided that all three likes where going to be one post here. I posted them as a comma separated list of URLs, and my blog made the following post out of it:

I have to admit I didn't write any new code for today. This is just the way I made my like-posts work from the start. I just never found a proper use for it until now. Let's see what I break with this post.

I also POSSEd the likes to Instagram, of course :)

Day 37: color tweaks

Minor thing, but... I feel lighter these days, so I wanted my site to reflect that. I always thought of #eee as the lightest of grays, because there is only #fff (white) as the next step. The six-digit notation was too granular for me. But it turns out that, for a background color, #f6f6f6 actually gives a whole different feeling. It's so much clearer!


Another thing you might have noticed, it that I broke the streak of consecutive #100daysofindieweb. This has to do with the lightness, I guess. I came home after a nice evening of talking about writing, and I just didn't want to get into the coding state of mind again. So I decided to leave it that night.

The returning problem with 100daysofindieweb, for me, is that I haven't figured out all the things I want from it yet. In the last entry, for example, I used Aaronpk's emoji library to display reacji in a certain way. While this is a nice thingy, there is an underlying question that I did not ask myself: do I need this?

For me, it was a recurring theme, remembering to do something IndieWeb around 0:30 at night, and just inventing 'problems' to solve, preferably small problems with quick solutions. I implemented a lot of stuff I think is useful, but also a lot of things just because other people did it before me.

A few days ago, I noticed that Whatsapp added the 'photo stories' feature, invented by Snapchat and copied by Instagram. My first reaction was: hm, how can I do this on my own site? While that is a nice question to ask oneself, it is useful to also ask the question wether you actually need to have such a thing on your site. Photo stories are hard to copy, because you can only add a new photo to them if you take that photo directly from the app. Also, the discoverability and way of viewing them is 80% of the feature. Their temporary nature also makes them less suited for the web. All in all, I shouldn't rush into this, and post photo's that disappear after 24 hours, just because I have a day to fill.

I will continue the 100 days. I will just sometimes take some time in between days, to think about the route I want to follow. To ask myself the question: do I need this? Minor tweaks make big changes over time, and it's okay to redo some stuff you did before. That's the way your understanding grows. But no more big new things for me now. I more or less have what I need, I just need to improve some things.

Day 36: reacji

A few days ago, Aaron Parecki made an emoji detector for PHP. I felt I had to reply to that in style by using it.

So, now my site supports reacji, a reply which contains only of one emoji. In theory, it did already support this, of course, but now I show them as a 'shortpost', next to likes and other things I use icons for:

Hurray for Aaron's detector 🎉

Day 35: in reply to author name

Today, I replied to some people on Twitter, and I was surprised to see 'twitter.com' turn up on my site as the author of the post I was replying to. I now have XRay with Twitter vision, right? Why didn't it work?

It turned out I only use XRay for likes, bookmarks and reposts, but this reply context relied on an old piece of code I wrote myself. It fetches a h-card for the URL, which works for IndieWeb sites with Microformats, but not for Twitter posts.

So I fixed that: now XRay fetches context for replies too:

This is the first step in actually displaying the full reply context on the permalink page. The data is there now!

Day 34: added a privacy policy

Today is a (almost) no code day. I wrote a privacy policy.

Now that I have ways to log in to my site, I kind of need a page, because I am handling with personal information. I believe it's even required for the Twitter login thing, so here it is.

It feels more formal than I want it to be, so I tried to keep it informal. I also translated the Dutch version into English, because I have embarked on this multilingual thing now with this 100days series and English visitors need a privacy policy too. The document just comes down to explaining what I do, and asking to contact me if one disagrees. I don't do crazy stuff, so I think it's fine.

The bit of 'code' I wrote is in the footer, where there's now a link to the privacy policy.

Day 33: timezones

At some point while building the foundation for this site, I decided to save all dates in UTC. I like UTC, I like timezones in general, and here in Europe we're not that much off UTC either.

In about a month from now, though, the gab between UTC and CET will grow again with one hour, due to 'zomertijd'. And even though there was an explicit 'UTC' behind all the times, it was still confusing for Dutch visitors, who where expecting 'normal' times.

I now show times in Central European Time. There's an explicit 'CET' behind all the times. The Microformats times are still on UTC though, but I added an explicit +0000 behind all the timestamps, to make clear that it's UTC.

Day 32: new repost policy

One of the things I keep changing my mind about, is reposts. They are totally normal on Twitter, but seem to be totally weird on your own site. When signing up for Twitter, you give permission to Twitter to let other people retweet your tweets. When signing up for IndieWeb, yeah, non of that exists.

Still, I reposted a post by Loran Kloeze two weeks ago. It was marked up with h-entry, so all I had to do was just feed my Micropub endpoint the URL, and my site automatically fetched the post for me. At that time, I thought it was good to do so, because the post was important and chances were Lorans server would not have handled it if it went viral. I mirrored it, so others would be able to mirror it. Sounds good, right?

I still did not ask permission for the repost to Loran. (And I doubt he knows about it... maybe he gets a Google Alert after a while? He does not support webmention.) Yet the whole post was available at my site. What about those copyrights? He has removed his Google Ads now, but at that time they where there, and I was potentially keeping visitors away by giving them an ad-free environment to read the post.

So, today I changed some things about how I repost. I only show the first 50 words in the stream, like this:

There is a link to read more at the original URL. Tweets are, with 140 chars, mostly kept as is. I am just quoting, but the whole post is so short that I display all of it. The longer posts are cut off, to encourage people to read it at the source. If the permalink expires at some point, I can always decide to show the whole post again. Or maybe I should delete the repost then? That depends on the post.

When visiting a permalink of a repost on my site, you will get redirected to the original post. This way, reposts only appear on my stream, and I don't host their content under a URL on my site.

Day 31: randomising Lees (and introducing it here)

Okay, I did not implement receiving private webmentions today. Reason for that is that I also need to do some other things in life, but on top of that: I don't like the way I am storing webmentions right now. I feel like I have to solve some other things about that, before I can actually implement receiving private webmentions. I could just go for it, but then I am just adding more on top of this thing I don't like, which makes it harder to change, etc. I will make receiving private mentions a gradual thing, spread out over more days.

I still need to do something today, but it was hard to come up with anything, for everything seems to big for the time of the evening. So I decided on something minor: I now randomise the post that are visible in the 'Read' view of Lees. Wait, let me first introduce you to that.


Lees, the Dutch word for 'read', is my IndieWeb reader. It is all quite experimental and unstable, so I don't recommend using it, although the code is open. (Do I have a good license there? No. I need to look into that.)

Lees just polls different websites via a cron job and pulls Microformats from the posts. It presents those posts in a 'new' feed, 10 at a time, oldest first, so you don't miss a thing. Then there is a button that says 'mark all as read', which marks all the posts in the current view as read. This is great for reading tweets in bulk.

Some posts need more time, though, so there is a 'read later' checkbox. Checking it will, after you click 'mark all as read', not mark the post as read, but send it to 'read later'. This way you are just glancing at the 'new' feed, and picking the things you really want to read.

As you can see above, you can also like, reply and bookmark directly from Lees. Well, reply is actually just a link to Quill, but it's still works. There is build-in Micropub support for the on-click-post ones.


My problem is that Lees does not yet filter stuff. I follow too much people on Twitter, so now I actually removed Twitter from Lees and check the Twitter-app again. I also have a list of articles I would like to read in my 'Read' stream, but I see only the same ones over and over again, the oldest 10. Every time I see them, I think 'yeah, I should read those', and that guild does not really convince me to do so.

So in an attempt to get myself back to Lees, I randomised the posts in the Read section. Their order is now shuffled, so I see 'new' ones when I login. Those are all posts I handpicked for looking interesting. I hope I am now more motivated to actually click some of them, as I rediscover them. Also: if I now keep seeing a particular article that I don't read... I can remove it with more confidence.

So there it is, day 31. Writing this blogpost took longer than the thing, but I'm happy with the result, that's what counts!

Day 30: private webmentions (special valentines edition)

Now that I support both private posts and webmention, it is time to put those two together and send private webmentions. In short, this is a way to notify URLs you mention in your posts, while still maintaining the privacy of the post.

Following the description on Indieweb.org, my private posts now send a HTTP Link header to my new token endpoint. When I send a private mention, I also send a code: a JWT token with the target and source URLs of the webmention and an expiration of 2 minutes. The other side can discover my token endpoint by looking at the Link header, and send the code in a POST request.

The code is then exchanged for an access token, but now with a me, which is set to the URL of the mentioned post, a page, which is my page, and a nonce to mess things up a little. This access token expires in an hour, which is plenty for automated fetching, but might be a bit short for people verifying manual. Normal people can still try and login via IndieAuth though!

However, the mentioned URLs and the whitelisted people are different fields, so they can be different. In fact, they should different: if I mention someone.com/a-post, I might to give someone.com access to the post by logging in, but only if the owner of someone.com/a-post is actually someone.com. In case of twitter.com/url-to-tweet, I don’t want to give twitter.com access. I’m not sure how to solve this yet, so I will do it manual until it hurts.

Also note that I only implemented sending private webmentions today. Please don’t private-mention me now. I will do that part tomorrow.


Now for the Special Valentines Edition™: I just created a post with a u-like-of pointing to a personal site / profile of someone I like. The post is of course private and only I and that person can see it when we log in. I have sent a private webmention for it. The only sad thing is that the other side did not support private webmention and nothing got sent, so I guess it does not really count as my first private mention. Tragic Valentines Day for me so far.

Day 29: responsible disclosures

Yesterday, I found a weakness in Quill, so I notified Aaron and he fixed it today. (Actually, I discovered it today at 1:30, and he fixed it yesterday at 20:30. Timezones are magic!)

On Day 15 of my 100days, I found a vulnerability on my own site. I promised to blog about it, but I actually waited, to give Bastian Allgeier the opportunity to fix his site too. Then I just postponed the writing some more, because life happens. I finally wrote about it today.

This brings my count of responsible disclosures to 2, and I’m a bit proud of that.

Day 28: Twitter login

Taking yesterdays private post adventure one step further: it’s now also possible to log in to Seblog with Twitter. I still recommend having your own site and use IndieAuth, but I have to be pragmatic: a lot of my friends do not have their own site. (If you want your own site, like this, just give a shout, I can help.)

To make this login adventure a bit more visible, I also added a ‘Log in’ link in the top right corner of every page.

Unfortunately, there is not much going on for people who logged in via Twitter. The private post of yesterday is still only visible for those who were on IRC-people yesterday. But it’s a step!

Day 27: private posts

A few months ago I wrote that I made 'privéstukjes' on my site. The implementation was as simple as one field called 'private' that I would give a value (true for example). If the field has a value, my site returns a 401 Unauthorized header and a page explaining that there is nothing to find there. I did not implement a way to log in, for I only used it for (two) drafts / pieces of bad writing I wanted to keep for myself.

But what is the fun of a private post when nobody can see it?

Today, I implemented a login for my private posts. It was a bit more work than I thought, getting IndieAuth to work and thinking out all the different states of a post, but I made it.

Posts can now also have an 'audience' field, where I keep a comma separated list of URLs that have access to the post. I plan on expanding or replacing that with predefined lists (friends, family, etc.), but for now this works fine.

If one is not logged in, the private post page returns a 401 with a (Dutch) explanation of what is going on. There is also a field to put in your personal URL for an IndieAuth login. If you login, but are not on whitelisted to view the post, you will get a 403 Forbidden, and a Dutch explanation. (Translating my site based on visitor language is still a to do.) If you are on the list, you will see the post.

I have made a test post, so you can try out for yourself. All URLs on IndieWeb's IRC-people page, at the time of writing this, are whitelisted. Have a try at it if you're on that list!

Meer laden