I enjoy InvoiceShelf since I migrated to it in December 2024. InvoiceShelf is open-source invoicing software. I do not allow it to send emails, but I’m exploring the idea.
How to prevent local web apps from sending emails
I run MailHog. It’s an open-source email catcher that allows me to see what emails sites running on my computer have tried to send.
Configure InvoiceShelf to use MailHog
Go to Settings > Mail Configuration.
Mail Driver: smtp
Mail Host: 127.0.0.1
Mail Port: 1025
Mail Encryption: none
Screenshot
Here’s a screenshot of my Mail Configuration page.
Create a directory for the site & install Drupal files
All my sites live in ~/sites, so I navigated there in macOS Terminal and ran these commands. I want my Drupal site in a folder named p8hd and my local website to live at https://p8hd.test.
composer create-project drupal/recommended-project:10.4.1 p8hdcd p8hd
valet link
valet secure
This creates a directory at “~/sites/p8hd”, populates it with composer.json and composer.lock files, installs the composer dependencies, creates a symbolic link, and creates a TLS certificate. A website is now live at the URL https://p8hd.test.
I’ve been a SiteGround customer since they gave me a free year of hosting at WordCamp US 2016 in Philadelphia. I do not believe I will renew in February 2025. I moved my sites from SiteGround to an Akamai/Linode.com server. I’m using SpinupWP to manage WordPress installs on the server, and anyone who uses this link to signup gets $50 to spend at SpinupWP.
If you’re looking for managed WordPress hosting for your business, I recommend Anchor Hosting. Anchor builds on top of great managed WP hosts and takes care of updates. I chose SpinupWP + Akamai because the number of personal sites I operate fluctuates, and a per-install cost structure is not always a great fit.
Recently, I had to re-home a site built on CS-Cart. SiteGround has been a great place for the client so far, so I recommend SiteGround for some non-WordPress sites.
Why I moved
SiteGround’s price no longer competitive for me
Support is necessary & AI chat bot support hallucinations
Bad email service, even though I know better
SiteGround’s price is no longer competitive with my skill level
I don’t need a UI anymore. I’ve got shell scripts! The control panels at hosts like SiteGround are just fancier versions of cPanel, and I can operate at the command line. Designing database queries is more comfortable in an app like phpMyAdmin rather than the mysql client shell, but this work is being done on my local copy of the site and the apps running on my computer, not the server.
Tech Support is Necessary With Big Hosting Companies
Server configuration changes require support tickets. The people at SiteGround have always been kind and helpful. Since I signed up, it has gotten more difficult to drill down through the website to find a contact form. It is the case I’ve migrated away from a hosting company that uses chat and chatbot support to a company that takes form submissions and replies via email.
AI Chat Bot Support
Months ago, SiteGround’s AI support hallucinated an answer to me. No one wants this, but yet some have deployed:
I’m a happy ProtonMail customer
I started a consulting business, tried Google Workplace for a year or two, and then began using a free email account from a hosting company for important work like a fool. I ran into a problem with SiteGround email in 2023.
SiteGround filters outgoing email for spam, and will refuse to send a message with a 550 High Probability of Spam error because of links with unique domain extensions it finds in quoted replies. This is absurd, because there would not be a quoted reply unless SiteGround accepted the message containing the link! Zoom meeting links use a .us domain.
SiteGround also refused to send a reply because it found a non-https link in a signature in a quoted reply. This good-enough-to-receive-but-not-good-enough-to-send treatment regarding quoted replies forced me to try ProtonMail, and I’m glad to have made the switch. ProtonMail customers get free VPN software, so you might save money by switching. Try a free month of ProtonMail with this link and I save a few bones, too.
So long and thanks for all the socks
SiteGround is famous for dress socks as conference swag. I do not wear suits often. If you see me in a suit, it is possible I have coordinated colors with a pair of SiteGround socks.
I’ll move one script updating Shopify inventory quantities by February, and then I’ll only have access to the slick interfaces inside SiteGround via a few clients.
This is the collection of all the WordPress memes I’ve created.
You Should Make Plugins
The West Coast Choppers meme is one of the greatest of all time. I made this for a presentation at the WordPress Lancaster meetup called How to Make a WordPress Plugin to help people get over the two biggest mental roadblocks to making their first plugin: “I don’t know PHP,” and “I don’t want to break my site.”
Is This a PHP File?
I made this for the same How to Make a WordPress Plugin presentation to help people understand that PHP start and end tags are what makes parts of a PHP file special, and there might be HTML or something else inside otherwise. This is slight meme abuse because the typical use of this image portrays our hero as naive.
But Her Editors
I made this to mock a sentence in Matt Mullenweg’s “New 5.0 Target Date” blog post that turned out to be false.
WordPress.com is Not WordPress
Matt Mullenweg used the wordpress.org blog to criticize one of his competitors. Which is the real post?
The | operator passes the results from wp site list to xargs. xargs can take the output from one command and send it to another command as parameters.
The -n1 flag to xargs processes each line of output from the site list command one at a time. -n2 would send two site URLs to the next command.
wp --url=% plugin activate hello.php is the command to which xargs is passing the site URLs. It activates the Hello Dolly plugin on each site specified by URL. The % sign is our replacement character where each URL will populate.
My free plugin, HEIC Support, just crossed 3,000 active installs.
Does my copy-or-replace switch remain a useful feature? Do I get obsoleted out of the .org plugin repo on November 12th? Does it shrivel and die quietly? I have no idea. I can’t wait to find out.
I’m not even an iOS user. I’ve never had any .heic images to convert! I wrote the plugin because @austinginder told me WordPress doesn’t accept iPhone photos at a meetup.
The path to the php.ini file my Laravel Valet uses is /opt/homebrew/etc/php/8.1/php.ini
In order to see changes in phpInfo() calls, the valet restart command is not good enough. I must use the command brew services restart [email protected]
Submit a second language translation to each plugin you list on wordpress.org.
Why?
Once a plugin has a translation, the “Languages:” section appears with a link “Translate into your language.” This link helps strangers using your plugin submit more translations. Plugins with one language do not have this link on their .org directory pages.
If you speak only English like me, you can likely produce an English (UK) translation of your plugin to provide a second language for your plugin.
I also hired a translator
I met someone on twitter who charges four cents per word for English to Spanish translation. WordPress recognizes 14 Spanish language variants. My translator said they would prepare a LATAM (Latin American) Spanish that would also work for other variants. I submitted the translation I bought for all variants, but one or two versions have been approved after 6 months. Many uploaded translation files sit behind tens of thousands of other contributions in queues waiting for review. The WordPress project is in dire need of translation volunteers.
Open the file in VS Code, and populate all translated strings with the untranslated strings using regex find replace Find: msgid “([^”]+)”\nmsgstr “” Replace: msgid “$1″\nmsgstr “$1”
Make these replacements manually on the “msgstr” lines:
Color > Colour
Zip, Zip Code > Postcode
Customizer > Customiser
Check > Cheque (if referring to a paper form of payment, not “check this out”)
Make sure the .po file is valid with msgcat {filename}
Import the file on the same page where you got the Export using the Import link.
Wait for someone to approve the translations you’ve submitted (<24 hours, 6 months, or longer depending on the language)
Get word count from .po file
I found this tool helpful when pricing projects with a translator.
Call wp_set_script_translations() for each of your script files on the admin_enqueue_scripts hook priority 1000
Run the wp-cli command wp i18n make-json languages/
Navigate to Settings > General > Site Language and select from the list of available languages the one you’d like to test.
Where to get feedback about translation compatibility and imports
In the core WordPress slack, there are two channels filled with automated messages about plugin translations. Search for your plugin slug in the Making WordPress slack and look for results in these channels:
#polyglots-warnings logs translation warnings generated on translate.wordpress.org when .po files are imported.
#meta-language-packs logs language pack notices as plugins are updated.
These channels will tell you if your plugin is not yet compatible with language packs and if anomalies were found while comparing translations.
Sample messages
I found both of these messages to be helpful when working on translations.
Plugin is not compatible with language packs: Requires WordPress 4.0; wrong text domain in header
Warning: Lengths of source and translation differ too much.
Why aren’t submitted translations showing up in the plugin directory?
One of the most surprising things I learned while visiting Italy was pizzas are not sliced. I looked around the restaurant we chose for our first dinner and saw everyone sawing through pizza with butter knives!
Photos of unsliced pizzas
The reason for this silliness is to prevent the pizza from cooling down. Italians bring food to the table as soon as it is ready, and do not hold dishes under a lamp so they can be served all at the same time.
We learned the cheat code
If you say the pizza is to share, they slice it! It’s not as if they do not have pizza slicers in the back. They do, and they’ll use them if you say every pizza will be shared among the table.
Before we learned the workaround, I bought and carried small scissors to restaurants. Here’s a photo that I’ve been told is very embarrassing to people who love me. Cutting pizza with a butter knife is embarrassing!
This post is part of a series I wrote at the end of a 16-day trip to Italy in June 2024. Find all the posts about my trip here.
I found Forminator, a form builder plugin that allows multi-page forms to be built for free.
I don’t always want to activate my Gravity Forms license
I have licenses to a couple form builders that provide multi-page functionality. Almost every project is Gravity Forms and ACF, though. It’s nice to learn about other systems.
Forminator provides slider controls to specify numbers or a range of numbers, for example. This feature is unavailable with any paid level of Gravity Forms.
I bought bidet attachments for my toilets during the pandemic. Not because there was a paper shortage, but because the reviews were great.
I went to Europe and used a few standalone, European bidets. I was not impressed. They required me to use more paper than I would with no bidet! You have to get up and move from one seat to another. Surprisingly, the $110 Tushy toilet seat attachment I’m using now is better than anything I saw in Italy. The United States truly is the greatest country in the world.
I was traveling with some non-bidet users, so I found instructions to help us where the first two steps are “1. Use the toilet” and “2. Locate and sit on the bidet.” https://toiletseek.com/stand-alone-bidet-how-use-pros-cons/
You want me to get up and move? No thanks.
This post is part of a series I wrote at the end of a 16-day trip to Italy in June 2024. Find all the posts about my trip here.
My phone provider is Ting. Ting is an MVNO, which is a cellular service reseller. They offer pay-as-you-go services on Verizon and T-Mobile. I live and work on wifi most days, so by not paying Verizon directly for unlimited minutes, texts, and data, I save money. My phone bill is usually less than $50 a month. Sometimes it’s less than 40.
Phone service is important, especially when traveling. I have a Verizon SIM in a Google Pixel 5, and Ting support told me this SIM card would not work at all in Italy.
Ting is willing to send customers SIMs to switch between Verizon and T-Mobile, but using a T-Mobile SIM in Italy would incur international roaming charges. It was recommended that I obtain a SIM from an Italian provider after I arrived.
After landing at the Milan Airport/MXP, I found a kiosk with signs in English that said “get your SIM card here”. I paid $56 with a Visa card for a SIM card from Wind Tre. It provided 70 gigs of data, and 300 minutes. No texts. After changing to the Wind Tre SIM, my phone obtained a local Italian phone number. There was a 30 minute delay between the time the SIM was inserted and when I received some welcome text messages. Wind Tre offers an app that allowed me to monitor my data usage, and I only used 3 gigs during a 16 day trip. All of the places we stayed offered wifi.
Screenshot of Settings > Network & Internet > SIMs > WINDTRE on a Google Pixel 5
Messaging apps on my phone like Signal and WhatsApp worked uninterrupted during and after using the European SIM card.
When I put my Ting SIM card back in the device at the end of the trip, I received every text message I had missed all at once. I had to reboot my phone twice before I could place an outgoing call.
Make sure services you plan to use during the trip that have two-factor authentication enabled are not using text messages to authenticate. You will not get these text messages if your phone number changes. Before swapping SIMs, change logins to these services to use an authentication app instead of texts.
This post is part of a series I wrote at the end of a 16-day trip to Italy in June 2024. Find all the posts about my trip here.