2nd page of the posts archive.

It might be pompous for the level I'm keeping and running things here; nonetheless, you can search the content now.

Pagefind made the implementation a no-brainer. I didn't customize the defaults, and there are still some loose ends and details to polish.

Pagefind is a fully static search library that aims to perform well on large sites, while using as little of your users’ bandwidth as possible, and without hosting any infrastructure.

If you are playing with the idea of creating a distributed social network or service, there are standards that you have to be aware of.

One of them is the WebFinger protocol.

Let's look at an example of "a decentralised, minimalist microblogging service for hackers" that does not use the WebFinger protocol.

If you want to follow someone with twtxt, you do:

twtxt follow bob http://bobsplace.xyz/twtxt

But Alice, because twtxt is configurable, can choose to expose their posts somewhere other than twtxt.

So when you want to follow Alice, you'll type:

twtxt follow alice http://alice.space/updates.txt

The question: how do you know each individual's twtxt URL if there's no standard, only a sensible default?

You have to find out. But how? The answer is: depends. You can try the default, make an educated guess, you can ask Alice, or Alice can share the link on their website.

This is where WebFinger comes into a play.

WebFinger (...) can be used to discover information about people or other entities on the Internet using standard HTTP methods.

For a person, the type of information that might be discoverable via WebFinger includes a personal profile address, identity service, telephone number, or preferred avatar.

