15,534
edits
Changes
→Gramps 4.2 and later: need to document process exactly
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:
# Package your addon
# List and document your addon
# Support it through the issue tracker# Maintain the code as GRAMPS Gramps continues to evolve
We'll now look at each of these steps in detail.
== Develop your addon ==
The [http://svn.code.sf.net/p/gramps-addons /code/ gramps-addons] subversion repository has the following structure:
* /gramps-addons
*** /download
** /branches
*** /gramps32gramps41*** /gramps34
**** /contrib
**** /download
The contrib subdirectories hold the source code for the addons for a particular version. If you are working on a addon for gramps32 gramps{{stable_branch}} then you should be working in gramps-addons/branches/gramps32gramps{{stable_branch}}/contrib. If you are working in gramps/trunk then you should use gramps-addons/trunk/contrib.
==== Setup the addon development tools====
These steps show how to download and work with the addon development tools.
===Follow the development API for your tool===Follow the development API for your tool, [[Report-writing_tutorial|report]], view, or [[Gramplets]]. Place all of your associated .py, .glade, etc. files in this directory. For general information on GRAMPS Gramps development see [[Portal:Developers]] and [[Writing a Plugin]] specifically.
=== Test your addon as you develop ===To test your addon as you develop it it is suggested that you replace your GRAMPS Gramps user plugin directory with a link to your addon development directory, like so:
cd ~/.gramps/gramps32gramps41/ mv plugins/* /wherever/trunk/gramps-addons/branches/gramps32gramps41/contrib/
rm -rf plugins
ln -s /wherever/trunk/gramps-addons/branches/gramps32gramps41/contrib plugins
If you have code that you want to share between addons, you don't need to do anything special. Currently, GRAMPS 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.
=== Commit your changes ===To commit your changes so that others can use your addon, .====Gramps 4.1 and earlier====For Gramps 4.1 and earlier follow these steps:
# Get an http://sourceforge.net account if you don't already have one.
# Request SVN write access for the gramps-addon project by emailing one of the admins of the project (listed under the gramps-addon title next to the group icon) from httpshttp://sourceforge.net/projectprojects/gramps-addons/memberlist.php?group_id=285429
# Remove the files that should not be added to SVN:
## <pre>./make.py clean NewProjectName</pre>
# Add the project to the repository:
## <pre>svn add NewProjectName</pre>## <pre>svn commit -m "A message describing what this addon is"</pre>
Before making additional edits to your addon, you should:
# <pre>svn update</pre># <pre>svn status</pre># <pre>svn commit -m "A message describing the changes"</pre> Also you may want to [[Addons_development#Package_your_addon |Package your addon]] so it can be downloaded via the plugin manager. ====Gramps 4.2 and later====For Gramps 4.2 and later follow these steps:# Get an https://github.com/join account if you don't already have one.# Request GIT write access for the https://github.com/gramps-project/addons-source project by emailing the [[Contact#Mailing_lists|gramps-devel mailing list]] {{out of date}}
=== 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.
from config import configas configman cm config = configconfigman.register_manager("view_placetreeview_0grampletname") cm# register the values to save: config.register("section.variable1option-name1", value1) cmconfig.register("section.variable2option-name2", value2)
...
x = cmconfig.get("section.variable1option-name1") cmconfig.set("section.variable1option-name1", 3)
and when this code is exiting, you might want to save the config. In a Gramplet that would be:
def on_save(self):
If your code is a system-level file, then you might want to save the config in the Gramps system folder:
This, however, would be rare; most .ini files would go into the plugins directory.
In other code that might use this config file, you would do this:
from config import configas configman cm config = configconfigman.get_manager("view_placetreeview_0grampletname") x = cmconfig.get("section.variable1option-name1")
=== Localization ===
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:
==== For Gramps 3: ====
from TransUtils import get_addon_translator
_ = get_addon_translator(__file__).gettext
==== For Gramps 4: ====
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.get_addon_translator(__file__).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:
# gettext
# lgettext
# ngettext
# lngettext
# ngettextsgettext Gramps 3 also provides:
# ugettext
# ungettext
== Create a Gramps Plugin Registration file ==
<pre>
register(PTYPE,
gramps_target_version = "3.24",
version = "1.0.0",
ATTR = value,
</pre>
[http://sourceforge.net/p/gramps/source/ci/master/tree/gramps/gen/plug/_pluginreg.py#l78 PTYPE ] is TOOL, GRAMPLET, REPORT, QUICKREPORTQUICKVIEW, IMPORT, EXPORT, DOCGEN, GENERAL, MAPSERVICE, VIEW, or RELCALC.
ATTR depends on the PTYPE. But you must have '''gramps_target_version''' and '''version'''. gramps_target_version 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.
description = _("Attaches a shared source to multiple objects."),
version = '1.0.0',
gramps_target_version = '3.24',
status = STABLE,
fname = 'AttachSourceTool.py',
</pre>
You can see examples of the kinds of addons [http://gramps.svn.sourceforge.net/viewvcp/gramps/trunksource/ci/master/tree/srcgramps/plugins/ here] (for example, see [http://gramps.svn.sourceforge.net/viewvcp/gramps/trunksource/ci/srcmaster/tree/gramps/plugins/drawreport/drawplugins.gpr.py?view=markup trunkgramps/srcsource/ci/master/tree/gramps/plugins/drawreport/drawreportdrawplugins.gpr.py]) and see the full documentation [http://gramps.svn.sourceforge.net/viewvcp/gramps/trunksource/srcci/master/tree/gramps/gen/plug/_pluginreg.py?view=markup 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.
=== Report plugins ===The possible report categories are (gen/plug/_pluginreg.py):<pre>#possible report categoriesCATEGORY_TEXT = 0CATEGORY_DRAW = 1CATEGORY_CODE = 2CATEGORY_WEB = 3CATEGORY_BOOK = 4CATEGORY_GRAPHVIZ = 5REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ]</pre> Each report category has a set of standards and interface. The categories CATEGORY_TEXT and CATEGORY_DRAW use the Document interface of Gramps. See also [[Report API]] for a draft view on this.The application programming interface or API for reports is treated at [[Report-writing_tutorial]]. For general information on Gramps development see [[Portal:Developers]] and [[Writing a plugin]] specifically. === General Plugins plugins ===
The plugin framework also allows you to create generic plugins for use. This includes the ability to create libraries of functions, and plugins of your own design.
==== Example: A Library library of Functions functions ====
In this example, a file name library.py will be imported at time of registration (when Gramps starts):
description = _("Provides a library for doing something."),
version = '1.0',
gramps_target_version = '3.34',
status = STABLE,
fname = 'library.py',
Here, you could connect signals to the dbstate, open windows, etc.
Another example of what one can do with the plugin interface is to create a general purpose plugin framework for use by other plugins. Here is the basis for a plugin system that:
First, the gpr.py file:
<pre>
register(GENERAL,
id = "ID",
category = "CATEGORY",
load_on_reg = True,
process = "FUNCTION_NAME",
)
</pre>
This example uses three new features:
# GENERAL plugins can have a category
# GENERAL plugins can have a load_on_reg function that returns data
# GENERAL plugins can have a function (called "process") which will process the data
If you (or someone else) create additional general plugins of this category, and they follow your load_on_reg data format API, then they could be used just like your original data. For example, here is an additional general plugin in the 'WEBSTUFF' category:
<pre>
# anew.gpr.py
register(GENERAL,
id = 'a new plugin',
category = "WEBSTUFF",
version = '1.0',
gramps_target_version = '3.4',
data = ["a", "b", "c"],
)
</pre>
This doesn't have load_on_reg = True, nor does it have a fname or process, but it does set the data directly in the .gpr.py file. Then we have the following results:
<pre>
>>> from gui.pluginmanager import GuiPluginManager
>>> PLUGMAN = GuiPluginManager.get_instance()
>>> PLUGMAN.get_plugin_data('WEBSTUFF')
["a", "b", "c", "Stylesheet.css", "Another.css"]
>>> PLUGMAN.process_plugin_data('WEBSTUFF')
["A", "B", "C", "STYLESHEET.CSS", "ANOTHER.CSS"]
</pre>
=== Registered GENERAL Categories ===
The following are the published secondary plugins API's (type GENERAL, with the following categories):
==== WEBSTUFF ====
A sample gpr.py file:
<pre>
register(GENERAL,
id = 'system stylesheets',
category = "CSSWEBSTUFF",
name = _("CSS Stylesheets"),
description = _("Provides a collection of stylesheets for the web"),
version = '1.0',
gramps_target_version = '3.34',
fname = "stylesheet.py",
load_on_reg = True,
)
</pre>
Here is the associated program:
</pre>
<pre>
</pre>
<pre>
</pre>
== Get translators to translate your addon into multiple languages ==
== Package your addon ==
That will build and copy your addon to ../download
To create a listing: cd gramps-addons/branches/gramps41/contrib # or wherever you have built your addon GRAMPSPATH=path/to/your/gramps/install python make.py listing NewProjectName That will create a series of files in the <tt>../listings/</tt> directory. Then add the package updated listing to SVN:
svn add ../download/NewProjectName.addon.tgz ../listings/*
cd ..
svn commit -m "Message describing changes"
== List and document your addon on the wiki==
Document the addon in the wiki using the name '''"Addon:NewProjectName"'''.
Edit [[Plugins3.4]] or [[Plugins4.1]] and describe your addon. You can point to the addon.tgz in SVN as the downloadable file.
== Miscellaneous commands ==
To build and compile translations for all projectsto their download/Addon.addon.tgz files:
python make.py build all
To compile translations for all projects to their download/Addon.addon.tgz files:
python make.py compile all
== List and document your addon Support it through issue tracker ==
== Support it through issue tracker Maintain the code as Gramps continues to evolve ==
= Resources =
* httphttps://sourceforge.net/p/gramps-addons/ - Gramps Addons site * https://github.svn.sourceforge.net/viewvccom/gramps-project/addons-source* https://github.com/ gramps- SVN browseproject/addons
[[Category:Developers/General]]
[[Category:Developers/Tutorials]]
[[Category: Plugins]][[Category:Reports]][[Category:Gramplets]][[Category:Addons]]