Skip to content

Instantly share code, notes, and snippets.

View KevinBatdorf's full-sized avatar
⚔️
I am undefined

Kevin Batdorf KevinBatdorf

⚔️
I am undefined
View GitHub Profile
@KevinBatdorf
KevinBatdorf / router.php
Last active December 26, 2025 12:01
A simple router for WordPress REST API - Laravel-like
<?php
defined( 'ABSPATH' ) or die;
namespace Kevin;
class Router extends \WP_REST_Controller
{
protected static $instance = null;
public function getHandler($namespace, $endpoint, $callback) {
\register_rest_route(
export const isValidJson = (str) => {
try {
JSON.parse(str)
return true
} catch (e) {
return false
}
}
@KevinBatdorf
KevinBatdorf / uploadImage.ts
Last active December 26, 2025 12:01
Upload an image to the WordPress media library using the ImageData JavaScript object type
import apiFetch from '@wordpress/api-fetch'
// This is also set up to clone fields from an existing image.
// Just remove imageToClone and supply the missing fields on your own.
export const uploadImage = async (image: ImageData, imageToClone: WpImage): Promise<WpImage | undefined> => {
const canvas = document.createElement('canvas')
canvas.width = image.width
canvas.height = image.height
const ctx = canvas.getContext('2d')
if (!ctx) return
@KevinBatdorf
KevinBatdorf / gutenberg-helpers.js
Last active July 13, 2025 09:43
WordPress check Gutenberg editor is ready
import { select, subscribe } from '@wordpress/data'
export function whenEditorIsReady() {
return new Promise((resolve) => {
const unsubscribe = subscribe(() => {
// This will trigger after the initial render blocking, before the window load event
// This seems currently more reliable than using __unstableIsEditorReady
if (select('core/editor').isCleanNewPost() || select('core/block-editor').getBlockCount() > 0) {
unsubscribe()
resolve()
@KevinBatdorf
KevinBatdorf / code-block-pro-plugin.js
Created October 22, 2023 01:33
Code Block Pro plugin - Sidebar panels
import { registerPlugin } from '@wordpress/plugins';
import {
PanelBody,
BaseControl,
createSlotFill,
Button,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
// CodeBlockPro.Sidebar.Start
@KevinBatdorf
KevinBatdorf / add-alpine-js-to-tailwind-ui.js
Last active October 23, 2024 09:21
Auto copy the Alpine code from Tailwind UI's copy button
// ==UserScript==
// @name Add AlpineJs to Tailwind UI
// @namespace http://tampermonkey.net/
// @version 3.0
// @description Add Alpine JS code to Tailwind Ui copy/paste
// @author https://gist.github.com/KevinBatdorf/8bd5f808fff6a59e100dfa08a7431822
// @match https://tailwindui.com/components/*
// @grant none
// ==/UserScript==
@KevinBatdorf
KevinBatdorf / sse.js
Last active August 22, 2024 08:42
useStreaming hook and Server Sent Svents (SSE) basic parser
const parseEvent = (eventData) => {
const lines = eventData.split('\n');
const eventType = (
lines.find((line) => line.startsWith('event:')) || 'event:message'
)
.slice(6)
.trim();
const eventDataExtracted = lines
.filter((line) => line.startsWith('data:'))
.map((line) => line.slice(5).trim())
@KevinBatdorf
KevinBatdorf / custom.css
Last active August 7, 2024 07:11
VS Code settings 2024
/* Code canvas top shadow */
.monaco-editor .scroll-decoration {
box-shadow: 0px 0px 20px rgba(0, 0, 0, .75) !important;
top: -6px !important;
}
/* Side bar */
.part.sidebar {
box-shadow: 0px 0px 50px rgba(0, 0, 0, .25);
}
.part.sidebar .title-label,
@KevinBatdorf
KevinBatdorf / check-steam-owned-games-on-humble-bundle.js
Last active April 23, 2024 12:52
Check on HumbleBundle whether you own the game on Steam already
// ==UserScript==
// @name Steam Owned HumbleBundle Games
// @namespace kevinbatdorf
// @version 0.1
// @description Will check whether you own the humble bundle game in your steam library already
// @author You
// @match https://www.humblebundle.com/*
// @icon https://www.google.com/s2/favicons?domain=humblebundle.com
// @grant none
// ==/UserScript==
@KevinBatdorf
KevinBatdorf / deleteRedditComments.js
Last active March 18, 2024 18:50
While on the comments page, put this in the console. May need to refresh a few times depending on how many you have
// Go to the old.reddit.com site
for (const dltbtn of document.querySelectorAll('[data-event-action="delete"]')) {
dltbtn.click();
await new Promise(requestAnimationFrame);
dltbtn.closest('form')?.querySelector('.yes')?.click()
await new Promise(r => setTimeout(r, 300));
}
// No longer works
// for (const dotdotdot of document.querySelectorAll('[aria-label*=more ]')) {