Sander van Dragt's Notes

Sander @ October 18 at 9:08 am

Lamb 0.5.0

Originally written on lamb-releases:

New in this release:

Crossposting from feeds. Support for user themes. A new retro 2024 theme.

I've been able to move the project closer to my vision for a frictionless blog and rss aggregator. #projects #lamb

Via lamb-releases
Sander @ September 27 at 9:39 am

Taskfile EOL

I've archived Taskfile and am now using Just. It's got more community support and works better in my experience.

Taskfile will keep working going forward but I have no plans for new features. If you are a used, I'd like to thank you.

Update: I'm not completely happy with how the just commands are executed, many shell commands I can't get to work, so I'm considering moving back to Taskfile. Will keep you posted

#projects #taskfile

Sander @ September 27 at 9:37 am

I switched back to the vintage theme as the 2024 Lamb theme I'm working on has some display issues on mobile. #lamb

Sander @ September 11 at 2:57 pm

Setup TextPattern using PHP composer and DDEV

I was totally going to step-by-step this guide but then I lost my draft.

TextPattern (TXP) instructs you to extract a zip file into your webroot and on upgrade replace all the files. If you have used PHP Composer to install your PHP dependencies you know this can be done more smoothly.

Composer PHP dependencies

If you want to the quick way, I've created a composer.json to get you started: view gist.

It adds the GitHub repository as a composer dependency, and installs it into the site/ directory using oomphinc/composer-installers-extender. The repo's type is set as a project type, so there are a couple of lines needed to setup composer installer to match it.

Run composer update, you will now have a site and vendor directory, in addition to the composer files:

├── composer.json
├── composer.lock
├── site
└── vendor

Missing JavaScript Depependencies

This typically should have been enough but in the TextPattern GitHub project the package.json file that contains the JavaScript dependencies is both ignored by git (so is missing from our checkout) but requires dependencies the install needs to run.

Let's pull in the copy from the main branch and install the dependencies using npm:

$ cd site
$ wget https://raw.githubusercontent.com/textpattern/textpattern/main/package.json
$ npm install --omit=dev
$ cd .. 

Local environment

For a local environment, I recommend DDEV. To set this up, simplify specify a project name and the docroot where the TXP install is installed to:

$ ddev config --docroot=site --project-name=mysite
$ ddev start
$ ddev launch

The #TextPattern Setup wizard should now open. Use ddev describe to inform you of the database values to enter in the setup wizard.

edit: For some reason I'm getting a database unavailable message. I'll update this if I find a solution. edit2: Solved I think, either through a reboot or the npm instructions.

Sander @ August 27 at 1:57 pm