Information returned via WebFinger might be for direct human consumption (e.g., looking up someone's phone number), or it might be used by systems to help carry out some operation (...)

To translate this into practice, if twtxt had implemented WebFinger, the following part would look like this:

twtxt follow bob@bobsplace.xyz
twtxt follow alice@alice.space

There would be no need to know the exact location of the twtxt files.

By the way, even though they look like email addresses, they are not. In the same way, those things that look like email addresses on Mastodon (account usernames) are not. Yes, indeed! Mastodon uses WebFinger.

With WebFinger, you can have a standardized protocol to discover the URLs "for you". Since URLs are retrieved instead of directly used, they can be changed without worry since they can be "rediscovered" anytime.

But as twtxt proves, it's not a requirement. While somebody misses it, the project had its fair share of success without it.

Nevertheless, IMHO, if you are playing with the idea of creating a distributed social network or service, use WebFinger.

Can you name all PSR proposals by their number? Or at least the accepted ones? I bet this was a game at a **** *** party.

PSR-12? That's the "Extended Coding Style Guide". Easy.

PSR-13? Uhgfg. What about PSR-20? The one that was accepted today.

I know people outside the tech industry who know where the (software) bug term comes from; it's one of those fun facts that can entertain or bore a group.

The etymology of the boilerplate code is as entertaining, probably less known, and a bit nerdier.

You might know the conventional commits specification. It's "a lightweight convention on top of commit messages".

For example, you start the commit message with fix: and that signals you are fixing something and not introducing a new feature. feat: is reserved for new features, and so on.

But did you hear about conventinal comments?

Conventional Comments is a standard for formatting comments of any kind of review/feedback process, such as code reviews.

Reviewing and providing feedback is something I've been doing a lot lately. And ever since, I've been thinking about how to phrase my comments better and overcome language and knowledge level differences.

I'll give this a try.

During this current wave of migration from Twitter, ActivityPub is a term mentioned a lot. From the Wikipedia entry:

ActivityPub is an open, decentralized social networking protocol. It provides a client/server API for creating, updating, and deleting content, as well as a federated server-to-server API for delivering notifications and content.

The whole point of ActivityPub is to allow interoperability and basic compatibility between different platforms (in the fediverse).

It's still hard to imagine, but there's a great demonstration of the "connection" between two very different services which support ActivityPub.

WriteFreely looks and does things nothing like Mastodon, on the surface, but yet, ... just check the video.

Imagine somebody force pushed to a branch. That person is unreachable now, and some critical code is gone. You never had that repo cloned or branch checked out. Can you do something?

It turns out, yes. At least if you are using GitHub (GH).

With the GH API, there are things you can do that are not otherwise available in the web UI.

For example, you can get a list of all things that happened to a repo using the list repository events endpoint.

curl \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer <YOUR-TOKEN>" \
https://api.github.com/repos/OWNER/REPO/events

This includes all kinds of activities, like somebody leaving a comment on a PR, somebody starring the repo, or somebody pushing a commit.

[
{
"id": "22237752260",
"type": "WatchEvent",
"actor": {},
"repo": {},
"payload": {
"action": "started"
},
"public": true,
"created_at": "2022-06-08T23:29:25Z"
},
{
"id": "22249084964",
"type": "PushEvent",
"actor": {},
"repo": {},
"payload": {
"push_id": 10115855396,
"size": 1,
"distinct_size": 1,
"ref": "refs/heads/master",
"head": "7a8f3ac80e2ad2f6842cb86f576d4bfe2c03e300",
"before": "883efe034920928c47fe18598c01249d1a9fdabd",
"commits": [
{
"sha": "7a8f3ac80e2ad2f6842cb86f576d4bfe2c03e300",
"author": {},
"message": "commit",
"distinct": true,
"url": "https://api.github.com/repos/octocat/Hello-World/commits/7a8f3ac80e2ad2f6842cb86f576d4bfe2c03e300"
}
]
},
"public": true,
"created_at": "2022-06-09T12:47:28Z"
}
]

The PushEvent includes the before, which is the "The SHA of the most recent commit on ref before the push". To put it otherwise, the "state that we want to recover".

Now we can take advantage of the create a reference endpoint. This would allow us to create a new branch with the state right before the force push. The SHA identifies the state. This is what we pass to the endpoint, together with the branch name we want.

curl \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer <YOUR-TOKEN>" \
https://api.github.com/repos/OWNER/REPO/git/refs \
-d '{"ref":"refs/heads/featureA","sha":"aa218f56b14c9653891f9e74264a383fa43fefbd"}'

This is it. "We saved the world."


I found the solution on Stack Overflow. This is just a more narrative explanation with updated links to the API.

I already mentioned here a monochrome emoji set.

Here's another type of emoji set that I like: a pixelated-looking for/from SerenityOS.

In fact, I like the whole idea of SerenityOS:

SerenityOS is a love letter to '90s user interfaces with a custom Unix-like core. It flatters with sincerity by stealing beautiful ideas from various other systems. Roughly speaking, the goal is a marriage between the aesthetic of late-1990s productivity software and the power-user accessibility of late-2000s *nix.

We need more of the 90s, or even 80s!, aesthetics. It's a growing sentiment that I share with UI, and UX experts, who see the limitation of today's trends.

We validate data all the time. In programming, as in all areas of life, what we get is not always what we expect.

Let's take one specific case where we use validation: when constructing objects.

Painter::fromArray([
// ...
]);

PHP already offers functions to assert things, but many use dedicated libraries like Webmozart Assert or Respect\Validation. Me too! They are more convenient to use, and they are more powerful.

But if you are working with WordPress, there is a "WordPress-specific" solution that sits somewhere between the "native PHP" and libraries regarding convenience and power.

It's the rest_validate_object_value_from_schema function. It's something worth considering before requiring an extra dependency.

The function's name gives the impression that it is "REST API specific", but that's not the case.

Imagine that, for some reason, the Painter, besides the name, needs the favorite color in HEX format and possibly the name of the favorite artists.

Painter::fromArray([
'firstName' => 'John',
'lastName' => 'Doe',
'favoriteColor' => '#000',
'favoriteArtists' => ['Picasso', 'Salvador Dalí']
]);

How would you write the validation in "plain PHP"?

Here's how it might look using the rest_validate_object_value_from_schema:

class Painter
{
public static function fromArray(array $data): self
{
$validationResult = rest_validate_object_value_from_schema(
$data,
[
'properties' => [
'firstName' => [
'type' => 'string',
'required' => true,
],
'lastName' => [
'type' => 'string',
'required' => true,
],
'favoriteColor' => [
'type' => 'string',
'format' => 'hex-color',
'required' => true,
],
'favoriteArtists' => [
'type' => 'array',
'items' => [
'type' => 'string'
]
]
],
],
''
);
 
if (is_wp_error($validationResult)) {
throw new InvalidArgumentException(
// ...
);
}
 
return new self(
// ...
);
}
}

It's pretty readable and understandable at first sight.

If you want to keep the validation code inside the factory method or move it to a dedicated method or a class, that's up to you. Lately, I prefer having dedicated validation/assertion classes.

You can refer to the REST API Schema page to check the validation rules you can use.

See more on the 3rd page