The GroIMP software can be extended by plugins. This page describes how to write a plugin named MyPlugin.
Firstly, a plugin has to have a special directory layout. The layout depends on how you run GroIMP. There are currently two layout:
In the compiled version of GroIMP (the one deployed and installed with the executable files) the plugins are loaded as:
In the development version of GroIMP (usually what you get from the source code, and using the –project-tree argument) the plugins are loaded as:
Important: Note that the files plugin.xml, and plugin.properties are required.
By default GroIMP load plugins from its root/plugins directory. During development, usually the –project-tree argument is used, making GroIMP load plugin from the same directory as the needed GroIMP plugins and projects (e.g., Graph, XL-Core, IMP-3D, …). It is also possible to set an additional directory where GroIMP look for plugins in the GroIMP preferences. Or by passing the command line argument -p when starting groimp.
The compiled plugins follow the maven project structure. You can get a template plugin here. By default the plugin follow the structure:
The default template includes the assembly files, which you do not have to change for the packaging to a GroIMP plugin.
If possible the third party dependencies should be defined in the pom.xml file and not added to the lib directory. During the maven compilation, the dependencies defined in the pom.xml are automatically added to the target/lib directory, so GroIMP can use them (this operation is performed by the lib.xml assembly file).
Afterwards, you should update the pom.xml file which is used by the Maven tool. Even if you use an IDE for development, a release of a plugin should be made using Maven (which do additional operations when packaging, e.g. source enhancement, deployment, doc, …). Assuming that MyPlugin needs two third party jar-libraries mylib.jar and yourlib.jar, that yourlib.jar is deplyed on Maven Central (an online repository for maven jars) and, that it references the plugins IMP-2D and IMP-3D of GroIMP, pom.xml looks as follows:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>GroIMP</artifactId> <groupId>de.grogra</groupId> <version>2.1</version> </parent> <artifactId>myPlugin</artifactId> <packaging>jar</packaging> <name>MyPlugin</name> <repositories> <repository> <id>lib-local</id> <name>lib</name> <url>file://${project.basedir}/lib/</url> </repository> <repository> <id>gitlab-maven</id> <url>https://gitlab.com/api/v4/groups/55048746/-/packages/maven</url> </repository> </repositories> <properties> <maven.assembly.plugin.move-lib>generate-resources</maven.assembly.plugin.move-lib> </properties> <dependencies> <dependency> <groupId>de.grogra</groupId> <artifactId>imp2d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>de.grogra</groupId> <artifactId>imp3d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>your.remote.lib</groupId> <artifactId>yourlib</artifactId> <version>xxx</version> </dependency> <dependency> <groupId>my.local.lib</groupId> <artifactId>mylib</artifactId> <version>xxx</version> </dependency> </dependencies> <build> <finalName>${project.name}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> </plugin> </plugins> </build> </project>
The first part - plugin info:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>GroIMP</artifactId> <groupId>de.grogra</groupId> <version>2.1</version> </parent> <artifactId>myPlugin</artifactId> <packaging>jar</packaging> <name>MyPlugin</name>
defines:
The second part - remote properties:
<repositories> <repository> <id>lib-local</id> <name>lib</name> <url>file://${project.basedir}/lib/</url> </repository> <repository> <id>gitlab-maven</id> <url>https://gitlab.com/api/v4/groups/55048746/-/packages/maven</url> </repository> </repositories> <properties> <maven.assembly.plugin.move-lib>generate-resources</maven.assembly.plugin.move-lib> </properties>
defines:
The third part - dependencies:
<dependencies> <dependency> <groupId>de.grogra</groupId> <artifactId>imp2d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>de.grogra</groupId> <artifactId>imp3d</artifactId> <version>${groimp.core.version}</version> </dependency> <dependency> <groupId>your.remote.lib</groupId> <artifactId>yourlib</artifactId> <version>xxx</version> </dependency> <dependency> <groupId>my.local.lib</groupId> <artifactId>mylib</artifactId> <version>xxx</version> </dependency> </dependencies>
defines the dependencies to:
Finally, the build section:
<build> <finalName>${project.name}</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> </plugin> </plugins> </build>
it defines that the plugin will be packaged with its <name> instead of <artifactId>. This part is common between all GroIMP plugins, usually you don't have to modify it.
Now that the Maven file is ready, you can compile, package or install you plugin with the commands: mvn compile, mvn pakcage, mvn install.
The file _plugin.properties_ must exist in the plugin path. It can be empty, but should contain the plugin name and provider. It can also include some information on the plugin license and link. Here is an example:
pluginName = The name of your plugin provider = grogra.de aboutplugin.License = GPL aboutplugin.tabs = license aboutplugin.tab.license = License aboutplugin.tab.license.content = gpl.html
The plugin.properties also include all additional text variable you want in your plugin. Which can exist in several language, see how to translate groimp plugins in other languages.
You can also define other resources to be accessible from GroIMP in the _plugin.properties_, see how to add resources in property files.
Then you have to create the plugin.xml file which is read by GroIMP to obtain required information about the plugin.
<?xml version = "1.0" encoding="UTF-8"?> <plugin id="bar.foo.myplugin" version="0.0.1" xmlns="http://grogra.de/registry"> <import plugin="de.grogra.imp2d"/> <import plugin="de.grogra.imp3d"/> <library file="mylib.jar" prefixes="{bar.lib.my,foo.lib.my}"/> <library file="yourlib.jar" prefixes="{bar.lib.your}"/> <library file="MyPlugin.jar" prefixes="{bar.foo.myplugin}"/> <registry> </registry> </plugin>
The id of MyPlugin can be chosen freely, and it must match with the name defined in the maven file <groupId>.<artifactId>. It is recommended to base the id on the Java naming convention for packages. Afterwards, the plugins to import have to be specified. Note that now you have to use the id, while the build.xml file requires the name of the directory which contains the plugin (which typically differs from the id). After the imports, specify the jar-libraries to use. The registration of the libraries has to be in an order such that earlier libraries do not depend on later ones. The last library has to be a jar-file with the same name as the project, so here it is MyPlugin.jar. The library prefixes are comma-separated lists in braces, each item is the prefix of packages which are present in the jar-file. This is used as a hint for class loaders.
Within the registry-element, the actual content of the plugin is registered. You can look at this page for more information on GroIMP's registry structure.
The embedded documentation of GroIMP is based on the docbook format with the htmlhelp template. The docbook file must be created in src/main/resources/manual.xml. There are several docbook editors available online. With GroIMP 2.1.4 it is also possible to use a markdown file as a source of documentation, this file is then turned in to a docbook file and forwarded to the normal pipeline. A documentation on the Markdown based approach can be found here.
The compilation including the embedded help is described here
The linking of the embedded documentation to the help buttons of the panels is explained here
In order to make your plugin easier to get started with, it is recommended to add an example project with it. The example projects are available in GroIMP from the project panel.
To include an example project,the gsz file needs to be placed in 'src/main/resources' and in the plugin the project needs to be referenced in the plugin.xml
file with:
<ref name="examples"> <directory name="CATEGORYNAME" optionCategory="true"> <projectDir name="PROJECTNAME"> <directory name="PROJECTVERSION"> <FilterSourceFactory name="FACTORYNAME"> <resource name="PROJECTFILE.gsz" /> </FilterSourceFactory> </directory> <!-- in the case where several versions of the projects are available --> <directory name="OTHERVERSION"> <FilterSourceFactory name="FACTORYNAME"> <resource name="OTHERFILE.gsz" /> </FilterSourceFactory> </directory> </projectDir> <directory/>
Where:
projectDir
. The other versions will be defined with an OTHERVERSION.plugin.xml
file and the PROJECTFILE
are in src/main/resources/
.
The displayed name can be changed in the plugin.properties
file:
/examples/CATEGORYNAME.Name = any name you want /examples/CATEGORYNAME/PROJECTNAME.ProjectName = ... /examples/CATEGORYNAME/PROJECTNAME.ShortDescription = ... /examples/CATEGORYNAME/PROJECTNAME.Image = `image IMAGEPATH.png` /examples/CATEGORYNAME/PROJECTNAME.Category = ... /examples/CATEGORYNAME/PROJECTNAME.Authors = ... /examples/CATEGORYNAME/PROJECTNAME.Tags = ...
Similar to the examples a FilterSourceFactory can be used to add new templates. Templates are the files that can be selected by creating a new project 'File/new/…'. To add a gsz file stored in 'src/main/resources' as a template it must be added in the template directory:
<ref name="ui"> <ref name="templates"> <FilterSourceFactory name="myTemplate"> <resource name="my_template.gsz"/> </FilterSourceFactory> </ref> </ref>
Additionally the name shown in the menu can be set in the properties file.
See more: