• Tech Tips

    You Can’t Fit a Square Title into a Round Url

    For whatever reason I always mix up the format for markdown links.

    Here are the possibilities (only one is valid):

    1. [https://agileadam.com](View my site)
    2. [View my site](https://agileadam.com)  ← the correct one!
    3. (https://agileadam.com)[View my site]
    4. (View my site)[https://agileadam.com]

    I’ve come up with a mnemonic I’m going to try employing:

    You can’t fit a square title into a round url.

    It’s a variation of the idiom, “You can’t fit a square peg into a round hole.”

    Square brackets. Round parentheses. You get it.

    Update July 12, 2024

    This still isn’t landing for me. “Can’t fit a square peg into a round hole” is easy to remember… but which is the peg and which is the hole? Square URL? Square Title? Round Title? Hmmm.

    Maybe an acronym would serve me better? Here are my initial thoughts:

    • “SLAP” (Square Label, Address in Parentheses)
    • “SNAP” (Square Name, Address in Parentheses)
    • “SLAP” (Square Label, Address in Parentheses)

    If you take a closer look, it’d be easy to accidentally assume “L” means “link” (aka URL), so maybe I should rule those out. That leaves me with “SNAP”, which seems like it’d be worth trying for awhile.

    I wish I knew what drives me to go down these rabbit holes.

  • Development

    Writing Tests for Drush Commands

    There are plenty of examples of these in the wild, but I figured I’d show a stripped down version of an automated Kernel test that successfully tests a drush command. The trick here is making sure you set up a logger and that you stub a few methods (if you happen to use $this->logger()  and dt()  in your Drush commands). Also featured in this example is the use of Faker to generate realistic test data.

    I learned this via the migrate_tools project here.

  • Development

    Using Data Providers in PHPUnit Tests

    This is the before code, where a single test is run, and each scenario I’m testing could be influenced by the previous scenario (not a good thing, unless that was my goal, which it was not).

    This is the after code, where three tests are run. Unfortunately this takes 3x longer to execute. The upside is that each scenario cannot affect the others and it’s perhaps more readable and easier to add additional scenarios.

     

  • Tech Tips

    Showing Salesforce RecordId in the Contact List

    I have a table of contacts in Salesforce. To my surprise you cannot choose to show the RecordId (e.g., 0036g00002d4BOHAAU) in the field configuration. I did some digging and it seems it’s not possible without using some workaround that requires a calculated field or similar. I just needed the IDs for a one-time use. I realized the ID is included in the linked fields but didn’t want to have to hover each of the “Name” and “Account Name” links to see the IDs. So, I whipped up some javascript to simply append the RecordId to the end of these links. I can run the javascript via console, or even add it to a user script or place it automatically with a code injector extension.

    Contact list without ID
    BEFORE

     

    Contact list with ID
    AFTER
  • Development

    Skip Empty Values During Concatenation in a Drupal 10 Migration

    UPDATE. You can do the same as below without the need for a custom module function. (source)


    This quick example shows one method to ignore empty values in a Drupal 10 migration concatenate process.

    Code

    Migrate code:

    Module code:

    Result

    Example data:

    Resulting field_address_full plain text value

     

  • Development,  Tech Tips

    Using lnav to View Live DDEV Logs

    https://lnav.org/ is a fantastic tool to work with log files. The SQL query functionality is a lot like https://github.com/multiprocessio/dsq, which also impresses.

    My quick tip is that lnav can read from stdin. This means you can pipe content into it. Here’s how I monitor my ddev environment in realtime. Hooray for colors!

    If you haven’t explored lnav you’ll want to dive into the documentation a bit. It does a lot more than just give pretty colors to your log files / output. https://docs.lnav.org/en/v0.11.2/hotkeys.html is certainly worth bookmarking.

  • Development

    Rendering null boolean values with Grid4PHP

    I’m a big fan of Grid4PHP for adding a quick CRUD user interface to a MySQL database.

    I have a lot of boolean columns, like “is_telehealth” that need to start as NULL until we make a determination about the field’s value. Grid4PHP renders null booleans as “0” in the table/edit form. This is misleading, given it’s not actually a 0 value. If you add the ‘isnull’ attribute to the column it lets you save the null value, but it still renders as a “0”.

    Using a custom formatter I was able to render an empty string (nothing) instead of “0” for these null booleans:

  • Development

    Drupal Migrate API skip_on_multiple Process Plugin

    Here’s a Migrate API process plugin I wrote in Drupal 9 that skips a property or row when more than one value exists. My use case:

    1. My source data has locations; each location has multiple associated organizations
    2. My new Drupal site has locations; each location has a parent organization
    3. I want to only populate the field_parent_org field (an entity reference) if there is a single organization value in the source data for the location
    4. I’m using a custom module called “pdms_migrate”

    I’ve stripped out all of the noise from the examples below… hopefully it’s enough to help you understand the example:

  • Tech Tips

    Quick Search Results using Raycast and DDGR

    This is more or less a proof of concept. I wanted a fast way to look up facts without navigating away from what I’m working on.

    Using Raycast is a natural place to start given you can pull it up and make it go away with ease. I looked for extensions in the Raycast Store (they’re free, despite the name) that might help but nothing seemed to do what I wanted. The Wikipedia extension does a great job of pulling information but it’s not as useful if I want a quick fact like “zip code for Portland Maine”.

    Next I began looking for command line tools that return web search results. Googler came up as a top choice but the project has been archived. ddgr was the next one I came across; it works beautifully to return DuckDuckGo search results as JSON. I installed it with homebrew ( brew install ddgr ).

    Finally, I whipped up a quick Raycast script command that would accept an argument, use ddgr to get the top search results, then spit them out in the Raycast output window. Raycast scrolls to the bottom of the output automatically, so I reversed the order of the top 10 results so that the most relevant appears at the bottom. That’s it!

    There isn’t any graceful error handling, automated test coverage, etc. Use it at your own risk. 😉

    Initial screen of RaycastSearching for Who is Derek Trucks?Search results

  • Development,  Tech Tips

    Handling Daylight Saving Time in Cron Jobs

    • Our business is located in Maine (same timezone as New York; we set clocks back one hour in the Fall and ahead one hour in the Spring)
    • Server A uses ET (automatically adjusts to UTC-4 in the summer, and UTC-5 in the winter)
    • Server B uses UTC (not affected by Daylight Saving Time) – we cannot control the timezone of this server

    We want to ensure both servers are always referencing, figuratively, the same clock on the wall in Maine.

    Here’s what we can do to make sure the timing of cron jobs on Server B (UTC) match the changing times of Server A (ET).

    Only one of the php artisan scrub-db  commands will execute, depending on the time of year.