Difference between revisions of "Addons development"

From Gramps
Jump to: navigation, search
(List and document your addon)
(List and document your addon)
Line 225: Line 225:
 
== List and document your addon ==
 
== List and document your addon ==
  
Edit [[3.2 Plugins]] and describe your addon. You can point to the addon.tgz in SVN as the downloadable file. Document the addon in the wiki using the name "Addon:NewProjectName".
+
Edit [[Plugins3.2]] and describe your addon. You can point to the addon.tgz in SVN as the downloadable file. Document the addon in the wiki using the name "Addon:NewProjectName".
  
 
== Support it through issue tracker ==
 
== Support it through issue tracker ==

Revision as of 03:46, 25 January 2010

This page documents the API, methods, and best practices for developing an 3rd-party addon for GRAMPS 3.2, due March 2010.

Addon Development

Addon's for GRAMPS can extend the program in many different ways. You can add any of the following types of addons:

  1. Doc creator
  2. Exporter
  3. Gramplet
  4. Importer
  5. Map service
  6. Plugin lib
  7. Quickreport
  8. Relationships
  9. Report
  10. Tool
  11. View

Writing an addon is fairly straightforward if you have just a little bit of Python experience. And sharing your addon is the right thing to do. The general steps to writing an addon and sharing your own addons are:

  1. Develop your addon
  2. Create a Gramps Plugin Registration file (.gpr.py)
  3. Get translators to translate your addon into multiple languages
  4. Package your addon
  5. List and document your addon
  6. Support it through issue tracker
  7. Maintain the code as GRAMPS continues to evolve

We'll now look at each of these steps in detail.

Develop your addon

These steps show how to download and work with the addon development tools.

  1. Checkout the gramps-addons files from the gramps-addons project:
    1. cd into gramps trunk, for example:
      1. cd ~/gramps/trunk
    2. Checkout gramps-addons:
      1. svn co https://gramps-addons.svn.sourceforge.net/svnroot/gramps-addons gramps-addons
    3. Change to that directory:
      1. cd gramps-addons
  2. Make a new project directory in gramps-addon/contrib:
    1. cd contrib
    2. mkdir NewProjectName
  3. Initialize the addon:
    1. ./make.py init NewProjectName

Follow the development API for your tool, report, view, or Gramplets. Place all of your associated .py, .glade, etc. files in this directory. For general information on GRAMPS development see Portal:Developers and Writing a Plugin specifically.

To test your addon as you develop it it is suggested that you replace your GRAMPS user plugin directory with a link to your addon development directory, like so:

