RSSAmplifier

Blog

Pixelastic

blog.pixelastic.comRSS feed ↗319 posts

Latest posts

Keeping the context of an Airtable Record Picker from page to page

I'm using Airtable Interfaces a lot, to pilot my automations. For a project at work I built a whole pipeline to help us organize meetups in our office. It starts with the URL of a meetup.com event, and ends with the printing of the signs to put in the building, and goes through all the phases of calculating the number of pizzas needed, booking rooms in the corporate calendar, printing badges for…

Compression strategy for heavy Whisper files

I'm often taking audio notes with my phone recorder app. I then have a make.com workflow in place where I push the audio file through Whisper to get a transcript of it, and start other workflows based on the content of the transcript. Sometimes it's just a simple note to remind me to do something, which gets added to my TODO list. Sometimes it's an idea about a blogpost I'd like to write, which…

Generating Bluesky embeds with templated.io

In my recent no-code plunge, I discovered templated.io . It's an online service to generate images based on templates you create yourself. The first use-case I had for it turned out to be a bit too complex for what it offers, but I've now used it for something where it shines much more. You might have stumbled upon this post through the embedded link on Bluesky, and the image for the link has been…

Differences between static and dynamic imports in ESM

This article has probably be written hundreds of times already, so I don't think I'm adding anything new to the overall tech knowledge online, but hey writing it will probably help me remember it better. In modern (ie. ESM) JavaScript, you no longer use the old require() method to load your dependencies; you use import instead. What I didn't really realize at first when I started migrating my…

Fetch this: Illegal invocation in Cloudflare Workers

If you write anything in JavaScript, you've certainly encountered the this keyword, and wondered what is this ? Even if you're an experienced JS dev, sometimes this can bite you in unexpected ways. This happened to me today, while porting a codebase from the got library, to the builtin fetch method. I had a method to write that was doing a bunch of API calls (using fetch ), massaging the data I…

The hidden complexity of "just a few lines of code"

We're often hosting meetups in the Algolia Paris office. To make our lives easier, I decided to build an API that would allow us to fetch metadata about the event easily (like description, date, list of attendees, etc). I decided to host that on Cloudflare Workers. The premise was simple. Pass the url of the event to the API, and metadata about the event returned in a nicely formatted JSON . My…

My journey through the ESM Tree Shaking forest

I had to work with Cloudflare Workers recently, and everything worked well until one day one of the HTTP calls I was doing started to fail. When I ran the same piece of code locally it worked (obviously!). But pushed and ran through Cloudflare Workers, it failed. This was the first step in what then became a day-long trip into the rabbit hole of debugging. After a couple of hours of debugging…

Minimal .zshrc for remote servers

Recently, I found myself connecting to remote machines quite often. I have to debug remote servers for work or connect through ssh to an emulation handheld console I just bought (more posts coming on that later). But I've configured my local zsh so much that when I connect to a bare remote server I feel a bit lost. No colors to differentiate folders and files. No tabbing through completion. Even…

Make webhook status visual feedback in Airtable

I've been working on my Airtable and Make automations, and I wanted to share a small trick I've implemented to improve error handling and visibility. I use Airtable interfaces equipped with various buttons that, when clicked, trigger webhooks in Make, that in turn update my Airtable record with additional data. However, I found it quite frustrating that there was no visual feedback indicating the…

Counting Elements in Airtable

Airtable is an impressive tool that keeps surprising me with its power. But sometimes, it seems to be missing what I assume would be very basic features. For example, it has powerful linking capabilities; let's say you have a companies table and an employees table, you can have a company field in employees that automatically allows selecting an existing company. The mirroring effect is…

Best Practices for Airtable IDs

When working with Airtable, I've started to develop some good practices regarding IDs in my tables. Airtable has a concept of a Primary Field , which is the "main" field of a given entry, displayed as the first column in Grid view. It can be any field of the table (even a formula aggregating several fields), and will be used in the UI to represent the row. But Airtable also has an internal notion…

My first steps into automating knowledge sharing

