Blog

  • Parking near Pittsburgh International Airport

  • Revert Elementor Taking Over a Page

    Accidentally clicking the Edit with Elementor button can ruin a perfectly good page. Sabotage or delete post meta fields for the post or page with these keys:

    • _elementor_edit_mode
    • _elementor_template_type
    • _elementor_version
    • _elementor_css

    wp-cli commands

    Change the zero to an appropriate post or page ID.

    wp post meta delete 0 _elementor_edit_mode
    wp post meta delete 0 _elementor_template_type
    wp post meta delete 0 _elementor_version
    wp post meta delete 0 _elementor_css

  • TP-Link Deco Mesh Wifi Setup on Xfinity

    While trying to setup TP-Link Deco mesh wifi devices, I found that it was easy to plug one of the devices into my existing wifi router. The Deco creates its own wifi network, however, instead of boosting the signal where it was plugged in.

    Problem: Light Turned Red

    I tried to replace my router with the Deco, and I ran into a problem. The light turned red after creating the Wi-Fi name and password.

    Solution

    On Xfinity, the correct IPTV/VLAN settings are:

    • Turn on IPTV/VLAN
    • Connection type Dynamic IP
    • Mode Bridge

    Where to input these settings

    1. Open the Deco app
    2. Navigate to More -> Advanced -> IPTV/VLAN

    This helped me configure my TP-Link Deco Mesh W3600 devices, but may work for other wifi networks using Xfinity internet.

  • PLUGIN_CHECK_PHP_BIN constant

    The WordPress Plugin Review team released Plugin Check. They use it to scan all plugin submissions to wordpress.org, and encourage all authors to run it before uploading plugins to the directory.

    PLUGIN_CHECK_PHP_BIN Error Message

    One error asks us to create a constant:

    Cannot find the PHP Binary file, please define it using the `PLUGIN_CHECK_PHP_BIN` constant

    It’s asking for the path to PHP so it can scan plugin code. Here is some PHP code to create the constant with a sample value of “path/to/php”.

    if ( ! defined( 'PLUGIN_CHECK_PHP_BIN' ) ) {
    	define( 'PLUGIN_CHECK_PHP_BIN', 'path/to/php' );
    }

    How to Find the Path

    In your local environment or while logged into a remote server, use the whereis php command to reveal the path to the PHP binary. In this example from my computer, the path is not the only text output by the command:

    $ whereis php
    php: /opt/homebrew/opt/[email protected]/bin/php /opt/homebrew/share/man/man1/php.1
    

    Where to Run the Command

    If you’re on macOS, open Terminal, type or paste the whereis php command, and press Enter.

    Define the Constant in wp-config.php

    The path is very likely to end in bin/php. Here’s what I added to wp-config.php files running on my computer:

    if ( ! defined( 'PLUGIN_CHECK_PHP_BIN' ) ) {
    	define( 'PLUGIN_CHECK_PHP_BIN', '/opt/homebrew/opt/[email protected]/bin/php' );
    }

    Run the Plugin Check again. If you successfully created the constant with the correct path, your Plugin Check report may be a bit longer.

  • WordPress 6.3 Errors in Dashboard

    Sites running WordPress 6.3 and plugins that add the post__not_in query variable on the parse_query hook are breaking the lists of posts and pages in the Dashboard. I found this bug because I built and maintain a plugin that did exactly this.

    Example pages with errors after updating to WordPress 6.3

    • wp-admin/edit.php
    • wp-admin/edit.php?post_type=page
    • wp-admin/edit.php?post_type={custom_post_type}

    Why?

    The post__not_in query variable makes it easy for developers to hide posts and pages from dashboard users. The parse_query hook is one of the last hooks before the main query runs, and a handful of hide-page-tutorials recommend using it to exclude specific posts or pages from the query.

    How to Fix

    Follow this advice: Avoid post__not_in

    How to find out if a plugin is causing the errors

    Disable all plugins one at a time and check the broken pages. This is the way to troubleshoot almost every problem on a WordPress site. If you cannot deactivate all plugins for this plugin conflict test, create a duplicate copy of the site to use during the test.

  • Escaping and Translating Text in WordPress

    WordPress core provides developers with a handful of functions to escape string content and enable translations into other languages.

    Translatable Strings

    Access the translated version of text used in plugins or themes with one of the following functions.

    <?php
    echo __( 'Hello', 'text-domain' );
    _e( 'Hello', 'text-domain' );
    echo _x( 'Hello', 'The welcome message', 'text-domain' );

    The first, __(), returns the text.

    The “e” in _e() stands for echo. This function outputs the text.

    The “x” in _x() stands for context and accepts an argument to explain to translators the context of the text.

    Escape for HTML

    Escapes strings so they are not parsed as HTML. Characters like < are converted to &lt;.

    <?php
    echo esc_html( 'Hello' );
    echo esc_html__( 'Hello', 'text-domain' );
    esc_html_e( 'Hello', 'text-domain' );
    echo esc_html_x( 'Hello', 'The welcome message', 'text-domain' );

    Example

    <p><?php esc_html_e( 'Hi there! >:)', 'my-plugin' ); ?></p>

    The above code will render the following HTML:

    <p>Hi there! &gt;:)</p>

    Escape for HTML attributes

    Escape strings used in HTML attributes like class="" so they do not break the HTML.

    <?php
    echo esc_attr( 'Value' );
    echo esc_attr__( 'Value', 'text-domain' );
    esc_attr_e( 'Value', 'text-domain' ); // Outputs the value.
    echo esc_attr_x( 'Value', 'The control value', 'text-domain' );

    Example

    <p><input type="text" value="<?php esc_attr_e( 'Something seems "off"', 'my-plugin' ); ?>" /></p>

    The above code will render the following HTML:

    <p><input type="text" value="Something seems &quot;off&quot;" /></p>

    Escape a URL

    Escape strings inside href="" or src="" attributes.

    <?php
    echo esc_url( 'https://coreysalzano.com/' );

    Escape for textareas

    Prevents the text content of a <textarea> from closing the element early.

    <?php
    echo esc_textarea( 'WordPress core provides developers with a handful of functions to escape string content and enable translations into other languages.' );
  • Microsoft Azure SqlServer

    Check the status of CREATE DATABASE and ALTER DATABASE queries

    SELECT * FROM sys.dm_database_copies

    List all users and roles

    SELECT * FROM sys.database_principals
  • Akismet Alternatives

    Blocking spam on WordPress websites is heavy work. Akismet comes pre-installed on every site, but it’s not free for businesses or the only way to stop spam.

    1. OOPSpam https://www.oopspam.com/
    2. CleanTalk https://cleantalk.org/
    3. Stop Forum Spam https://www.stopforumspam.com/
    4. Project Honey Pot https://www.projecthoneypot.org/
    5. Zero Spam https://www.zerospam.org

    There are a ton of anti-spam WordPress plugins. The criteria for this list of alternatives is “offers an API.”

    Thanks to Austin and Kerch for inspiration and help creating this list.

  • TypeError: c is not a function

    If you’re building blocks for WordPress, and the error TypeError: c is not a function is logged in your browser’s developer console, you may have created a TextControl component and failed to include both value and onChange attributes.

    This code will cause the error:

    <TextControl
    	label={ __( 'Cash/trade', 'invp-payment-calculator' ) }
    	id={ 'trade' }
    	onChange={ changeTradeValue }
    </TextControl>

    This is a correct syntax:

    	label={ __( 'Cash/trade', 'invp-payment-calculator' ) }
    	id={ 'trade' }
    	value={ attributes.trade }
    	onChange={ changeTradeValue }
    </TextControl>
  • Gravity Forms confirmation not working. Instead, “Thanks for contacting us! We will get in touch with you shortly.”

    If you see the default “Thanks for contacting us! We will get in touch with you shortly.” even if you’ve created a custom confirmation for your Gravity Form, your entry may have been marked as spam.

    All entries deemed spam are shown the default message. Login and try again–logged in users will not get caught in the spam filter.

    Also, visit the Entries list in the dashboard, and look for the Spam folder. Your entry may have been saved with the other Spam.

    Where in the Gravity Forms source code does this happen?

    plugins/gravityforms/form_display.php line 3894

  • TypeError: b.map is not a function

    If you’re building blocks for WordPress, and the error TypeError: b.map is not a function is logged in your browser’s developer console, you may have created a SelectControl component and failed to wrap the options in brackets to create an array.

    This code will cause the error:

    			<SelectControl
    				label="Minimum Rating"
    				value={ attributes.minimumRating }
    				options={ 
    					{ label: 'Great Deal', value: 'GREAT_PRICE' },
    					{ label: 'Good Deal', value: 'GOOD_PRICE' },
    					{ label: 'Fair Deal', value: 'FAIR_PRICE' }
    				 }
    				onChange={ onChangeMinimumRating }
    			/>

    This is the correct syntax:

    			<SelectControl
    				label="Minimum Rating"
    				value={ attributes.minimumRating }
    				options={ [
    					{ label: 'Great Deal', value: 'GREAT_PRICE' },
    					{ label: 'Good Deal', value: 'GOOD_PRICE' },
    					{ label: 'Fair Deal', value: 'FAIR_PRICE' }
    				] }
    				onChange={ onChangeMinimumRating }
    			/>
  • Router Circle Jig Calculator

    Router Circle Jig Calculator

    I recently gifted myself a Bosch 1617EVSPK router, and the first project is mounting it to a old Craftsman 171.253512 router table that came with the used contractor table saw I bought myself for my 37th birthday.

    An adapter plate is needed. None of the threaded mounting holes on the fixed router base line up with holes in the table. A friend advised me to cut the plate out of metal or acrylic rather than wood. I may do that. First, I’m making a prototype out of 1/2 inch birch plywood.

    The challenge is that a hole is needed in the center to line up with the hole in the center of the router table. The hole is 2 and 7/8 inches. The first thing you learn when you get a router is that you need a guide for every cut. To cut a hole, you need a bigger hole, or circle jig, in which to run the tool.

    How Big of a Hole do I need to cut a Hole?

    What size circle jig is needed to cut a 2 and 7/8″ circle? Well, what size is the router base plate, and what size is the bit? The answer for me was 9 inches. I made a circle jig calculator spreadsheet to help you calculate your own answer: https://docs.google.com/spreadsheets/d/1j-HHztDr0gRN3G3gc9z6VhBRuo2sOvzG_dBccMmtVgg/edit?usp=sharing

    A screenshot of a calculator built in a Google Sheet

    Is this silly? Is there an easier way to do this? Please, let me know.