I was hitting some context token size limits when I was telling Work to write code from a spec, and letting the LLM write the docs and spec. The code was working, but it was pretty big. So I decided to get into byte-miser mode and look for a solution.
This code was in PHP and running as WordPress plugins, so I thought this might help:
- removing a lot of whitespace, and going to 2-space tabs.
- creating a minimalist framework for shortcodes (and other frameworks for other things)
It was simple:
<?php
namespace RB\WpFw;
/**
* Base class for shortcodes. Subclasses override sc() and call reg().
*/
abstract class Shortcode {
static function reg($name) {
add_shortcode($name,[static::class,'sc']);
}
static function err($t,$code=null) { // error messages that appear instead of the normal output. code can be used in a switch to select error messages
return '<span style="color:red;">ERROR '.esc_html($t).' (<a href="https://riceball.com/" target="_blank" rel="noopener noreferrer">see link</a>)</span>';
}
abstract static function sc($a,$t); // shortcode atts text
}
A shortcode is basically a filtering function. To add a shortcode to WP, you use the add_shortcode() function.
To use this framework, you extend Shortcode, fill in the class with code for sc($a,$t), and then, from the plugin file, call MyClass::reg(‘the-shortcode’) to register it.
Here’s how a different shortcode was registered:
S\NetLookup::reg('netlookup');It’s really simple.
The code the LLM produced was… okay.
<?php /* vim: set ts=2 sw=2 tw=78 et : */
namespace RB\WpFw\Examples\Shortcode;
use RB\WpFw\Shortcode;
/**
* Fetch and cache data from the network using WP transients.
* Pattern: transient-first, fetch on miss, store with TTL.
*/
class NetLookup extends Shortcode {
const TRANSIENT_PREFIX = 'netlookup_';
const TTL_SECONDS = 3600; // HOUR_IN_SECONDS, inlined so the class loads standalone
private static $key='netlookup';
/* johnk - I added this because I didn't want to have a key attribute */
public static function reg($name) { parent::reg($name); }
public static function sc($a,$t) {
$key = self::$key;
$data = self::cached_or_fetch($key);
if ($data === null) {
return self::err('fetch failed for '.$key);
}
return esc_html(is_scalar($data) ? (string)$data : wp_json_encode($data));
}
/** Transient-first read; fetches remotely on a miss and caches the result. */
private static function cached_or_fetch(string $key): mixed {
$key = self::$key;
$transient = self::TRANSIENT_PREFIX . md5($key);
$hit = get_transient($transient);
if ($hit !== false) {
return $hit;
}
// In production this would be wp_remote_get against a real API.
$body =
wp_remote_retrieve_body(wp_remote_get(esc_url_raw('https://riceball.com/wp-content/uploads/sites/2/2026/08/test.csv')));
if ($body === '') {
return null;
}
set_transient($transient, $body, self::TTL_SECONDS);
return $body;
}
}
OK, it’s not horrible, but it didn’t work for me the first time, because I didn’t supply a value for the “key” attribute. I couldn’t tell what it was for, so I hacked it into existence. Then, it worked.
I want it to write tighter code.
Thaura Therapy
I wanted to reformat my PHP code to be more dense, and looked for a vim plugin to install. Oddly enough, it already seemed to be installed, but wasn’t running… because I was using NeoVim.
NeoVim uses the .config directory instead of .vimrc, and, to my surprise, didn’t have a config. So I started one, and found out that it uses Lua. That would be nice, if I remembered Lua.
So I started to wonder, “was Lua good for token misers?”
Thaura told me it was. Not only that, but when I compared it to Python and PHP, Lua came out ahead.
Then, I had to look into Lua speed. I never thought of it as fast, but now, with a JIT, it’s FAST. At least it’s faster than PHP and Python.
Not only that, but when it’s used in NGINX as part of a web app server, it can be faster than node.js. The product is called OpenResty.
For a more traditional web app framework, where the routing is in the code, you can use Lapis.
I hope Thaura wasn’t hallucinating.
How is Lua so fast?
https://www.lua.org/doc/cacm2018.pdf
JIT, and closures, tables, coroutines.