Aubrey Portwood
Senior WordPress Developer, Stoic, Girl-Dad², Tennis Player, INTJ,
Enneagram 1, & Vintage Computer Tinkerer — based in Albuquerque, NM.

Posts

How I use Apple Dictation and AI for better written communication

TLDR; I speak, AI writes.

There’s a new way AI has been helping me be more productive. I’m known as the “screencast guy” at work because I record a lot of my updates. To be honest, I’m not particularly skilled at crafting written content. I tend to work quickly, so quick screencasts have become my style. So I prefer to recording a screencast and using my voice and mouse to explain things quickly. But in the world I work in written content is super important. So, I’ve been using AI to help me overcome this problem.

It’s been quite simple. I even used it to write this post. I simply start Apple Dictation on my Mac and speak what I want to say.

Start Dictation option on macOS.

The textual output isn’t always amazing (as you will see below), but with the addition of Apple Intelligence, I can select that text and ask it to rewrite it. Usually, it makes it far more coherent written version. Of course, I’ll read it and make a few minor edits and additions here and there, but beyond that, that’s how I create written content most of the time now.

Rewrite option in macOS Writing Tools.
Rewrite option in macOS Writing Tools.

Sometimes, I’ll take that content and use it in something more complex, like ChatGPT Canvas, and really let it go to work on it and create something more of a masterpiece. At work, I’ll also take the screencasts I usually do and give them to an app called Aiko, an app that converts video to a transcript. Then, I’ll either hand that transcript to Apple Intelligence—usually ChatGPT—to make it into a written form.

This has significantly simplified my life because I usually spend a considerable amount of time editing written content or writing content that I usually spend a lot of time on. What I write can sometimes be hard for others to understand because I’m just not great at writing, I tend to be repetitive, and over-explain things. But this has been a big game changer for all that. I’m one of those people who isn’t really into the whole AI hype still. I think AI is an amazing tool, but it’s not taking our jobs. It’s not coding for us. But, it can do things like this that really make you more productive. 

The original text from Apple Dictation:

“No, I’m not going to give you a giant list, not that kind of post. But, there has been a new way that AI has really been helping me be more productive. At work I’m known as the screencast guy, I record them all the time. Truth be told I’m not very good at creating well written content I would rather just record what I’m doing and use my voice to explain something so I’ve been using AI to sort of get around this problem and how I’ve been doing. It has been pretty simple I’m even using it to write this post. I simply start Apple dictation on my Mac and I speak what I wanna say now the textual output from that isn’t the most amazing thing, but with the addition of intelligence, I am able to then go select that text and ask it to do a rewrite, which usually makes it somewhat coherent. Of course read it and do a couple little edits here and there, but beyond that that’s kind of how I do written content now sometimes I’ll take that content into something a little more complex like ChatGPT canvas, and really go to work at it and create some kind of masterpiece usually at work sometimes I’ll take the screen cast that I will normally do and give it to AIKO an app that will convert video to a transcript and then hand that transcript either to Apple Intelligence or usually ChatGPT to make it make more sense this is made my life a lot easier because spending a lot of time editing, written content or writing written content to something that I struggle with often what I write is sometimes hard to understand for other people simply because I’m not great at writing, but this has been a big game changer for me. I am one of those guys that is not into the whole AI hype. I think AI is an amazing tool and it’s just that it’s not taking our jobs. It’s not coding for us, but he can do things like this that really make you more productive.”

First snow…

Summer this year was long, fall was short, and the snow is already here…

Hello Wolrd

I can’t remember the first blog post I ever wrote, but I do remember mis-spelling the title of that blog as Hello Wolrd and I left it that way. I always do this, I start a blog and I write the first post in it and I make excuses about how I need to re-start blogging and writing and ruminate about all the blogs I have had in the past and that this blog is going to be the one to rule them all.

This is another one of those posts!

Why?

I am turning 40 for the 2nd time Friday, and I don’t know if it’s because I’m getting older, but I’m getting really tired of the content on social media. I tend to have small things to say and I usually post on social media when I want to say it. A month ago I decided to get off social media for the rest of the year, and I’m even considering getting off it forever (or at least for a long time). But I still have things to say! Not much, but a few things. I also have said a lot in the past on all these various blogs and I do intend to port them over and back-date them to this site. Hopefully it becomes a place I can share what I think outside of social media, which has just become crazy these days. TBH the real reason I’m off social media is reels the doom-scrolling black holes of this feature of most social media really is the worst thing about social media. But, I digress…

An Update

Again, I can’t remember that last post I wrote but I currently work at AwesomeMotive after 7 years at WebDevStudios. I left WDS because I wanted to change the kind of work I was doing. They were a great company to work for and I often miss things about working at WDS. But I wanted to work on a single product or plugin, and that’s what I get to do everyday working on AffiliateWP.