cd ~/.gramps/gramps32/
mv plugins/* /wherever/trunk/gramps-addons/contrib/
rm -rf plugins
ln -s /wherever/trunk/gramps-addons/contrib plugins

GRAMPS will search this folder (and subdirectories) for .grp.py files, and add them to the plugin list.

If you have code that you want to share between addons, you don't need to do anything special. Currently, GRAMPS adds each directory in which a .gpr.py is found onto the PYTHONPATH which is searched when you perform an import. Thus "import NewProjectName" will work from another addon. You should always make sure you name your addons with a name appropriate for Python imports.

To commit your changes so that others can use your addon, follow these steps:

  1. Get an http://sourceforge.net account if you don't already have one.
  2. Request SVN write access for the gramps-addon project from https://sourceforge.net/project/memberlist.php?group_id=285429
  3. Remove the files that should not be added to SVN:
    1. ./make.py clean NewProjectName
  4. Add the project to the repository:
    1. svn add NewProjectName
    2. svn commit -m "A message describing what this addon is"

Before making additional edits to your addon, you should:

  1. svn update
  2. svn status
  3. svn commit -m "A message describing the changes"

Config

Some addons may want to have persistent data (data settings that remain between sessions). You can handle this yourself, or you can use Gramps' built-in configure system.

In the file that defines the settings, you would do this:

from config import config
cm = config.register_manager("view_placetreeview_0")
cm.register("section.variable1", value1)
cm.register("section.variable2", value2)
...
cm.init()

This will create the file "view_placetreeview_0.ini" and put in the same directory as the addon. In the addon, you can then:

x = cm.get("section.variable1")
cm.set("section.variable1", 3)

and when this code is exiting, you might want to save the config. In a Gramplet that would be:

def on_save(self):
    cm.save()

If your code is a system plugin, then you might want to save the config in the Gramps system folder:

cm = config.register_manager("view_placetreeview_0", use_config_path=True)

In other code that might use this config file, you would do this:

from config import config
cm = config.get_manager("view_placetreeview_0")
x = cm.get("section.variable1")

Localization

For general help on translations in Gramps, see Coding for translation. However, that will only use translations that come with Gramps, or allows you to contribute translations to the Gramps core. To have your own managed translations that will be packaged with your addon, read the rest of this page.

For any addon which you have translations into other languages, you will need to add a way to retrieve the translation. You need to add this to the top of your NewProjectName.py file:

from TransUtils import get_addon_translator
_ = get_addon_translator().gettext

Then you can use the standard "_()" function to translate phrases in your addon.

You can use one of a few different types of translation functions:

  1. gettext
  2. lgettext
  3. lngettext
  4. ngettext
  5. ugettext
  6. ungettext

NOTE: currently we don;t have a method of using a context in any of these functions.

The translation functions that are supported are defined as follows.

gettext(message)

If a fallback has been set, forward gettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes.

lgettext(message)

If a fallback has been set, forward lgettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes.

ugettext(message)

If a fallback has been set, forward ugettext() to the fallback. Otherwise, return the translated message as a Unicode string. Overridden in derived classes.

ngettext(singular, plural, n)

If a fallback has been set, forward ngettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes.

lngettext(singular, plural, n)

If a fallback has been set, forward ngettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes.

ungettext(singular, plural, n)

If a fallback has been set, forward ungettext() to the fallback. Otherwise, return the translated message as a Unicode string. Overridden in derived classes.

Create a Gramps Plugin Registration file

First, create the NewProjectName.gpr.py file. The registration takes this general form:

register(PTYPE,
     for_gramps = "3.2",
     version = "1.0.0",
     ATTR = value,
)

PTYPE is TOOL, GRAMPLET, REPORT, QUICKREPORT, IMPORT, EXPORT, DOCGEN, GENERAL, MAPSERVICE, VIEW, or RELCALC.

ATTR depends on the PTYPE. But you must have for_gramps and version. for_gramps should be a string of the form "X.Y" version number matching Gramps X major, Y minor integer. version is a string of the form "X.Y.Z" representing the version of your addon. X, Y, and Z should all be integers.

Here is a sample Tool GPR file:

register(TOOL, 
         id    = 'AttachSource',
         name  = _("Attach Source"),
         description =  _("Attaches a shared source to multiple objects."),
         version = '1.0.0',
         for_gramps = '3.2',
         status = UNSTABLE,
         fname = 'AttachSourceTool.py',
         authors = ["Douglas S. Blank"],
         authors_email = ["[email protected]"],
         category = TOOL_DBPROC,
         toolclass = 'AttachSourceWindow',
         optionclass = 'AttachSourceOptions',
         tool_modes = [TOOL_MODE_GUI]
         )

You can see examples of the kinds of addons here (for example, see trunk/src/plugins/drawreport/*.gpr.py) and see the full documentation here in the comments and docstrings.

Note that this .gpr.py will automatically use translations if you have them (see below). That is, the function "_" is predefined to use your locale translations; you only need to mark the text with _("TEXT") and include a translation of "TEXT" in your translation file. For example, in the above example, _("Attach Source") is marked for translation. If you have developed and packaged your addon with translation support, then that phrase will be converted into the user's language.

Get translators to translate your addon into multiple languages

  1. Initialize and update the template.pot for your addon:
    1. ./make.py init NewProjectName
  2. Initialize a language for your addon (say French, fr):
    1. ./make.py init NewProjectName fr
  3. Update it from gramps and other addons:
    1. ./make.py update NewProjectName fr
  4. Edit contrib/NewProjectName/po/fr-local.po
  5. Compile the language:
    1. ./make.py compile NewProjectName fr
  6. Add or update your local language file, and commit changes:
    1. svn add NewProjectName/po/fr-local.po
    2. svn commit NewProjectName/po/fr-local.po -m "Added fr po file"

Package your addon

To create a downloadable package:

./make.py build NewProjectName

Then add the package to SVN:

svn add download/NewProjectName.addon.tgz

List and document your addon

Edit Plugins3.2 and describe your addon. You can point to the addon.tgz in SVN as the downloadable file. Document the addon in the wiki using the name "Addon:NewProjectName".

Support it through issue tracker

Maintain the code as GRAMPS continues to evolve

Resources