I’ve been saying, “I’ve been coding for over ten years.” for more than a decade now (so yeah, I've been coding for a long time). And I still love it. Coding feels like a deeply creative process to me. It’s about long-term problem-solving and crafting elegant solutions. But it's also about diving into the nitty-gritty and getting your hands dirty. I take pride in writing clean, maintainable code,…

Writing faster: just speak

As a web and software developer, I often see coding as a creative way to solve problems. After years in the field, I take pride in writing clean, understandable, and maintainable code. Understanding the quality of my work gives me satisfaction, much like an artisan. Recently, I have been diving into automation tools that help streamline repetitive tasks, enhancing my productivity. My journey with…

Using multiple variable modifiers in zsh

zsh has a lot of variable modifiers, and sometimes trying to put more than one on the same variable either throws an error or does nothing. To fix that, I've been assigning and re-assigning to the same variable, each time with a new modifier added. Today, I found a syntax that allows chaining/embedding of modifiers. local myArray =( ../../up-the-tree ./here ../in-the-parent ) # To display this…

Padding a string with zsh

To pad a string with leading spaces in zs, you can use ${(r(15)( ))variableName) . r(15) pads on the r ight (use l for l eft padding) The 15 defines the maximum length of the string ( ) defines the character to use for padding (here, a space)

Proxy command completion in zsh

Commands like sudo take other commands as input and run them in a specific context. I also have a command similar, called lazyloadNvm that runs nvm use when needed. I wanted zsh to suggest completion for the passed commands instead of completion for the initial command ( sudo or lazyloadNvm ). The solution was to create a _nvm-lazyload comdef file like this: #compdef function _nvm-lazyload () { #…

Debugging performance issues in zsh

If I add too much code in my .zshrc , my zsh takes longer to load. As I use a lot of different terminal windows (splitting one main tmux window), I want those split to happen quickly. This is why I'm trying very hard to keep the loading time of zsh under 150ms. Hyperfine One way to evaluate the current loading speed and track potential regressions and improvement is to use hyperfine hyperfine…

Substrings in zsh

To get only parts of a specific string in zsh, you can use the ${var:start:stop} syntax. If stop is omitted, it will cut until the end of the string. You can also pass negative values.

Path to the current script folder in zsh

To get the path of the folder of the script currently running in zsh, use ${0:a:h} . $0 is the path to the currently running script, a forces it to absolute, and h to keep the head (the folder). This is useful when you need to reference scripts that are not in your $PATH , but are stored close to your initial script.

How to trim a string in zsh

Trimming a string means removing any space at the beginning or end of it. It's something I need to do often when parsing the output of commands. The easiest way I found to do it in zsh is to cast the string into an array, and back into a string with myvar="${=myVar}" . The ${=} syntax splits the string as a list of arguments (so, separated by spaces), and wrapping it in "" casts it back into a…

Slicing an array in zsh

To get only part of a specific array in zsh, you have to use the [@]:X:Y syntax, where X is the start of your slice and Y the end of it. You can omit the Y or use negative indices. For example, ${myArray[@]:2} slices the array by removing its first element

Check if an array contains a value

zsh doesn't have a way to check if a value is in an array, but can tell us (using ${(ie)} ) the index of the element. The i means i nverse subscript, meaning that instead of accessing a value by its index, we want to access the index by its value. e is for e xact match; without it zsh will return the index of any value that contains the substring, instead of exactly matching it. The trick is that…

Custom completion methods in zsh

I needed to define a custom completion function to suggest files when typing vfa <TAB> . vfa is my alias around git-file-add . I needed it to suggest modified/added files. Telling zsh about the completion function I started by telling zsh which completion method to call when completion git-file-add with this code: compdef _git-files-dirty git-file-add The convention in zsh is that completion…

Calling external scripts in the shell in vimscript

Some of my vimscripts need to call external commands, through the shell CLI. I learned some quirks the hard way, and documenting them here The basics Calling an external command is done through system('external-command') . If you need to pass arguments you must wrap them in shellescape(myArgument) or it will mess up spaces and quotes. The quirks If you echom the result and see it through :messages…

Array (List) functions in vimscript

Vimscript Array s are called List s. They have a set of rules and functions that I'll document here for my own reference: Basics They are defined with let myArray=['one', 'two', 'three'] They are zero-indexed: echo myArray[0] is one They can be accessed from the end echo myArray[-1] is three Functions add(myArray, 'four') adds a new elements. myArray+=['four'] also works get(myArray, 0, 'default…

Parsing string as arguments in zsh

I had a commandOptions string variable that I wanted to use as arguments to fzf . But commandOptions had all kind of spaces and quoted strings in it and I had a hard time passing it as a set of distinct arguments and not one long string argument. The best solution I found was to actually display this commandOptions in a multiline format, where each line was an option. Then, using the…

Deduplicating array values in zsh

Given an array with a lot of values, I want to keep only one occurence of each value. I want to make those values unique. The (u) modifier local myArray =( a b c d a b b ) echo ${ (u)myArray } # a b c d Applied on an array, the (u) (for u nique) deduplicates the array. The typeset -aU definition Somehow, I didn't work in my case and I'm still unsure why, so I found another way. By defining my…

Replacing new lines with spaces in zsh

Another one of those things I need to often do in zsh and never remember the syntax. I had a multiline string (as returned by fzf ) and wanted to convert it into a single line, with spaces instead of spaces. This was the right formula: selection=("${(f)selection}")

Complex sed search and replace (multiline, regexp, non-greedy)

I had a large chunk of text (output from another command), and needed to perform a search and replace on it. I usually do that either with zsh builting ${var:gs/x/y/} syntax or sed , but this time my pattern was spread on several lines. Multi-line with --null-data The trick here is to use sed ---null-data to make it operate on the full text instead of on invidual lines. Technically, it now…

Splitting a string with zsh

This is one of those transformations I know how to do with node, ruby, or even the command line, but that I always have to refer to Stack Overflow when attempting to do it with zsh . Hopefully, writing this blog post (and referring to it later) will help me remember how to do it. To split a string variables by a delimiter, one can use the (${(@s/X/)variableName}) syntax. The wrapping () means that…

ZSH filepath modifiers

zsh comes bundled with variable modifier to alter filepaths and extract the relevant parts. Given the following code, we can display $filepath in a lot of different ways: mkdir -p /tmp/subdir cd /tmp local filepath = ./subdir/file.zsh | Name | Output | Modifier | Mnemonic | | --------- | ---------------------- | ----------------- | ------------------ | | Absolute | /tmp/subdir/file.zsh |…

Default variable values with zsh

zsh has two modifiers ( ${:-} and ${:=} ) to handle fallback for empty values. echo ${ahead:-0} will display the variable $ahead , or display 0 if the variable is empty. echo ${ahead:=0} (note the := instead of :- ) will assign 0 to the variable $ahead , and then display it. They are pretty similar, and in that example the result is the same. But with := , the variable will still be set to 0…

Search and replace with zsh

To search and replace with zsh , there are two ways. With ${var//XXX/YYY} This will replace all occurences of XXX in $var with YYY . Note that you can interpolate variables inside of XXX , so ${var//${input}/YYY} with input="foo" will replace foo with YYY in $var . You can use only one / instead of // to only replace the first occurence. With ${var:gs/XXX/YYY} The :s/XXX/YYY modifier is the basic…

Thanks, HTTrack

Sometimes, you need to download a whole website locally. And for that, HTTrack is the best tool I ever found. Sure, you could use wget and some recursion to get what you want, but HTTrack solves all that for you. Reasons you might need to download a whole website: - You need to browse it when you don't have an internet connection (on the go, with low data usage, in a train, etc) - You want to run…

Scoping zsh variables

By default in zsh, if you define a local myVariable it will be available to the whole script running it. Any of those variables defined in your .zshrc will also be visible in your terminal. This can create weird bugs when you accidentally defined a variable with the same name as another zsh script. Note that those are not environment variables. Even if you can read them from your zsh terminal,…

Dynamic variable names in zsh

Imagine the following scenario: local projects=(blog www meetups) local color_project_blog=146 local color_project_www=75 local color_project_meetups=23 And now you'd like to iterate on all projects, and display their associated color. You need dynamic variables, where part of the variable name is itself coming from another variable. This will be achieved using two zsh modifiers: ${(P)} and ${:-}…

Iterating on words and lines in zsh

When writing zsh scripts, I often needs to iterate on elements, but depending on how I create them, they can either be a core zsh array, a string of words, or the output of a command, delimited by newlines. Iterating on an array Iterating on arrays in zsh has a pretty straightforward syntax: local projects =( firost aberlaas golgoth ) ; for project in $projects ; do echo " ${ project } is one of…

Firebase authentication with Auth0

I use Auth0 on my current project to authenticate my users. It prompts my users with a clear modal UI to ask them to authenticate using Google/GitHub/Other third parties. It's an easy way to handle authentication from the front-end without too much hassle. But my app also uses Firebase as its main database, and I'm querying it from the front-end. I've set my Database rules to auth != null meaning…

Authentication to Firebase Database from a Firebase Function

On one of the projects I'm working on, I'm using both Firebase functions and Firebase Database. I'm calling functions in reaction to specific events, that will save data in my Firebase Database. I managed to have something running in development in a week. As I was still developing, I kept the default ACL to read:true and write:true on the database, meaning that anyone could read and write my…

Creating a screencast from the commandline

A picture is worth a thousand words, that's why I always try to add screencasts when describing an issue I'm facing. I found it useful to be able to record my screen when I'm filing a GitHub issue about some UI or UX issue. I have a method called gif-record in my command line toolbox that let me do that. It let me draw a rectangle on screen, record what is happening inside, and get a .gif as…

(Not)Hibernating Ubuntu 16.04 with full disk encryption

To maximize the usage of my new laptop battery, I wanted to have it hibernate when I close the lid. I could see I had an "Hibernate" option in the settings, but it always stayed always greyed out and I could not select it. One morning I sat at the table decided to fix this issue. First thing I tried was running sudo pm-hibernate to see if I could actually hibernate. The command did nothing except…

Mocking in Jest

I used to do my JavaScript testing using a combination of mocha , expect and sinon , but Jest packages all those features into one cohesive package. Transitioning to Jest has been smooth. The part that took me a while to figure out is how to properly mock methods, and this is what I'm going to develop here. Mocking direct methods Imagine a dummy component with two methods, foo and bar , with the…

Sending data to an iframe with Vue.js

Communicating from a parent window to a child iframe is a known problem in JavaScript and has already been solved. How to do it in the context of a Vue.js application is slightly different but based on the same principles. I was confronted with the matter yesterday and had to find an elegant way to send data (credentials) from the parent window to a child iframe from my Vue.js app. Here's how I…

Importing iframe with Webpack and Vue.js

I've spent hours on a webpack + Vue.js + iframe issue yesterday. As I don't want all those hours to be completly wasted, I'm going to document my issue and the final solution. The problem I'm working on a Vue.js application, using Webpack for building all the assets. One of the pages need to include an iframe, loading a stand-alone keen-explorer.html file. My problem was that the…

Publish my first npm package

I published my first npm package today. It's a micro-css framework, based on tachyons.css , but extended with Algolia-specific classes. What the package actually do is not the point of this post, though. What I'd like to share here are the tricks and workarounds I had to get right to publish the final package on NPM. Having a script ready for release I've reused a release script we've been using…

Server backup using Dropbox

Last week-end I received an email from the company that hosts this very own website. Their monitoring detected that there was an issue with my server. 2 hours later they were able to tell me something was wrong with my hard drive. 24 hours after that they explained the procedure to get the hard drive replaced. I'm using this dedicated server for hosting websites, but also as a backup for some…

Meetup random user picker

Being co-organizer of two meetups ( HumanTalks and TechLunch ) in Paris, I often give random prizes to the attendees at the end of the sessions. It can be free tickets to conferences we are partners with, or gifts from some of our sponsors. To choose who is going to get the prize, we resort to randomness and we have a bunch of JavaScript scripts lying around to do that. To make the process easier…

Making of CSS Flags

If you're following me on Twitter, you might have seen that I released a crazy project called CSS Flags . People often ask me why I did such a thing. This blog post is an attempt at explaining the thought process that motivated me to build it. Trip to Tours Two years ago I was on holidays and visited the city of Tours, in France. It's a small medieval city where you can find the museum of…

How to spot a bullshit hackathon

Being co-organizer of a meetup group , I often receive messages from companies asking us to promote their hackathon or conference. We always refuse to do such advertisement, unless we've already attended their events and appreciated it. Last week, we received a mail about what I call a "bullshit hackathon". I've translated it to English and replaced the name of the company with FooBar. Enjoy your…

Searching the ParisWeb conferences

I've been going to ParisWeb almost every year since it started ten years ago. I missed the first one and the 2012 edition (I was living in New Zealand at that time. I guess it's a good enough excuse). I cannot say how much I learned from this event. I used to say that I could learn more in two days at ParisWeb than in 6 months of technical watch on my own, reading blogs. That's the conference that…