swipe to read
Crosspost to Inkwell — Technical Changelog (continued)
ΞVΞ🦋@eve@evecodes.com · 2d ago
evecodes.com03/16/26 — Bug Fixes
Timezone fix for Social Notes title fallback
- Social Notes crossposted to Inkwell were timestamped 4 hours behind the correct local time
- Root cause:
$post->post_dateis already converted to the site’s local timezone but stored as a plain string with no timezone info —strtotime()was interpreting it as UTC, thenwp_date()was converting it again, doubling the UTC offset - Fix: switched to
$post->post_date_gmt(true UTC) withUTCappended so PHP parses it unambiguously, thenwp_date()converts it to the site’s configured timezone in a single clean pass
00
March 15, 2026 10:10 PM
Added one new slight change. Hashtags in Jetpack Social notes will now post as native tags to Inkwell Social
#wordpress #plugin #crossposttoinkwell
10
Crosspost to Inkwell — Technical Changelog (continued)
ΞVΞ🦋@eve@evecodes.com · 2d ago
evecodes.com03/16/26 — Hashtag-to-Tag Extraction & Jetpack Social Notes Support
Hashtag extraction from post content
- New setting added: Hashtag Tags (enabled by default) under Settings → Entry Settings
- When enabled, the plugin scans the post body for
#hashtagpatterns and adds them to the Inkwell entry tags - HTML is stripped from content before scanning so hashtags inside
hrefattributes or HTML tags are not picked up - Only hashtags starting with a letter are matched — filters out numeric patterns like
#1or#2024 - Extracted hashtags go through the same sanitization pipeline as WP post tags: lowercased, underscores converted to hyphens, non-alphanumeric characters stripped
- Merged with existing WP post tags and deduplicated — if a hashtag in the content already exists as a WP post tag, it is only sent once
- Debug log records how many hashtags were extracted and lists them by name
- “What Gets Sent” sidebar updated to reflect the new tag source
Jetpack Social Notes support
jetpack-social-notepost type now explicitly checked viapost_type_exists()and injected into the Post Types checklist if Jetpack registers it as non-public or after the settings page renders- Hashtag extraction works identically on Social Notes — enable
jetpack-social-notein the Post Types setting and any#hashtagin a Social Note body will be sent as an Inkwell tag - Social Notes have no real title — Jetpack assigns a
#NuMb3rsplaceholder. The plugin now detects this pattern and substitutes a human-readable date/time string (e.g.March 16, 2026 1:24 AM) as the Inkwell entry title instead
00
Crosspost to Inkwell — Technical Changelog (continued)
ΞVΞ🦋@eve@evecodes.com · 2d ago
evecodes.com03/15/26 — 03/16/26 — Post-Submission Bug Fixes & New Features
03/15/26 — “Publishing failed” error with WordPress 6.9.4
- Root cause:
transition_post_statushook was making synchronous HTTP calls to the Inkwell API inside the Gutenberg REST API request, blocking the response and triggering a publish failure - Fix: detect
REST_REQUESTand defer crosspost execution usingwp_schedule_single_event+spawn_cron() - Follow-up: cron never fired on host due to blocked loopback HTTP requests — replaced with
shutdownaction hook ignore_user_abort(true)added to keep DB connections alive after response is sentfastcgi_finish_request()called when available so PHP-FPM flushes the response to the browser before the crosspost runs- Wrapped shutdown execution in
try/catch (\Throwable)to surface silent fatal errors - Fixed
add_transient()unavailable in shutdown context afterfastcgi_finish_request()— replaced transient lock with directget_post_meta()check andforce=truecall in shutdown path - Retained cron hook registration for any events already queued from previous version
03/15/26 — Debug Log page
- New admin page at
Settings → Crosspost to Inkwell → 🪲 Debug Log - Enable/disable toggle — off by default to avoid storing sensitive data unnecessarily
- Dark terminal-style log viewer, color-coded: green for success, red for errors, blue for outgoing requests, orange for API responses
- Refresh button (live AJAX reload) and Clear Log button with confirmation prompt
- Log stored in
wp_optionsunderinkwell_debug_log, capped at 200 entries - Debug Log link added to settings page header and plugin action links row
- 26 log points added throughout the crosspost flow:
- Cron/shutdown deferral and execution
- Crosspost start (post ID, force flag, post status)
- Transient lock and already-posted guard hits
- Every outgoing API request (method, URL, payload keys)
- Every API response (HTTP status code + first 600 chars of body)
- Image upload — file read, encode, upload, result
- Crosspost success with entry URL
- All error and skip paths
03/15/26 — Verify Key: reads live field value
inkwell_ajax_verify_keywas reading the API key only from savedwp_options, so clicking Verify Key before saving always returned “No API key entered”- Fix: JS now reads the current value of
#inkwell_api_keyand passes it in the AJAX request; PHP handler uses the submitted key if present, falls back to saved option
03/15/26 — API key field: show/hide eye toggle
- Added 👁 / 🔒 toggle button inline with the API key
<input type="password">field - Button switches field between
passwordandtexttype on click aria-labelupdates on toggle for screen reader accessibility- Typing in the key field clears the connected account status display so re-verification is obvious
03/16/26 — Persistent connected account display
- After a successful Verify Key, the connected account name and handle are now saved to
wp_optionsand displayed persistently on page load — no longer disappears on refresh connected_display_nameandconnected_usernameadded to plugin options defaults and sanitize callbackinkwell_ajax_verify_keyrefactored to make a single/api/mecall (previously called it twice — once ininkwell_verify_credentials()and once again to extract data), saving account info and building the response message from the same result- On verify failure, saved account info is cleared so stale data from a previous key is never shown
- Sanitize callback updated to pass through
connected_display_nameandconnected_usernamefrom$inputwhen present — previously always read from$existing(old DB value), silently overwriting the newly saved name on everyupdate_optioncall wp_kses()used instead ofsanitize_text_field()for display name to preserve emoji and Unicode characters (e.g.ΞVΞ🦋)- API key change (via settings save) clears connected account info so stale name from previous key is never displayed
00
1—4
Subscribe to #crossposttoinkwell entries via RSS feed