What else? I’m living in Albuquerque, NM now. I lived in Phoenix for about 10 or so years and we moved back to New Mexico (grew up in Roswell, NM) to be closer to family and for our kids to enjoy time with their grandparents and great-grandparents. We moved here as a bit of an experiment, but it’s turned out to be a place we really love to live and watch our kids grow. So we’ll likely be here for a while.

Balloon Fiesta 2024
Balloon Fiesta — 2024

Living in ABQ has really improved my involvement with the Tennis Community here. I’ve won a couple tournaments here and I really enjoy the people that make up this community. Every weekend just-about I’m playing Tennis!

Ashley & Aubrey (Tennis)
Ashley & Aubrey — Sets in the City 2024

Trying out Webkit

So last night I decided I was going to try using Safari/Webkit DevTools. I asked myself: What is Firefox Developer Edition/Chrome DevTools giving me that Safari DevTools isn’t? I thought I’d try it out for a couple of weeks… I also asked myself the same thing about iTerm2, so I also decided to try out the basic macOS Terminal application.

Of course, I’m a stickler for UI consistency. It took some time for me to get Visual Studio Code to resemble WebKit DevTools, but I must say, I really like it!

Update: August 5, 2024 – I’ve switched back to iTerm as my Terminal. The reason? Panes. I simply didn’t like how Terminal.app handled panes, and I had a few instances where I wanted to use them. For example, I was using a command to transcribe some audio to text using Whisper, but I also needed to monitor htop because it was significantly impacting my CPU usage. I required a pane… unless I had a specific need. So, my philosophy has been to ask myself if a native macOS application provides what I require. As soon as I discover that a native app doesn’t offer what I need, I’ll consider alternatives. For instance, Raycast turned out that I only utilized 3% of its features. Since I switched to Spotlight, it has been more than sufficient.

Update: July 15, 2024 – I’ve also abandoned Raycast. I once again questioned whether I genuinely use it. In reality, I don’t think I do. I could, of course, but in truth, I only use about 10% of its features. Therefore, I disabled it (I’ll still utilize the AI features I paid for). I installed a snippet and clipboard history tool, enabled Spotlight, and moved on.

Update: June 11, 2024 – So far, I’m still using the built-in macOS Terminal and WebKit. Terminal has occasionally behaved erratically, but I always load up the application I’m working on in iTerm, and it usually turns out that the issue also occurs in iTerm. However, there are a few things I’ve had to compromise on in iTerm. It allows you to remap right ⌘ to CTRL, but I can’t do that in Terminal. That’s okay with me; I’ve simply remapped alt-s in Micro and called it a day. I don’t use panes (although panes are a pain, haha), but I’ll use tabs. So far, that’s it… I’m still waiting for a gotcha.

Update: June 3, 2024 – I’ve also been moving all my to-do lists (yes, even for work) to Reminders and using Notes more frequently. I’m genuinely enjoying the feeling of having less… less apps, less organizing!

How I add an icon to the macOS Dock that just launches a URL in Safari

Using automator make an app that runs this applescript:

on run {input, parameters}
    set targetURL to "https://example.com" -- Replace with your desired URL

    tell application "Safari"
        activate
        set windowList to windows
        set windowFound to false

        repeat with currentWindow in windowList
            if (URL of current tab of currentWindow) contains targetURL then
                set index of currentWindow to 1 -- Bring the window to the front
                set windowFound to true
                exit repeat
            end if
        end repeat

        if not windowFound then
            -- No window with the URL found, create a new one
            make new document with properties {URL:targetURL}
        end if
    end tell

    return input
end run

Change the URL, and save it as an application, and add that application to the dock.

This will automatically detect a window you already have open with the URL and activate it instead.

How I figured out how to publish an Apple Note online

While I wait for the day Apple adds a publish note link to Apple Notes, I have been trying to figure out how to do it with a workaround. This is the best I have come up with without having to involve another blogging service.

It’s not perfect, but here’s how I did it:

I found a script by Bear (another notes app) that will export your Apple Notes as HTML. I used that (and some ChatGPT) to get it to only export notes in a Posts folder in my Notes app:

Yesterday

Here’s the script:

set exportFolder to (choose folder) as string
-- Function to delete all .html files in the chosen folder
on deleteHTMLFilesInFolder(folderPath)
    tell application "Finder"
        set htmlFiles to every file of folder folderPath whose name ends with ".html"
        repeat with htmlFile in htmlFiles
            delete htmlFile
        end repeat
    end tell
end deleteHTMLFilesInFolder

-- Simple text replacing
on replaceText(find, replace, subject)
    set prevTIDs to text item delimiters of AppleScript
    set text item delimiters of AppleScript to find
    set subject to text items of subject

    set text item delimiters of AppleScript to replace
    set subject to "" & subject
    set text item delimiters of AppleScript to prevTIDs

    return subject
