Form & shortcode 3 - customize

Translate or customize the SubscriptionForm shortcode (3)

Earlier articles:

Form & shortcode - 1
set up a subscription form saving submitted data to the database, using a custom controller and shortcode

Form & shortcode 2 - email
send the subscription forms' submitted data via e-mail, using an e-mail alias via shortcode

In this third article we look into customizing shortcode and argument names. It isn't all that flexible to pour the name and arguments of a shortcode in concrete!!. One siteadmin might be happy with [Subscription topic="Songwriting" to="Music"], but someone else might maybe rather have something like [Course title="Songwriting" dept="Music"]...

Change the shortcode 'Subscription' to 'Course'

Of course setting the name for a shortcode is flexible: you can use any given word, but once registered, you can't just use something else, so if you change the registration, you need check all existing shortcodes. Best think of a good name in advance... In this case I can change Subscription to Course, but after that it stays...

ShortcodeParser::get('default')->register(
    'Course',
    array('SubscriptionForm' ,'SubscriptionShortcodeHandler')
);

I've added some thoughts on internationalizing shortcode names at the bottom of this article - but until now they've not led up to much...

The arguments

Different names for the same argument?

Selecting a name for an argument is harder, since they are hardcoded. For instance: we're checking on the 'topic' argument in the SubscriptionForm constructor, and we don't really want to change code all the time. So we need some way to map a custom argument to an existing key. A static array will do fine in this example, and I'm going to let the Subscription class host it:

In Subscription.php

static $shortcode_arguments = array();

public static function set_shortcode_arguments($args) {
	if (is_array($args) && !empty($args)) {
		self::$shortcode_arguments = $args;
	}
}

In _config.php:

// define custom names for topic and to
Subscription::set_shortcode_arguments(array(
	'title' => 'topic',
	'dept' => 'to'
));

Now we need to convert the arguments in the SubscriptionForm constructor in order to create the right fieldnames.

function __construct($controller, $name, $arguments=array()) {

	...

	foreach ($arguments as $key => $value) {
		if (array_key_exists($key, Subscription::$shortcode_arguments)) {
			$arguments[Subscription::$shortcode_arguments[$key]] = $value;
		}
	}
	$to = (!empty($arguments['to']))? $arguments['to']: '';
	$fields->push(new HiddenField('To', 'To', $to));

	if (!empty($arguments['topic'])){
		$fields->dataFieldByName('Topic')->setValue($arguments['topic']);
	}
	...

Note: this is all kept simple for the sake of this example: don't let the $arguments overlap theĀ  $shortcode_arguments array, As not all available arguments may be present in the map!

Some thoughts on internationalizing shortcode names...

Do skip this...

Follow the admin's profile language?
Unfortunately there is no easy way to change the shortcode name according to the users profile language: once entered into the text, it's just another string. Of course you could write the functionality to change the name once it is loaded in TinyMCE, and change it back again on write() - but I'll leave that to he desperate...

Use multiple names for the same shortcode?
You could probably define multiple names for the same shortcode handler, and register all of them, but you'd still have the problem that once entered, they'd just be strange code to a siteadmin with a different language profile. But then again - would a Spanish admin manage the Swedish translation?

Note - look into registering the shortcode: what is 'default'? Is there more? Can I register multiple names to the same handler?

What's Next?

Form & shortcode 4 - multiple forms - howto create multiple subscription forms on one and the same page (follows soon)