Chapter 3. Creating menu entries

When you create a new plugin, you need to tell RKWard about it. So the first thing to do, is to write a .pluginmap file (or modify an existing one). The format of .pluginmap is XML. I'll walk you through an example (also of course, be sure you have RKWard configured to load your .pluginmap -- SettingsConfigure RKWardPlugins):

Tip

After reading this chapter, have a look at the rkwarddev package as well. It provides some R functions to create most of RKWard's XML tags for you.

<!DOCTYPE rkpluginmap>
	

The doctype is not really interpreted, but set it to "rkpluginmap" anyway.

<document base_prefix="" namespace="myplugins" id="mypluginmap">
	

The base_prefix attribute can be used, if all your plugins reside in a common directory. Basically, then you can omit that directory from the filenames specified below. It safe to leave this at "".

As you will see below, all plugins get a unique identifier, id. The namespace is a way to organize those IDs, and make it less likely to create a duplicate identifier accidentally. Internally, basically the namespace and then a :: gets prepended to all the identifiers you specify in this .pluginmap. In general, if you intend to distribute your plugins in an R package, it is a good idea to use the package name as namespace parameter. Plugins shipped with the official RKWard distribution have namespace="rkward".

The id attribute is optional, but specifying an id for your .pluginmap makes it possible for other people to make their .pluginmaps load your .pluginmap, automatically (see the section on dependencies).

	<components>
	

Components? Aren't we talking about plugins? Yes, but in the future, plugins will be no more than a special class of components. What we do here, then, is to register all components/plugins with RKWard. Let's look at an example entry:

		<component type="standard" id="t_test_two_vars" file="t_test_two_vars.xml" label="Two Variable t-Test" />
	

First the type attribute: Leave this to "standard" for now. Further types are not yet implemented. The id we've already hinted at. Each component has to be given a unique (in its namespace) identifier. Pick one that is easily recognizable. Avoid spaces and any special characters. Those are not banned, so far, but might have special meanings. With the file attribute, you specify where the description of the actual plugin itself is located. This is relative to the directory the .pluginmap file is in, and the base_prefix above. Finally, give the component a label. This label will be shown wherever the plugin is placed in the menu (or in the future perhaps in other places as well).

Typically a .pluginmap file will contain several components, so here are a few more:

		<component type="standard" id="unimplemented_test" file="means/unimplemented.xml" />
		<component type="standard" id="fictional_t_test" file="means/ttests/fictional.xml" label="This is a fictional t-test" />
		<component type="standard" id="descriptive" file="descriptive.xml" label="Descriptive Statistics" />
		<component type="standard" id="corr_matrix" file="corr_matrix.xml" label="Correlation Matrix" />
		<component type="standard" id="simple_anova" file="simple_anova.xml" label="Simple Anova" />
	</components>
	

Ok, this was the first step. RKWard now knows those plugins exist. But how to invoke them? They need to be placed in a menu hierarchy:

	<hierarchy>
		<menu id="analysis" label="Analysis">
	

Right below the <hierarchy> tag, you start describing, in which <menu> your plugins should go. With the above line, you basically say, that your plugin should be in the Analysis menu (not necessarily directly there, but in a submenu). The Analysis menu is standard in RKWard, so it does not actually have to be created from scratch. However, if it did not exist yet, using the label attribute you'd give it its name. Finally, the id once again identifies this <menu>. This is needed, so several .pluginmap files can place their plugins in the same menus. They do this by looking for a <menu> with the given id. If the ID does not yet exist, a new menu will be created. Otherwise the entries will be added to the existing menu.

			<menu id="means" label="Means">
	

Basically the same thing here: Now we define a submenu to the Analysis menu. It is to be called Means.

				<menu id="ttests" label="t-Tests">
	

And a final level in the menu hierarchy: A submenu of the submenu Means.

					<entry component="t_test_two_vars" />
	

Now, finally, this is the menu we want to place the plugin in. The <entry> tag signals, this actually is the real thing, instead of another submenu. The component attribute refers to the id you gave the plugin/component above.

					<entry component="fictional_t_test" />
				</menu>
				<entry component="fictional_t_test" />
			</menu>
			<menu id="frequency" label="Frequency" index="2"/>
	

In case you have lost track: This is another submenu to the Analysis menu. See the screenshot below. We'll skip some of what's not visible, marked with [...].

				[...]
			</menu>
			<entry component="corr_matrix"/>
			<entry component="descriptive"/>
			<entry component="simple_anova"/>
		</menu>
	

These are the final entries visible in the screenshots below.

		<menu id="plots" label="Plots">
			[...]
		</menu>
	

Of course you can also place your plugins in menus other than Analysis.

		<menu id="file" label="File">
			[...]
		</menu>
	

Even in standard-menus such as File. All you need is the correct id.

	</hierarchy>	
</document>
	

That's how to do it. And this screenshot shows the result:

Menu hierarchy created by the code shown above

Confused? The easiest way to get started is probably taking some of the existing .pluginmap files shipped with the distribution, and modifying them to your needs. Also, if you need help, don't hesitate to write to the development mailing list.

Controlling the order of menu entries

By default, all items (entries / submenus) inside a menu will be sorted alphabetically, automatically. In some cases you may want more control. In this case you can group elements as follows:

  • You can define groups inside any menu like this. All elements belonging to the same group will be grouped together:

    		<group id="somegroup"/>
    				
  • If you want the group to be visually separated from other entries, use:

    		<group id="somegroup" separated="true"/>
    				
  • Entries, menus, and groups can be appended to a specified group, using:

    		<entry component="..." group="somegroup"/>
    				
  • In fact, it is also possible to define groups (without separator lines) implicitly:

    		<entry component="first" group="a"/>
    		<entry component="third"/>
    		<entry component="second" group="a"/>
    				
  • Group names are specific to each menu. Group "a" in menu "Data" does not conflict with group "a" in menu "Analysis", for example.

  • The most common use case is defining groups at the top, or at the bottom of a menu. For this, there are pre-defined groups "top" and "bottom" in each menu.

  • Entries within each group are sorted, alphabetically. Groups appear in the order of declaration (unless appended to another group, of course).

  • Menus and entries without group specification logically form a group (""), too.