end replaceText

-- Get an HTML file to save the note in.  We have to escape
-- the colons, or AppleScript gets upset.
on noteNameToFilePath(noteName)
    global exportFolder
    set strLength to the length of noteName

    if strLength > 250 then
        set noteName to text 1 thru 250 of noteName
    end if

    set fileName to (exportFolder & replaceText(":", "_", noteName) & ".html")
    return fileName
end noteNameToFilePath

-- Delete all existing HTML files in the chosen folder
deleteHTMLFilesInFolder(exportFolder)

tell application "Notes"
    -- Limit the export to the "Posts" folder
    repeat with theNote in notes in folder "Posts" of default account
        set noteLocked to password protected of theNote as boolean
        set modDate to modification date of theNote as date
        set creDate to creation date of theNote as date

        if not noteLocked then
            -- File name composed only by note title
            set fileName to (name of theNote as string)
            set filepath to noteNameToFilePath(fileName) of me
            set noteFile to open for access filepath with write permission
            set theText to body of theNote as string
            set theContainer to container of theNote

            -- Export the folder containing the notes as tag in bear
            -- The try-catch overcomes a 10.15.7 bug with some folders
            try
                if theContainer is not missing value then
                    set tag to name of theContainer
                    set theText to ("" & theText & "#" & tag & "#") as string
                end if
            end try

            write theText to noteFile as «class utf8»
            close access noteFile

            tell application "Finder"
                set modification date of file (filepath) to modDate
            end tell
        end if

    end repeat
end tell

I saved this as an automator application that I can run anytime I want. Here’s a ZIP of that application. When you run it, it will export any notes in the Posts folder in Notes.app into a folder you choose.

CleanShot 2024-06-01 at 21.25.43@2x

This script will:

  • Export notes from a folder called Posts
  • Delete all *.html files in the folder you choose (in case you deleted anything)
  • Export all note into a .html file named with the title of the note

I then used shfs/MacFuse to mount an STFP folder on my mac:

How I figured out how to publish an Apple Note online.html

CleanShot 2024-06-01 at 21.20.52@2x

So, when I use the exporting app to select this folder, the new files will be uploaded via SFTP to a server automatically.

I then wrote a simple PHP script to list out the HTML files (stored in ./html/) and output the HTML when you select one, here’s that script (index.php):

<?php

$post = $_GET['post'] ?? '';

if ( ! empty( $post ) ) {
    show_post( $post );
} else {
    show_posts();
}

function get_base_post( $file ) {
    return basename( str_replace( '.html', '', $file ) );
}

function get_post_files() {

    // Notice if your site is notes.aubreypwd.com, mount the ./html folder on your Mac to export to.
    $files = glob( __DIR__ . '/html/*.html' );

    $sorted_files = array();

    foreach ( $files as $file ) {
        $sorted_files[ filemtime( $file ) ] = $file;
    }

    ksort( $sorted_files );

    return $sorted_files;
}

function show_posts() {

    ?>

    <?php the_header( 'Posts' ); ?>

    <div class="posts">
        <ul class="post-list">

                <?php foreach ( get_post_files() as $date => $file ) : ?>

                    <li>
                        <a href="?post=<?php echo get_base_post( $file ); ?>"><?php echo get_base_post( $file ); ?></a><br>
                        <small><span class="date"><date><?php echo date( 'm/d/Y', $date ); ?></date></span></small>
                    </li>

                <?php endforeach; ?>

            </ul>
    </div>

    <?php footer(); ?>

    <?php
}

function the_header( $title ) {
    ?>

    <!DOCTYPE html>
        <html lang="en"  data-theme="light">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">

            <title><?php echo $title; ?></title>

            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">

            <meta name="color-scheme" content="light dark" />

            <link
                rel="stylesheet"
                href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.blue.min.css"
            />

            <style>

                body {
                    /* zoom: 90%; */
                }

                .site-title a {
                    text-decoration: none;
                    color: black;;
                }

                .site-title {
                    font-size: 80%;
                    border-bottom: 1px solid #dadada;
                    padding-bottom: 30px;
                    padding-top: 30px;
                }

                .post-date {
                    margin-top: 30px;
                    padding-top: 30px;
                    border-top: 1px solid #dadada;
                }

                code {
                    display:block;
                    padding-left: 20px;
                    background: none;
                }

                .post h1.post-title {
                    margin-top: 20px;
                }

                .post > div {
                    margin-bottom: var(--pico-typography-spacing-vertical);
                }

                img {
                    border-radius: 3px;
                }

                .post-list {
                    padding-left: 0;
                }

                .post-list li {
                    list-style: none;
                    padding-bottom: 5px;
                }

            </style>

        </head>
        <body>

        <main  class="container">

            <header><h1 class="site-title"><a href="../">👨🏻‍💻 Aubrey's Notes</a></h1></header>

    <?php
}

