Skip to content

Instantly share code, notes, and snippets.

@ozh
Last active June 23, 2026 09:12
Show Gist options
  • Select an option

  • Save ozh/ff7c454ce3fa9ce8ffeaba07f8324caa to your computer and use it in GitHub Desktop.

Select an option

Save ozh/ff7c454ce3fa9ce8ffeaba07f8324caa to your computer and use it in GitHub Desktop.
Colon in YOURLS short URL
<?php
/**
* Plugin Name: Allow Colon in Short URLs
* Plugin URI: https://ozh.in/10i
* Description: Allow the colon ":" in short URLs (like <tt>http://sho.rt/foo:bar</tt>)
* Version: 1.0
* Author: Ozh
* Author URI: http://ozh.org/
*/
// No direct call
if( !defined( 'YOURLS_ABSPATH' ) ) die();
// Add the colon to the allowed short URL character set...
yourls_add_filter( 'get_shorturl_charset', 'ozh_colon_in_charset' );
function ozh_colon_in_charset( $charset ) {
return $charset . ':';
}
// ...unless we are crafting a random keyword, to keep auto-generated keywords colon-free
yourls_add_action( 'add_new_link_create_keyword', function() {
yourls_remove_filter( 'get_shorturl_charset', 'ozh_colon_in_charset' );
} );
// Don't let a keyword that contains a colon be mistaken for a URI scheme
yourls_add_filter( 'get_protocol', 'ozh_colon_get_protocol', 10, 2 );
function ozh_colon_get_protocol( $protocol, $url ) {
// Nothing was detected as a protocol: leave as is
if ( $protocol === '' ) {
return $protocol;
}
// A genuine "scheme://..." URL (eg a bookmarklet target): leave as is
if ( str_contains( $protocol, '/' ) ) {
return $protocol;
}
// Here $protocol is a bare "scheme:" with no slashes. If the whole candidate
// string consists only of valid short URL charset characters, it's one of our
// keywords (eg "foo:bar"), not a URL: don't treat the colon as a scheme.
$pattern = yourls_make_regexp_pattern( yourls_get_shorturl_charset() );
if ( ! preg_match( '@[^' . $pattern . ']@', $url ) ) {
return '';
}
return $protocol;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment