Extension:Scribunto/Example extension

This page may be used as a resource for people trying to extend Scribunto's library with their own extensions.

YourExtension/YourExtension.php edit

As with a conventional extension, this file is mostly boilerplate. I'm extracting a lot of information from the file name.

<?php

$ndExtensionName = basename( __FILE__, '.php' );
$ndExtensionLuaPath = __DIR__ . '/' . $ndExtensionName . '.lua';
$wgAutoloadClasses[$ndExtensionName] = __DIR__ . '/' . $ndExtensionName . '.body.php';
$wgExtensionMessagesFiles[$ndExtensionName] = __DIR__ . '/' . $ndExtensionName . '.i18n.php';
$wgHooks['ScribuntoExternalLibraries'][] = 'nd' . $ndExtensionName . 'Setup';

$wgExtensionCredits[$ndExtensionName][] = array(
	'path' => __FILE__,
	'name' => $ndExtensionName,
	'author' => 'A Concerned Citizen',
	'url' => 'https://www.mediawiki.org/wiki/Extension:' . $ndExtensionName,
	'description' => 'The ' . $ndExtensionName . ' library for Scribunto.',
	'version' => 0.0,
);

function ndScribuntoLuaSocketSetup( $engine, array &$extraLibraries ) {
	$extraLibraries['mw.ext.' . $GLOBALS['ndExtensionName']] = 'Scribunto_LuaSocketLibrary';
	return true;
}

YourExtension/YourExtension.body.php edit

The body file contains a rudimentary extension of the Scribunto_LuaLibraryBase class, which registers the interface for this library.

<?php

class Scribunto_LuaSocketLibrary extends Scribunto_LuaLibraryBase {
	public function register() {
		global $ndExtensionLuaPath;
		$this->getEngine()->registerInterface( $ndExtensionLuaPath, [], [] );
	}
}

YourExtension/i18n/en.json edit

{
	"scribuntoluasocket" => "ScribuntoLuaSocket",
	"scribuntoluasocket-desc" => "ScribuntoLuaSocket, an extension adding LuaSocket support to Scribunto."
}

YourExtension/YourExtension.lua edit

With an existing library edit

My particular scenario, which may not apply to anyone else, is that I wanted to use LuaSocket to allow fetching the raw content of certain pages and so forth. (This is a private wiki, so I'm not worried about the security implications.)

Of course, simply typing local socket = require 'socket' in a Module: page didn't work. So what to do? Write an extension, apparently.

In the attempt to figure out how the hell this is done, I've figured out the following, which, unfortunately, does not work (it says that 'socket' is not found. Providing absolute and relative paths does not seem to work either, presumably because of the restrictions on the extension's version of require.). I'm not sure if there's any way around this.

local ScribuntoLuaSocket = require 'socket'
local php

function ScribuntoLuaSocket.setupInterface( options )
	-- Remove setup function
	ScribuntoLuaSocket.setupInterface = nil

	-- Copy the PHP callbacks to a local variable, and remove the global
	php = mw_interface
	mw_interface = nil

	-- Do any other setup here

	-- Install into the mw global
	mw = mw or {}
	mw.ext = mw.ext or {}
	mw.ext.ScribuntoLuaSocket = ScribuntoLuaSocket

	-- Indicate that we're loaded
	package.loaded['mw.ext.ScribuntoLuaSocket'] = ScribuntoLuaSocket
end

return ScribuntoLuaSocket