function footer() {
    ?>


        </main>
        </body>
    </html>

    <?php
}

function get_post_filename( $post ) {
    return __DIR__ . '/html/' . "{$post}.html";
}

function show_post( $post ) {

    if ( ! file_exists( get_post_filename( $post ) ) ) {

        show_posts();
        return;
    }

    ob_start();

    ?>

            <?php the_header( $post ); ?>

            <div class="post">

                <?php

                echo str_replace(
                    array(
                        '#Posts#',
                        '<div><tt',
                        '</tt></div',
                        "\t",
                        '<div><br></div>',
                    ),
                    array(
                        '',
                        '<code',
                        '</code',
                        '&nbsp;&nbsp;',
                        '',
                    ),
                    file_get_contents( get_post_filename( $post ) )
                );

                ?>

                <p class="post-date">
                    <strong>Posted on: </strong>
                    <date><?php echo date( 'm/d/Y', filemtime( get_post_filename( $post ) ) ); ?></date>
                </p>

            </div>

            <?php footer(); ?>

    <?php

    echo ob_get_clean();
}

It was dead-simple, but it worked! But now I can basically update any post in my Posts folder, run that export script, and just wait for a simple site to update!

CleanShot 2024-06-01 at 21.44.44@2x

As you can see, the images come out in base64, so there’s no files to manage (I’m fine with that for now).

But…

I wasn’t super happy with the solution, but wanted to share just in case it might be enough for someone else.

I left it up on notes.aubreypwd.com →

👋🏻 Valet

After about three months of using LocalWP I switched back to Laravel Valet yesterday. LocalWP just made my workflow a bit tedious:

The Site Shell works, but I just wish wp worked in the site folder.

Turns out creating a site for each context (at work) resulted in about 20 sites being created this quarter. This turned out to feel really inefficient.

Blueprints turned out to be hard to maintain. Not that it’s super hard, but it became a nuncance to update them and prune old ones.

Don’t get me wrong, LocalWP is great. Totally. But here’s what I’m doing now:

I have one site in Valet for my work (affiliatewp-dev) and it’s setup just the way I like it. One WordPress install. One setup. No blueprints.

The repo I work on, mostly, is symlinked in my ~/Repos folder (I use ghq to manage repos). Now, I just have one repo… all my work… one place.

To “switch” between cases I just use a command that uses wp to export the DB and re-setup WP at a blank slate. I can switch back and forth through databases using a command I setup called wpdbs. It just exports the DB and imports the other by name. I can switch contexts this way much easier with one WP install and one repo cloned… and of course switch branches at will.

This was my old setup, and it turned out to feel more intuitive and easier to work with. I thought LocalWP would make development feel easier, but it didn’t.

If you’re curious about wpdbs checkout my dotfiles.

CMD+P & VSCode

What am I missing about VSCode? I don’t get why it’s so popular… I can’t even get it to go to a file in the directory tree using CMD+P?

VSCode even has its own tag on DEV!

💻 🚫

So I took down my external monitor.

About three months ago I hooked up my 27″ monitor, a bluetooth keyboard, some book-shelf speakers and was pretty happy… until I wasn’t… today.

The monitor is showing some signs of ghosting, and everyone once in a while it flickers. I really didn’t want the Apple Magic Keyboard (external) because of the janky arrow keys, so I bought what I thought was the best BT keyboard I could find. It takes 2.5 seconds to re-connect, it often “fights” with whatever signal my Magic Mouse was using, jets out some random characters, and finally connects. It doesn’t have touch-id so I have been manually typing my super-hard password everyday! I mis-type it about half the time. I had to use the bookshelf speakers remote control to switch it to Bluetooth before my computer would connect to it, so I also bought a dock and wired it, but I still had to turn them on….

I think you get the point. It just never works out for me when I try to do this… An external monitor is nice, but the setup always comes with some price I have to pay.

My MacBook Air has a screen and a keyboard ATTACHED to it, and it works…all the time!

So, I took all that shit down and am just back on my 💻

…again.

It always feels weird going from this big-ass screen to this tiny 13″ one. My desk always feels a bit empty and barren too…it’s always nice to have your desk full of big tech 💪🏻! But, it just isn’t meant to be.

I missed ⌨️👈🏻 Touch ID so much.

How to disable the Lock key on a non-Mac Bluetooth Keyboard

I have been searching the Internet for the answer to this, and it turned out to be quite simple.

You don’t need Karabiner-Elements, just run:

defaults write com.apple.loginwindow DisableScreenLockImmediate -bool yes

That disabled the stupid Lock key above the Delete key! I hit this thing all the time, and I have a really complicated password!