Macos' patch command is outdated and doesn't work with some modern patches. Homebrew has a gpatch (GNU's patch) which is up to date and the composer PHP utility takes advantage of this automatically if it's installed. #til

Sander @ August 23 at 10:29 am

Wine32 on elementaryOS 7 or Ubuntu 22.04

x86 games, like Championship Manager 01/02, might not install on this OS which cannot install wine32 due to system conflicts. This means apps like Bottles (Wine wrapper) cannot select a working Wine version.

To get around this, install the PlayOnLinux flatpak, which has an option to change the current Wine version. This will let you pick x86 versions, which install wine32 inside the flatpak. After which the installer will run.

If you get prompted to insert the CD use this trick to copy the the files into a virtual CDROM

#gaming #cm0102 #linux

Sander @ August 6 at 8:23 am

Taskfile 2.0.0

I've released Taskfile 2.0.0, a task runner using taskfiles containing bash functions.

It's a nicer menu and shorthand for sourcing a bash file with functions.

The latest version contains a few small changes. As I renamed system tasks, semver dictates a new major version is called for:

Breaking change: inbuilt tasks (_edit, _edit-local, _help) are now prefixed with underscores so they're hidden from the Task list.

  • New: hide your own helper tasks by prefixing their function name with underscore
  • New: edit your local taskfile by running t _edit-local
  • General tidying up

To update simply git pull if you git installed it, or replace the Taskfile.sh script some other way.

#projects #taskfile

Sander @ July 31 at 6:40 pm

While Palworld allows for online play, its huge concurrent player numbers were not the result of its developer carefully cultivating a fear of missing out (FOMO) among players.

A chill game that’s not causing mental health issues, genius.

Sander @ July 16 at 9:18 am

Sometimes I want to monitor a page for changes, for example news articles where the publication has contacted someone for comment. This week I'm trying out Distill Web Monitor as a browser extension and optional desktop app and it has nice features such as a very extensive notification system (desktop, email, audio) and visuall diff, monitoring of specific parts of the page etc.

2024-07-16_10-16.png

Just a tip if you're looking for something similar. #software

Sander @ July 15 at 10:53 am

Small tip: In Firefox you can enable tab previews on hover by setting the following preference: browser.tabs.hoverPreview.enabled to true

Sander @ June 24 at 1:50 pm

Found an interesting article with a positive take on useful features that modern blogs should have. The Hacker News comment thread shows that whether a feature is considered useful is very subjective.

I'd like to go further and state that most of the usability and user experience enhancements should be implemented as browser add-ons, so that they can be installed if the user sees it as a positive enhancement to their reading experience.

The old-school view is that the reading experience is the domain and the responsibility of the browser, and we have collectively gone way beyond what a website should offer in terms of behaviour. #technology

Sander @ June 12 at 4:11 pm

Trying out a new 2024 theme I've started working on. It's not super clear yet where a new post begins, and it's a bit bland. #lamb #projects

Sander @ June 7 at 8:39 am

Bandcamp celebrated their 40th birthday last month by removing its most useful feature, it's no longer a BandCamp Friday every month!

Sander @ June 7 at 8:29 am

Most mobile “games” are like being a Sponsor on the Hunger Games: spend money dropping in some booster food for the contestant, who you have no control over. Is it time to reclassify these premium currency manager apps under the Finance category they belong to? Using their family's credit card, it's training multiple generation of kids to become hedge fund managers gambling their own future. My review of NASCAR Manager: 0% interest gained #games #iap

Sander @ April 19 at 10:02 am

Schrödinger's login: if I am able to comment as a member, but see a login form when I click on my account, was I logged in or not?

Sander @ March 13 at 12:37 pm

Tried 1Password for SSH keys and Git management (keys in 1Password, authentication via agent + desktop prompt before access, and 1Password must be running) and not a fan of more red tape around the SSH keys. Non-interactive processes just fail to use the key first-time round, so I ended up having to commonly do operations twice. Easy restore from a BackInTime backup. #security #linux

Sander @ February 21 at 11:07 am

Navigate Xbox Series console using LG remote

To navigate an XBOX series games console using an LG Magic Remote, first disable the Automatic Configuration option in the Connection settings under HDMI Configuration in the TV's settings. Reconnect the XBOX's HDMI cable going into the TV. Then on the input switcher, edit the Xbox setting, mark it as a Blu-ray player manufactured by Microsoft, and follow the wizard. #technology

Sander @ February 12 at 10:38 am

Looking at my browser tabs, I can't believe that we collectively have still not standardized on page title vs site title formats in 2024. I've seen SITE - PAGE, PAGE / SITE, PAGE | SITE, SITE: PAGE, PAGE etc. I'd prefer it if we had a sitetitle tag in head and let the browser figure it out. #technology #html

Sander @ January 31 at 11:57 am

Use an expression to select an array value in PHP. It's handy for quick output logic. Update: it's a bit too clever, perhaps, versus using the tenary operator.

$classes .= [ ' sort-default', ' sort-custom' ][ has_custom_sort( $post ) ];

#php #technology #tips

Sander @ January 23 at 10:11 am

I replaced my cold half finished coffee with a hot half finished coffee.... because the machine ran out of water 😂

Sander @ January 3 at 2:07 pm

What would it take to make writing vanilla JavaScript more pleasant? After reviewing the code for my blogging engine Lamb I concluded:

Most of the code adding interactivity to personal websites comes down to running code after the page has loaded; niceties to query the DOM and hook into events. There's probably more but this is a start. The result is shorthand.js. Hint: it's not dissimilar to jQuery, but you can fully learn it in 5 minutes.

Which simplifies code to:

onLoaded(() => {
    const forms = $$('form.form-delete')
    forms?.forEach($form => $form.on('submit', ev => {
        cancel(ev)
        let confirmed = confirm(`Really delete status ${ev.target.dataset.id}?`)
        if (!confirmed) return
        ev.target.submit()
    }))
})

This is just a prototype and will evolve.

#technology #projects #lamb

Sander @ January 2 at 4:37 pm

If you're using the Anytype (current version at the time of writing: 0.37.3) AppImage and made a .desktop file to launch it, here are a few tweaks that integrate it into your system better.

You may want to use a program like Desktopius to edit the .desktop file.

The Anytype icon and part of the main window

Prevent two dock icons

If you see one item for the AppImage and one for the application window in the Dock, add StartupWMClass=anytype and these will be combined. This value is the result of running xprop WM_CLASS and clicking on the Anytype main window.

Fix the icon

If you see the generic icon, extract the icon to a path and update Icon=/path/to/anytype.png (replacing the path to the directory where you will extract the icon).

To extract the icon from the AppImage do the following:

$ cd /tmp
$ mkdir anytype && cd anytype
$ /path/to/Anytype.AppImage --appimage-extract
....
$ cp squashfs-root/usr/share/icons/hicolor/1024x1024/apps/anytype.png /path/to/anytype.png

#technology #anytype

Sander @ January 2 at 9:59 am

PHP-Activate 0.3.1

I've released php-activate 0.3.1, a PHP project version manager for Linux systems using native PHP packages.

Made for those working with multiple projects using a variety of PHP versions, this script will switch to the correct PHP version for the local shell session. It does not require sudo, so even works in IDEs.

The latest version contains a few small changes:

  1. Eliminate the activate_php:export:20: invalid option(s) output. Exporting the php function is not needed as we source the script into the current shell session.
  2. Harden the script by implementing shellscript linting recommendations.
  3. Readme update.

#projects #phpactivate

Sander @ December 15, 2023 at 9:47 am

PHP-Activate 0.3.0

I've released php-activate 0.3.0, a PHP project version manager for Linux systems using native PHP packages.

Made for those working with multiple projects using a variety of PHP versions, this script will switch to the correct PHP version for the local shell session. It does not require sudo, so even works in IDEs.

The latest version drops support for the Fish shell again, and fixes compatibility with direnv. The correct PHP version is activated when changing into a project directory that is setup according to the README. #projects #phpactivate

Sander @ December 11, 2023 at 8:51 am

I experimented with _hyperscript to replace the little JS enhancements on the Lamb microblog over the weekend. After a day I had all the scripts replaced with clearer code in about half the lines of the previous JavaScript. It sounds like a success, however I rolled it all back. This is because _hyperscript requires a 100KB library, whereas the 3KB JavaScript it replaces does not. As Lamb is a minimal blogging system, that's the vast majority of the pagesize. #technology

Sander @ December 6, 2023 at 2:28 pm

Lamb image test

Image upload support has landed in the Lamb repo:

Drag images into the composer textarea and they will be automatically uploaded behind the scenes and inserted into the post as markdown, similar to how GitHub works:

Peek 2023-12-06 14-36.gif

This has been the main missing piece for me, so I'm very pleased. #lamb #projects

Sander @ November 14, 2023 at 10:08 am

Ashley Belanger writes for Ars Technica Apple gets 36% cut of Safari deal with Google as default search:

Statista reported that Google's advertising revenue was $224 billion in 2022, and based on that, Engadget estimated that Apple likely gets paid in the tens of billions of dollars for Google's default Safari placements.

Meanwhile Slack, Discord and others continue not to benefit from an Electron commit that wasn't properly reviewed setting Search with Google as the default #technology #privacy

Sander @ October 27, 2023 at 1:59 pm

There is no queue, I play one song: Spotify adds the next song in the playlist in the queue. There is one item in the queue, I add another song to the queue: Spotify replaces the queue with the song.

Sander @ October 5, 2023 at 8:59 am

PHP-Activate 0.2.0

I've released php-activate 0.2.0, a PHP project version manager for Linux systems using native PHP packages.

Made for those working with multiple projects using a variety of PHP versions, this script will switch to the correct PHP version for the local shell session. It does not require sudo, so even works in IDEs.

The latest version adds support for the Fish shell. #projects #phpactivate

Sander @ September 26, 2023 at 10:24 am

When you want to create an exception to a add_header directive in nginx that is declared in an include, just declare it before it, as successive declarations of the same header are ignored. #til

Sander @ September 22, 2023 at 9:12 am

On personal goals

Today, I've realised my overarching goal as a software engineer: create digital experiences that help improve mental health for the people using them.

Unwittingly I myself have trended towards community software where capitalism, media manipulation and corporate influence is minimised (open-source, privacy first, self-hosting), and writing software with these values in mind.

In my experience, capitalism and corporate software distort the incentives of software for the financial benefit of it's backers. Media manipulation uses information overload and content agendas to influence the news cycle and change the common values we live by. This ultimately is more important to them than the wellbeing of the person experiencing the artifact, but not to me.

How have I been unwittingly trying to create positive user experiences:

#technology, #projects, #society

Sander @ September 19, 2023 at 1:52 pm

Made a Linux shell script called BreakAware that calculates the time since your last break as I couldn't find an alternative to Pandan (macOs).

BreakAware is a lightweight and user-friendly Fish shell script designed to help you maintain a healthy work-life balance. It tracks the time since your last break, whether it's due to PC sleep, hibernation, logout, or session locking. BreakAware empowers you to be more aware of how you spend your time and encourages you to take regular breaks, enhancing your productivity and well-being.

#projects #breakaware

Sander @ September 9, 2023 at 12:56 pm

If you want an example of why we need a viable open source phone ecosystem, try and share some assorted music files from your non-Apple pc to another person’s iPhone. #technology

Sander @ August 25, 2023 at 11:49 am

RAM Usage Nerdery

I've been wondering how much RAM I used on my 32GB Ubuntu derivative workstation, mainly used for web development using docker containers and light vm experimentation. Yes when I spotcheck with htop I have enough RAM free, but do I actually need 32GB, when I'm in the market for a new device or an upgrade?

It turns out, yes I do ideally.

The setup

On startup I've been running this script to save the memory stats into a csv file:

#!/usr/bin/env bash
while true
  do free  | grep Mem | tr --squeeze-repeats ' ' ',' | tee --append ~/memory.csv
  sleep 10
done

Today (after 15 days) I pulled the stats into a database and browsed it:

sqlite-utils insert /tmp/mem.db memory-stats memory.csv --csv
datasette /tmp/mem.db

Sorting by the available column shows that the lowest value I get is 11.9GB available to be freed.

The available column is the sum of the Free column plus the portions of the Buffers and Cache columns (or the Buff/cache column) that can be relinquished immediately. The Available column is an estimate, not an exact figure. https://www.howtogeek.com/456943/how-to-use-the-free-command-on-linux/#the-available-column

I think it's a reasonable measure. This system does not have zram memory compression enabled, that would help probably.

It has 4GB swap, I did not measure it's usage.

Hopefully this review helps for people who want to measure their own usage.

#linux

Sander @ August 16, 2023 at 10:10 am

You can search GitHub wikis by using the search bar and then filtering by wiki. That's almost as nice as keeping your notes in a Lamb instance ;-) #TIL

Sander @ August 16, 2023 at 7:13 am

We really now need a norobots.txt / terms of use for a persons identity to centrally state how a persons information can be not used by big tech. Something linked to indieauth perhaps?

Sander @ August 3, 2023 at 9:03 am

Anchor bugs in Blink engine browsers

I've been looking into an issue for work where Google Chrome loads a URL ending in an anchor and scrolls to the incorrect position on the page. Imagine linking to the third heading on a page and Chrome scrolling to a indeterminable position above that. Firefox is not affected.

After ruling out all JavaScript and the particular HTML source code, it turns out that disabling the html { scroll-behavior: smooth; } CSS style fixes the issue. My theory so I suspect there is a race condition between determining the length of a page and position of the element while scrolling? This results in bugreports such as "Anchorlink going to the wrong place"

Regular behaviour is also partially broken

What's more interesting is that blink based browsers are unable to scroll to the anchor even after the page is already loaded!

Testcase:

  1. load https://downloads.vandragt.com/test-long.html#test This page has an id attribute test set on the header but is otherwise plain text. Any other page will also work though.
  2. The page loads and the scrollposition is correctly set at the test header.
  3. Scroll up a paragraph or more than a screen, and refresh the page. Notice the scrollposition isn't set.
  4. Optionally refresh many times, or press the Enter key in the address bar to attempt to reload the page. However the scroll-position is now permanently broken until you navigate away from the page.

This results in bug-reports such as "It only goes to a place when you first enter the URL to the browser, it doesn’t go to the same place when you re-fresh the page". Together this erodes the trust in the application and honestly it's hard to believe this has not been more widely reported.

There's probably an elaborate JavaScript solution but in my opinion a browser's bugs should be fixed by the browser, because in the future when the browser fixes itself a workaround might result in incorrect behaviour. #technology

Sander @ July 28, 2023 at 11:43 am

Lamb 0.3.0

Introducing Lamb 0.3.0 - Literally Another Micro Blog. This release brings new features, improvements, and bug fixes, making blogging even easier. The update includes Docker support, an optional config.ini with support for menu items to customize your installation, improved documentation, and more.

Lamb offers a simple, self-hosted single-author blog with a Twitter-like interface, friction-free Markdown entry, discoverable Atom feed, hashtags support, and a 404 fallback URL feature.

Download the latest release from GitHub and provide your valuable feedback. #lamb #projects

Sander @ July 6, 2023 at 2:03 pm

The fixed line fiber broadband market is currently dysfunctional with too many players struggling to compete and see a return on investment. It is time for the UK industry to collaborate in a smarter way to provide all users with a better service," he said.

UK’s bigger than London.

source

Sander @ June 17, 2023 at 7:33 pm

Fafi 0.2.3

Fafi is a bookmark indexing and search tool.

Install the fafi command line app easily using pipx install fafi that's all that's needed, and then feed it a single URL, a text file with one URL per line, a bookmarks.html containing links (any browser's export) or --firefox and it will detect the Firefox profile and extract its bookmarks and index them.

Then search all your bookmark contents using full-text search and ranking!

New in 0.2.3

The release notes for version 0.2.3 of Fafi (Favorites Finder) include the following changes and updates:

  • Fixes pipx installs: This release addresses issues related to installing Fafi using pipx, a tool that allows you to install Python applications in isolated environments. The fixes aim to improve the installation process and ensure smoother usage of Fafi.

  • --url option: A new command-line option, "--url," has been added to Fafi. This option allows users to add single URLs directly for indexing and searching purposes. It provides a convenient way to include specific webpages in the Fafi search index.

  • --list=textfile: Another addition to the command-line options is "--list=textfile." This option enables users to specify a text file containing a list of URLs or webpage locations that should be indexed by Fafi. It offers a means to index multiple URLs at once from a single file, streamlining the indexing process.

  • Textual TUI: Fafi now includes a Textual Terminal User Interface (TUI). This feature enhances the user experience by providing a text-based interface within the command-line environment. The TUI improves interaction with Fafi, making it more intuitive and user-friendly.

  • Dependency updates: The release incorporates updates to Fafi's dependencies. These updates ensure that Fafi remains compatible with the latest versions of the libraries and packages it relies on. By keeping the dependencies up to date, Fafi benefits from bug fixes, performance enhancements, and new features introduced in those libraries.

View on GitHub

#projects #fafi

Sander @ June 16, 2023 at 11:23 am

Workaround for when poetry cannot find pyenv managed python

I use pyenv to manage python versions for my projects, and use poetry to manage project dependencies. Poetry was unable to find the latest python version, and insisted on creating virtual envs with system python.

Setting poetry config virtualenvs.prefer-active-python true did not work for me, and neither did poetry env use whatever-version:

$ poetry env use 3.11
Could not find the python executable python3.11

However pyenv can list the the full path to the currently active python, which can be used as a parameter to poetry, so the following worked:

$ poetry env use $(pyenv which python)
$ poetry install; poetry run python --version

Update: double check that pyenv is configuring the shell correctly -- $HOME/.pyenv/shims should be in your PATH variable, and your shell runtime configuration file (such as .bashrc / .zshrc) should contain eval "$(pyenv init -)"

Hope this helps!

#poetry #python #pyenv #ubuntu #elementaryos

Sander @ June 6, 2023 at 3:11 pm

In Sublime Text you can hold shift and select another tab and it will split the view! wow.

Sander @ May 15, 2023 at 1:29 pm

Sander van Dragt

This my personal site, Sander van Dragt’s Notes. I create positive digital experiences that aim to improve mental health for the people using them.

I'm a Senior Web Engineer at Human Made, an agency operating in the enterprise WordPress space, maker of Altis DXP, where I create better ways to manage content. I contributed to the core sitemaps feature that shipped with WordPress 5.5.

The site is powered by Lamb (see footer), my bespoke microblogging software that doesn't demand your attention. It’s frictionless and fast.

See Also

  1. Brain - a personal knowledge base.
  2. My GitHub profile with ~80 other side projects.
  3. Follow me on micro.blog this is Mastodon compatible as well.
  4. I post generative AI photos to photos.vandragt.com, and the gallery script is mostly generated too!

Other interests:

  • Indie publishing
  • Semantic web
  • PHP
  • Python
  • audio / DJ
  • automation
  • Game development using Godot
  • Backend development
  • Linux computing
Sander @ April 12, 2023 at 10:39 am

If you also find the Leave button in Slack Huddles moves about a lot at the end of meetings, you can click on the headphone toggle in the bottom of the left sidebar to leave a huddle. (or try your luck at russian roulette and press the shortcut which either starts, joins, leaves or ends a huddle)

Sander @ April 11, 2023 at 3:08 pm

Turns out yaml_parse() in PHP automatically parses a front matter block out of a markdown based post.

Sander @ April 10, 2023 at 11:04 am

Entry titles aren't optional in Atom feeds, how to micro blogs deal with that? Update: it seems by making the title an empty element.

Sander @ April 10, 2023 at 10:41 am

The AI evolution seems scary until you realise most of the applications are summarised as a wrapper around the OpenAI API that does all the work, with the context provided by a prompt prefix. So with half a day's study most programmers can participate. #technology

Sander @ April 6, 2023 at 10:43 am

Ubuntu's minimal installation appears to be the standard installation plus the removal of some packages! That's unexpected as I was trying to save installation time. #ubuntu #technology

Sander @ April 4, 2023 at 1:55 pm

Map Eject to Multitasking View

So I use ElementaryOS and in version 7 you are no longer able to map just the Eject key. I like to map this to the Multitasking View (something like the macOS Expose).

The solution is to use the DConf Editor application and search for show-desktop. ElementaryOS repurposes the show desktop to the multitasking view. Simply set the value to ['Eject']

Alternatively you can set the left-super key (windows/command) to the Multitasking View. This seems better supported.

#elementaryos #linux

Sander @ March 24, 2023 at 9:46 am

Lamb 0.2

I've released Lamb 0.2, my micro blogging app that's powering this site.

What's new?

  • Posts! Posts are statuses with a title. The title can be added in the front matter (front matter is parsed as an ini-string). Posts have a slug based on the title when the post was created.
  • Individual statuses / posts have opengraph tags for improved sharing fidelity.
  • The text editor grows to accommodate the input.

#lamb #projects

More info and download link

Sander @ March 24, 2023 at 9:41 am

0.2.0

Originally written on lamb-releases:

Posts! Posts are statuses with a title. The title can be added in the front matter (front matter is parsed as an ini-string) Posts have a slug based on the title when the post was created. Individual statuses / posts have opengraph tags for improved sharing fidelity. Fixed several XSS, thanks @cameronterry

Via lamb-releases
Sander @ March 24, 2023 at 7:24 am

Anyone, regardless of coding experience can now create scripts and simple WordPress plugins:

WordPress developers who want to share their AI-assisted creations with the community have also started submitting them to WordPress.org.

We can imagine the headlines in six months when another popular site or plug-in is hacked, when both the author and the generator and the webmaster don’t understand the code, and can’t review it for security weaknesses, The current tools are proof of concept creators, but please be careful not to assume production ready code.

If you want a code review done hit up an engineer, like myself #technology #ai #wordpress

Sander @ March 21, 2023 at 2:28 pm

I've released php-activate 0.1.2, a PHP project version manager for Linux systems using native PHP packages.

Made for those working with multiple projects using a variety of PHP versions, this script will automatically switch to the correct PHP version after cding into the project folder. It does not require sudo, so even works in IDEs.

The latest version contains only documentation changes, but I've been using this successfully for a few months, so wanted to share this more widely. #projects #phpactivate

Sander @ March 21, 2023 at 12:41 pm

Basic routing using REQUEST_URI

So for nginx it is not straightforward to setup PHP-FPM so that PATH_INFO is correctly populated. Lamb uses the following /index.php/some/other type routing, where /some/other should be the PATH_INFO. Instead I want to make setup for a variety of web-servers straightforward, so I've switched to the more robust REQUEST_URI. This simplifies nginx configuration and Caddy and the PHP built-in web-server are compatible.

REQUEST_URI contains everything after the domain name, including the query string, so that needs to be removed:

$request_uri = '/home';
if ( $_SERVER['REQUEST_URI'] !== '/' ) {
    $request_uri = strtok( $_SERVER['REQUEST_URI'], '?' );
}

We can see that for a request for the root of the site, REQUEST_URI returns / whereas PATH_INFO would be empty, so the code above takes that into account. We can then deduct a router action as follows:

$action = strtok( $request_uri, '/' );

Once the $action is known, it can be checked against an allowed list of actions:

switch ( $action ) {
    case 'edit':
        ...
        break;
    default:
        respond_404();
        break;

#php #lamb

Sander @ March 18, 2023 at 12:06 am

Godot simplified drag n drop tutorial

I was "following" Generalist Programmer's Godot drag and drop tutorial and I made a few refinements that I wanted to share. Please read the tutorial and then follow along.

Drop-in behaviour

Wouldn't it be cool to give a node drag and drop behaviour simply by dropping in a node with the script, independent of any other scripting?

We can do this by creating a new child node (here called Drag-and-drop Dropin), and attaching the script to it. It must extend from the dropin Node2D.

Node structure

In the script itself we make two changes:

  1. Disconnect the KinematicBody2D's input_event signal, and write it in code in the dropin's _ready function. Call it on it's parent: get_parent().connect("input_event", self, "_on_KinematicBody2D_input_event"). We want to process the input_event of the KinematicBody2D, not the dropin.
  2. In the _process function, assign the mouse position to the parent of the dropin: get_parent().position = Vector2(mousepos.x, mousepos.y).
  3. Same for the last line in the script where we set the position of the parent.

The script then reads as follows:

extends Node2D

var dragging = false

signal dragsignal

func _ready():
    connect("dragsignal", self, "_set_drag_pc")
    get_parent().connect("input_event", self, "_on_KinematicBody2D_input_event")

func _process(delta):
    if dragging:
        var mousepos = get_viewport().get_mouse_position()
        get_parent().position = Vector2(mousepos.x, mousepos.y)

func _set_drag_pc():
    dragging = !dragging

func _on_KinematicBody2D_input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            emit_signal("dragsignal")
        elif event.button_index == BUTTON_LEFT and !event.pressed:
            emit_signal("dragsignal")
    elif event is InputEventScreenTouch:
        if event.pressed and event.get_index() == 0:
            get_parent().position = event.get_position()

Simplifying the script

I was refactoring this, and it turns out we can simplify this further.

  1. We don't need a dragsignal because the signal is both emitted and consumed within the same script. We can just replace the emit_signal calls with calls to _set_drag_pc(). We can then remove the connect() call in the _ready function, and the signal dragsignal.
  2. The same function is called when the left mouse button is both pressed and not pressed, so we can remove that conditional and remove the elif statement in the input event handler.
  3. As there is only one invocation of _set_drag_pc() we can inline it.

The final script becomes:

extends Node2D

var dragging = false

func _ready():
    get_parent().connect("input_event", self, "_on_KinematicBody2D_input_event")

func _process(delta):
    if dragging:
        var mousepos = get_viewport().get_mouse_position()
        get_parent().position = Vector2(mousepos.x, mousepos.y)

func _on_KinematicBody2D_input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT:
            dragging = !dragging
    elif event is InputEventScreenTouch:
        if event.pressed and event.get_index() == 0:
            get_parent().position = event.get_position()

So this dropin can now be added to any node to add Drag-and-Drop behaviour. I think the script can be improved a little so that the node is not centered under the mouse cursor but takes account the offset where it is picked up.

Let me know your thoughts! #godot

Sander @ March 16, 2023 at 4:49 pm

404 Fallback comes to Lamb

I've added a 404 fallback feature to Lamb. What this means is that if you request a URL that doesn't exist on your Lamb instance, it will redirect to the same relative path on the domain you have provided in the configuration, if you enabled this feature.

This means you can move your site from example.com to say 2023.example.com and then set that as the 404 fallback url and you will not lose any SEO traffic! Here's an example! #lamb #projects

Sander @ March 15, 2023 at 4:15 pm

Whilst building Lamb I have realised that RedBean ORM, SQLite + plain PHP (used here) or CodeIgniter makes for a very nice setup. Turns out the frameworks just add loads of extra knowledge, that you don't really need if you know not to shoot yourself in the foot with security stuff.

(Famous last words)