I think I must be missing something basic. I have a template that is usually called via a URL but I also want to be able to call it manually using theme() /** * Implements hook_menu(). */ function signup_menu() { $items = array(); $items['list/signup/success/%'] = array( 'title' => 'Sign-up Successful', 'page callback' => 'theme', 'page arguments' => array(3), 'page arguments' => array('signup_success'), ); return $items; } /** * Implements hook_theme(). */ function signup_theme() { return array( 'signup_success' => array( 'arguments' => array('node' => NULL), 'template' => 'signup-success', ) ); } function signup_preprocess_signup_success(&$variables) { $signup = signup_record(arg(3)); $variables['signup'] = $signup; } How do I override the argument that is usually passed through the URL? So I can call it like this: theme('signup_success', $signup-id); The preprocess function only ever takes the argument that comes from the current URL which is incorrect.