User:Ahs3/Contributing
|
Looking for Gramps addons to install? If you are looking for existing addons to install to your Gramps desktop, visit: Third-party Addons. This page is concerned only with creating new addons. |
Contents
- 1 CONTRIBUTING Addons
- 2 What Can Addons Extend?
- 3 Overview of Writing an Addon
- 4 Develop Your Addon
- 4.1 Addons Source Code Repository
- 4.2 Addons Download Repository
- 4.3 Set Up a Github Account
- 4.4 Create Project Forks in Github
- 4.5 Set Up Addon Development Environment
- 4.6 Create Your Development Branch
- 4.7 Create Your Addon Subdirectory
- 4.8 Follow the Development API
- 4.9 Test Your Addon As You Develop
- 4.10 Addon Configuration
- 4.11 Localization
- 4.12 Files Included in Addon Distribution
- 5 Create a Gramps Plugin Registration file
- 6 Review the Addon Checklist
- 7 Create a Pull Request
- 8 Announce Your Addon
- 9 Support Your Addon Through Bug Tracker
- 10 Maintain Your Addon as Gramps Evolves
- 11 Resources
- 12 Addon Development Tutorials and Samples
- 13 Addons External to Github
CONTRIBUTING Addons
This document describes the API, methods, and best practices for developing third-party addons for Gramps 6.0 and later.
Gramps Is Usually Developed Using Linux We assume that most addons will be developed using a Linux development
environment. While it is possible to do so under Windows or MacOS,
many of the steps will differ and the documented processes have not
been as thoroughly reviewed. Developer beware. Beyond here there be
dragons. |
Working knowledge of Python and git is required. Ideally, all addons will be contributed and maintained using github, but having a github account is not required.
The addons source tree in github is licensed under the [GNU Public License v2 (GPL-2.0)](https://opensource.org/license/gpl-2-0). We assume you agree with redsitribution under that license when contributing addon source.
If you're looking for *existing* addons to install, see [Third-Party Addons](https://gramps-project.org/wiki/index.php/Third-party_Addons).
If you're looking to contribute to Gramps directly, see [Portal:Developers](https://gramps-project.org/wiki/index.php/Getting_started_with_Gramps_development).
What Can Addons Extend?
Addons for Gramps can extend the program in many different ways. You can add any of the following types of addons:
- Importer (IMPORT) - adds additional file format import options to Gramps
- Exporter (EXPORT) - adds additional file format export options to Gramps
- Gramplet (GRAMPLET) - adds a new interactive interface section to a Gramps view mode, which can be activated by right-clicking on the dashboard View or from the menu of the Sidebar/Bottombar in the other view categories.
- Gramps View (mode) (VIEW) - adds a new view mode to the list of views available within a View Category
- Map Service (MAPSERVICE) - adds new mapping options to Gramps
- Plugin lib (GENERAL) - libraries that are present giving extra functionality; can add, replace, and/or modify builtin Gramps options.
- Quickreport/Quickview (QUICKREPORT) - a view that you can run by right-clicking on an object, or if a person quickview, then via the Quick View Gramplet
- Report (REPORT) - adds a new output report; this includes Website that outputs a static genealogy website based on your Gramps Family Tree data.
- Rule (RULE) - adds new filter rules. — ⚡new for version 5.1
- Tool (TOOL) - adds a utility that helps process data from your family tree.
- Doc creator (DOCGEN)
- Relationships (RECALC)
- Sidebar (SIDEBAR)
- Database (DATABASE) - add support for another database backend. — ⚡new for version 5.0
- Thumbnailer (THUMBNAILER) — ⚡new for version 5.2
- Citation formatter (CITE) — ⚡new for version 5.2
Overview of Writing an Addon
Writing an addon is fairly straightforward if you have a 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:
- Develop your addon
- Create a Gramps plugin registration file (.gpr.py)
- Addon Checklist
- Create a Pull Request for your addon
- Announce it on the Gramps Forum - Let users know it exist and how to use it.
- Support it through the issue tracker
- Maintain the code as Gramps continues to evolve
We'll now expand on each of these steps.
Develop Your Addon
Addons are found in two locations:
- The source code repository, where the addons are developed and maintained: addons-source
- The download repository, which stores the packages that Gramps Addons Manager users download and update for addons they want:
Addons Source Code Repository
The addons-source github repository holds the source code for addons, with branches for each version of the different Gramps releases.
Example commands refer to the current public release and maintenance branch rather than the master branch. Only addons maintainers will merge changes into the current release branch(es); the master branch is only used by the repository maintainers, and only as needed.
Hence, the branches in addons-source to be concerned with are:
- master - managed only by addon maintainers, and not necessarily current
- maintenance/gramps52 - the Gramps 5.2 current release branch, for the previous version of Gramps
- maintenance/gramps60 - the Gramps 6.0 current release branch, for the _current_ version of Gramps
If you are working on an addon for gramps for the current Gramps 6.0 public release, be sure to use the maintenance/gramps60 git branch. NB: there are branches for older releases should they be needed.
The source code in addons-source has the following structure, with the code for each addon in its own subdirectory:
/addons-source
/IndividualNameOfAddon1
/IndividualNameOfAddon2
/...
There are some command line tools and documentation in the root directory as well.
Addons Download Repository
The addons git repository holds packaged versions of the addons for each release of Gramps. As an addon developer, you shouldn't have to do anything with this repository. You should only need to use this repository if you want to have a model of an addon repository in order to make and manage your own, or to test the packaging of your addon. The repository has the following structure:
/addons
/gramps52
/download
/listings
/gramps60
/download
/listings
Set Up a Github Account
In order to use all of the tools github repositories can offer, it is necessary to have a github account. While this is not absolutely required to develop and addon (see [Addons External to Github](#addons-external-to-github)), it can make things easier. For those new to github and git:
- Create a Github account if you don't already have one.
- Create and upload an SSH key for your github account (see Connecting to GitHub with SSH).
- There is a short git introduction with instructions for installing git and getting basic settings configured in a way familiar to Gramps and addons developers.
Even if you are not using github, you will need some familiarity with git.
Create Project Forks in Github
Github assumes a similar development process for all projects:
- Find the project you wish to contribute to -- your upstream project.
- Create a github fork of that upstream project in your user account.
- Make modifications in your fork of the upstream project.
- Once your modifications are ready, create a PR (Pull Request) in the upstream project pointing to the work in your fork.
- The upstream maintainers will then work with you, through the PR, to make sure your modification fits into their project.
This may require several iterations of the addon code for the PR.
Gramps addon development will only require one fork of a github upstream project: addons-source. For testing of the addon packaging, a fork of addons will be needed:
- The addons-source project at https://github.com/gramps-project/addons-source.
- The addons project (the packaged form) at https://github.com/gramps-project/addons.
In the github web interface, login and go to each of the links above. There is a Fork pull-down menu in the upper right hand side of the page. Just click and follow the directions. In this document, we will assume that your github user name is user and that your forks just re-use the names addons-source and addons (these names are not required, but are simpler).
This can also be done from the command line with the gh command. First, authenticate with github, then do the forks:
$ gh auth login # just follow instructions .... $ mkdir myaddon $ cd myaddon $ gh repo fork https://github.com/gramps-project/addons-source $ gh repo fork https://github.com/gramps-project/addons
You'll be asked if you wish to clone the fork. It's not required but if you respond yes it will save you a step later. When the forks are ready, you should be able to see them:
$ gh repo list Showing 2 of 2 repositories in @user NAME DESCRIPTION INFO UPDATED user/addons Contributed 3rd p... public, fork about 1 day ago user/addons-source Contributed 3rd p... public, fork about 1 day ago
Git URIs Whilst we use the URI https://github.com/gramps-project/addons-source above, the URI [email protected]:gramps-project/addons-source.git points to exactly the same place, and accomplishes the same thing. The former relies on HTTPS for security, and the latter relies on SSH. In general, HTTPS is often used for read-only copies of repositories, or when networking precludes SSH usage; SSH however is usually more secure and less subject to man-in-the-middle attacks and thus often used when write access to repositories is needed. |
Set Up Addon Development Environment
Next, we need to download the addon source and its dependencies to build up a development environment. We will need copies of three repositories: addons-source, addons and the main Gramps source gramps. All three of these local copies need to have the same root directory so that the make.py script to be used later works properly.
To continue the examples above, assume our github user name is user and the root directory for development is called myaddon.
Gramps Repository
In developing an addon, we will not need to change the upstream Gramps source, but we will need access to it for the make.py packaging script (described later) to work properly. So, just clone a copy of the current release branch. With SSH:
$ cd myaddon $ git clone -b maintenance/gramps60 [email protected]:gramps-project/gramps
Or with HTTPS:
$ cd myaddon $ git clone -b maintenance/gramps60 https://github.com/gramps-project/gramps.git
The -b parameter tells git to checkout and clone from the named branch.
Addons Repository
The addons repository will hold the package and packaging metadata for the addon being written -- the myaddon.gpr.py registration file, for example, and a compressed tarball of the addon itself. Changes to the upstream addons repository only happens via PRs and using the make.py script.
A recommended structure for your local repository is to have two git remotes, one for upstream, and one for your addon work. If the gh repo fork command was used and it cloned for you, this has already been done. You can see this with:
$ cd myaddon $ cd addons $ git remote -v origin [email protected]:user/addons.git (fetch) origin [email protected]:user/addons.git (push) upstream [email protected]:gramps-project/addons.git (fetch) upstream [email protected]:gramps-project/addons.git (push)
where origin is your fork of the upstream repository, and upstream is the original source.
If just a fork was made, either on github or some other location, an upstream remote should be added:
$ cd myaddon $ cd addons $ git remote -v origin [email protected]:user/addons.git (fetch) origin [email protected]:user/addons.git (push) $ git remote add upstream [email protected]:gramps-project/addons.git $ git pull -a $ git remote -v origin [email protected]:user/addons.git (fetch) origin [email protected]:user/addons.git (push) upstream [email protected]:gramps-project/addons.git (fetch) upstream [email protected]:gramps-project/addons.git (push)
If not using github, setup is a little different:
$ cd myaddon $ mkdir addons $ cd addons # git init $ git remote add upstream [email protected]:gramps-project/addons.git $ git pull -a $ git remote -v origin <your-git-repository> (fetch) origin <your-git-repository> (push) upstream [email protected]:gramps-project/addons.git (fetch) upstream [email protected]:gramps-project/addons.git (push) $ git push origin --all
In all cases, cloning will check out the default branch to start. However, we will not change these branches so we can always refer back to the original upstream source.
Addons Source Repository
The addons-source repository will hold your addon source code. Changes to the upstream addons-source repository will only happen via PRs, and only in the current maintenance branch (e.g., maintenance/gramps60). All of your work will be in your github fork of the addons source repository.
We recommend the same structure for your local repository as above for the addons tree: two git remotes, one for upstream, and one for your addon source. If the gh repo fork command was used and it cloned for you, this has already been done. You can see this with:
$ cd myaddon $ cd addons-source $ git remote -v origin [email protected]:user/addons-source.git (fetch) origin [email protected]:user/addons-source.git (push) upstream [email protected]:gramps-project/addons-source.git (fetch) upstream [email protected]:gramps-project/addons-source.git (push)
where origin is your fork of the upstream repository, and upstream is the original source.
If just a fork was made, either on github or some other location, the upstream remote will have to be added:
$ cd myaddon $ cd addons-source $ git remote -v origin [email protected]:user/addons-source.git (fetch) origin [email protected]:user/addons-source.git (push) $ git remote add upstream [email protected]:gramps-project/addons-source.git $ git pull -a $ git remote -v origin [email protected]:user/addons-source.git (fetch) origin [email protected]:user/addons-source.git (push) upstream [email protected]:gramps-project/addons-source.git (fetch) upstream [email protected]:gramps-project/addons-source.git (push)
If not using github, setup is a little different:
$ cd myaddon $ git clone <your-git-repository> addons-source $ cd addons-source $ git remote add upstream [email protected]:gramps-project/addons-source.git $ git pull -a $ git remote -v origin <your-git-repository> (fetch) origin <your-git-repository> (push) upstream [email protected]:gramps-project/addons-source.git (fetch) upstream [email protected]:gramps-project/addons-source.git (push)
In all cases, cloning will check out the default branch to start. However, we will not change these branches so we can always refer back to the original upstream source.
Create Your Development Branch
Now that copies of all the necessary upstream code have been set up, create the branches that will be used to save your addon and where all of your work will occur:
$ cd myaddon $ cd addons-source $ git checkout -b myaddon60 origin/maintenance/gramps60 $ git push --set-upstream origin myaddon60 $ cd ../addons $ git checkout -b myaddon60 origin/master $ git push --set-upstream origin myaddon60
The checkout will create the branch myaddon60 and then set the current branch to the one just checked out. The push should be done in order to declare the repository for the branch, and to make sure you have a good starting point.
Create Your Addon Subdirectory
Make a new directory in addons-source for your addon:
$ cd myaddon $ cd addons-source $ git checkout myaddon60 $ mkdir NewProjectName # camel case, please
This makes sure we're on the right branch (myaddon60 created in the previous step), and then creates the new directory where your addon development will occur, NewProjectName.
Follow the Development API
Create the two required files: NewProjectName.py that provides the addon implementation, and NewProjectName.gpr.py that provides the information to package the addon so that Gramps can load it and run it.
From this point on, just follow the development API for your specific class of tool: report, view, or Gramplets development. Place all of your associated .py, .glade, and any other files in your addon-source directory. For general information on Gramps development, see Portal:Developers and Writing a Plugin specifically.
Test Your Addon As You Develop
To test your addon as you develop, we recommend you copy your NewProjectName plugin into your Gramps user plugin directory from your addon development directory, prior to testing. Or, just edit in the Gramps user plugin directory until it is ready to publish, then copy back to your addon development directory. Your installed Gramps desktop application will search this folder (and subdirectories) for any .gpr.py files, and add them to the plugin list.
You can of course still use the git branch for your addon to store intermediate steps and other work in progress.
|
Bug 10436 Symbolic links to folders in the gramps plugin directory are not scanned, so you cannot just create a symbolic link pointing to your addon source tree; you will have to copy it. |
If you have code that you want to share between addons, you don't need to do anything special. 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 other addons. You should always make sure you name your addons with a name appropriate for Python imports.
Addon Configuration
Some addons may want to have persistent data (data settings that remain between sessions). You can handle this yourself, or you can use Gramps' builtin configure system.
At the top of the source file for your addon, you would do this:
from config import config as configman
config = configman.register_manager("grampletname")
# register the values to save:
config.register("section.option-name1", value1)
config.register("section.option-name2", value2)
...
# load an existing file, if one:
config.load()
# save it, it case it didn't exist:
config.save()
This will create the file grampletname.ini and put it in the same directory as the addon. If the config file already exists, it remains intact. The natural location for .ini files is in the directory in which the addon is installed; using the main gramps.ini file for addon preferences could potentially lead to a conflict between addons. Other locations and file formats are possible. See The Gramps architect recommends leaving this decision to the addon developer.
In the addon, you can then:
x = config.get("section.option-name1")
config.set("section.option-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):
config.save()
If your code is a system-level file, then you might want to save the config in the Gramps system folder:
config = configman.register_manager("system", use_config_path=True)
This is rare; most .ini files go into the plugins directory.
In other code that might use this config file, you would do this:
from config import config as configman
config = configman.get_manager("grampletname")
x = config.get("section.option-name1")
Localization
Python Strings Only These instructions will only work for Python strings. If you have a glade file, it will not get translated. |
For general help with translations for Gramps, see Coding for translation. However, that will only use translations that come with Gramps, or allow you to contribute translations to the Gramps core. To have your own managed translations that will be packaged with your addon, you will need to add a way to retrieve the translation. Add the following to the top of your NewProjectName.py file:
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 sgettext
These are obsolete starting in Gramps 4.x; gettext, ngettext, and sgettext always return translated strings in Unicode for consistent portability between Python2 and Python3.
See the Python documentation for using gettext and ngettext. The "l" versions return the string encoded according to the currently set locale; the "u" versions return Unicode strings in Python2 and are no longer available in Python3.
The method sgettext should always be used; it is a Gramps extension that filters out clarifying comments for translators, such as in:
_("Remaining names | rest")
where "rest" is the English string that we want to present and "Remaining names" is a hint for translators.
Files Included in Addon Distribution
The process that creates the compressed tar file that the Gramps Download Manager installs in Gramps to use your addon automatically includes the following files:
*.py *.glade *.xml *.txt locale/*/LC_MESSAGES/*.mo
Starting with Gramp 5.0, if you have files other than those listed above, you should create a MANIFEST file in the root of your addon folder that lists the files (or pattern) to be added, one per line, like this sample MANIFEST file. The Addon folder name should be included in each line.
Addon/README.md Addon/extra_dir/* Addon/help_files/docs/help.html
|
Use Weblate Starting with Gramps 6.0 (and only 6.0) translations can be done on Weblate. Initial testing has appeared successful, but please let us know if you notice any problems. The Weblate Addons component contains aggregated translations for every addon. See https://hosted.weblate.org/projects/gramps-project/addons/. |
Create a Gramps Plugin Registration file
First, create the NewProjectName.gpr.py file. The registration takes this general form:
register(PTYPE,
gramps_target_version = "6.0",
version = "1.0.0",
ATTR = value,
)
PTYPE values include: TOOL, GRAMPLET, REPORT, QUICKVIEW (formerly QUICKREPORT), IMPORT, EXPORT, DOCGEN, GENERAL, MAPSERVICE, VIEW, RELCALC, SIDEBAR, DATABASE, RULE, THUMBNAILER, and CITE.
ATTR depends on the PTYPE.
You must include a gramps_target_version and addon 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.
Be sure to include attributes for author name(s) and email(s) in the form of an array of comma-separated strings.
There is an additional set of attributes, maintainers and maintainers_email — ⚡new for version 5.2. If you, the author, are also the maintainer it will be identical to the author attributes, but you may also designate a maintainer, in which case the maintainer will become the primary point of contact.
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',
gramps_target_version = '6.0',
status = STABLE,
fname = 'AttachSourceTool.py',
authors = ["Douglas S. Blank"],
authors_email = ["[email protected]"],
maintainers = ["Douglas S. Blank"],
maintainers_email = ["[email protected]"],
category = TOOL_DBPROC,
toolclass = 'AttachSourceWindow',
optionclass = 'AttachSourceOptions',
tool_modes = [TOOL_MODE_GUI],
help_url = "Addon:AttachSourceTool"
)
You can see examples of the kinds of addons here (for example, see gramps/plugins/drawreport/drawplugins.gpr.py) and see the full documentation in the master/gramps/gen/plug/_pluginreg.py comments and docstrings.
Note that this .gpr.py will automatically use translations if you have them (see Localization). 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):
#possible report categories
CATEGORY_TEXT = 0
CATEGORY_DRAW = 1
CATEGORY_CODE = 2
CATEGORY_WEB = 3
CATEGORY_BOOK = 4
CATEGORY_GRAPHVIZ = 5
CATEGORY_TREE = 6
REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE,
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, CATEGORY_TREE]
Each report category has a set of standards and an 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 in the [[Report-writing_tutorial]. For general information on Gramps development, see Portal:Developers and Writing a Plugin.
General 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 of functions
In this example, a file named library.py will be imported at the time of registration (i.e., any time Gramps starts):
# file: library.gpr.py
register(GENERAL,
id = 'My Library',
name = _("My Library"),
description = _("Provides a library for doing something."),
version = '1.0',
gramps_target_version = '6.0',
status = STABLE,
fname = 'library.py',
load_on_reg = True,
)
You can access the loaded module in other code by issuing an import library as Python keeps track of files already imported. However, the amount of useful code that you can run when the program is imported is limited. You might like to have the code do something that requires a dbstate or uistate object, but neither of these is available when just importing a file.
If load_on_reg was not True, this code would be unavailable until manually loaded. There is no mechanism in Gramps to load GENERAL plugins automatically.
In addition to importing a file at startup, you can also run a single function inside a GENERAL plugin, and it will be passed the dbstate, the uistate, and the plugin data. The function must be called load_on_reg, and take those three parameters:
# file: library.py
def load_on_reg(dbstate, uistate, plugin):
"""
Runs when plugin is registered.
"""
print("Hello World!")
Here, you could connect signals to the dbstate, open windows, etc.
Another example of what you 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:
- allows plugins to list data files
- allows the plugin to process all of the data files
First, the gpr.py file:
register(GENERAL,
id = "ID",
category = "CATEGORY",
load_on_reg = True,
process = "FUNCTION_NAME",
)
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:
# anew.gpr.py
register(GENERAL,
id = 'a new plugin',
category = "WEBSTUFF",
version = '1.0',
gramps_target_version = '6.0',
data = ["a", "b", "c"],
)
This doesn't have load_on_reg = True, nor does it have an fname or process, but it does set the data directly in the .gpr.py file. Then, we have the following results:
>>> 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"]
Registered GENERAL Categories
The following are examples of the published secondary plugin categories of APIs of type GENERAL.
WEBSTUFF
A sample gpr.py file:
# stylesheet.gpr.py
register(GENERAL,
id = 'system stylesheets',
category = "WEBSTUFF",
name = _("CSS Stylesheets"),
description = _("Provides a collection of stylesheets for the web"),
version = '1.0',
gramps_target_version = '6.0',
fname = "stylesheet.py",
load_on_reg = True,
process = "process_list",
)
Here is the associated program:
# file: stylesheet.py
def load_on_reg(dbstate, uistate, plugin):
"""
Runs when plugin is registered.
"""
return ["Stylesheet.css", "Another.css"]
def process_list(files):
return [file.upper() for file in files]
Filters
For example, gpr.py:
register(GENERAL,
category="Filters",
...
load_on_reg = True
)
And the actual plugin:
def load_on_reg(dbstate, uistate, plugin):
# returns a function that takes a namespace, 'Person', 'Family', etc.
def filters(namespace):
print("Ok...", plugin.category, namespace, uistate)
# return a Filter object here
return filters
List Your Addon Prerequistes
In your gpr.py file, you can have a line like:
..... depends_on = ["libwebconnect"], .....
which is a list of plug-in identifier's from other gpr.py files. This example will ensure that libwebconnect is loaded before your addon. If that ID can't be found, or you have a cycle (a circular import), then your addons won't be loaded. The Gramps architect summarizes this as: "The depends_on list is used to specify other plugins which the plugin depends on. These will be installed automatically."
Example code used in the Addon:Web_Connect_Pack that references libwebconnect prerequistes can be seen in RUWebPack.gpr.py#L17.
This means that common prerequisites can be shared between addons. Code can be maintained in its own gpr.py/addon file instead of trying to synchronize the maintenance of multiple copies across various silos.
Additional requirements properties were implemented starting with the Gramps 5.2 Registration Options to provide for specifying plug-in prerequisites:
- For modules: requires_mod
- For GObject introspection: requires_gi
- For executables: requires_exe
Review the Addon Checklist
Before you publish your new addon, review this checklist for completeness
- Is it a good addon name and description?
- Is it in the right tool, report, rule, view, gramplet category?
- Does it need translatable strings marked?
- Does it need a different location for config files?
- Has a wiki page been generated?
- Has the help_url been changed from the GitHub repository to the wiki page?
Create a Pull Request
Once you have created your addon, built the .gpr.py registration file, and have tested it (you did test it, right?) so that you're sure it works well, you next need to submit a Github Pull Request (PR).
If you are already familiar with github and PRs, you can probably skip this section.
There is a script called make.py that can help with some of these tasks; examples of usage will be given below, along with examples for the command line utility gh, and the github web interface, where appropriate.
Commit Your Changes
To begin with, make sure you're in the right local git repository, and on the right branch (all created earlier); you should be able to see something like this:
$ cd myaddon $ cd addons-source $ git ls-remote --get-url [email protected]:user/addons-source.git $ git status On branch workflow60 Your branch is up to date with 'origin/workflow60'. nothing to commit, working tree clean
where user is your github user name, your fork was also called addons-source, and workflow60 is the branch we created earlier to store the new addon. The key point is you want to put your changes into your fork, not the upstream gramps-project/addons-source repository.
Next, commit your changes to your local repository; the git status command will show you what changes it has and has not been told about.
If using the make.py command, remove the files that should not be added to github using the clean command (e.g., template.pot/, locale, etc.):
$ cd myaddon $ cd addons-source $ ./make.py gramps60 clean NewProjectName
If you choose to do the same thing manually:
$ cd myaddon $ cd addons-source $ git checkout myaddon60 $ cd NewProjectName $ rm -i *~ po/*~ po/*-global.po po/*-temp.po po/??.po po/????.po $ rm -i *.pyc *.pyo $ rm -ir locale
Now add the project to your local repository (this adds all files in that directory):
$ git add NewProjectName
Commit it with an appropriate message
$ git commit -m "A message describing what this addon does"
You should now be able to see your commit in the local log:
$ git log
All of these commands operate on your local repository only; there is no need to use gh or the github web interface.
Verify Your Addon Is Current
Before you push your changes into your github fork (the origin remote repository), make sure the changes can actually be merged into the upstream addons-source project.
- Sync your fork to the upstream source to incorporate all the latest upstream changes into your remote repository on github; with the github
web interface, this means pushing a button at the top of the Code page labeled Sync fork. Or, via command line:
$ gh repo set-default user/addons-source $ gh repo sync
- Rebase the changes for your addon, just in case something happened upstream that affects your code; assuming the same example we've been using:
$ git checkout myaddon60 $ git pull --rebase
- Use git status to make sure you haven't missed any files.
Correcting problems when rebasing or merging is a complicated topic. If there are problems, you'll have to fix those before going any further (the git pull --rebase will complain). Typically this a problem when maintaining an addon with multiple contributors working on the same branch at the same time; git mergetool and git revert or git rebase --abort will be your friends here, along with learning more about git than we can cover. And of course, make sure to add, commit, and rebase again, if you do make changes.
Push To Your Fork
To now make your new addon visible to the world, push it to your fork in github:
$ cd myaddon $ cd addons-source $ git checkout myaddon60 $ git push
If for some reason you get a message like this:
fatal: The current branch myaddon60 has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin myaddon60
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
It means that the branch was not pushed as recommended in [[#Create Your Development Branch]Create Your Developmnet Branch]]. Simply enough, just use the push command shown in the message.
Your addon is now visible in your fork of the addons-source repository on github.
Create the PR
Github will usually give you a hint on how to create the PR when you do the push:
$ git push Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) remote: remote: Create a pull request for 'myaddon60' on GitHub by visiting: remote: https://github.com/user/addons-source/pull/new/myaddon60 remote:
If you know where the Code page is on your repository fork, go to the Pull requests tab, then click on New pull request -- which takes you to the URL shown above. Fill in a good description of what the addon does and how it helps and then submit the PR.
When using the command line, submit the PR this way:
$ cd myaddon $ cd addons-source $ git checkout myaddon60 $ gh repo set-default user/addons-source $ gh pr create --title "One line title for your addon" --body "description of what the addon does"
Work Towards a Merge
With the PR created, it's now a matter of working with the addons-source maintainers. Suggestions and corrections will be made and it may be mecessary to modify the original submission to get the addon accepted.
The key thing is to monitor progress and comments. Your PR will have an ID number -- 1234, for example -- so you can always go to the github web page for it:
https://github.com/gramps-project/addons-source/pull/1234
and follow the comments and discussion. This can also be done via the command line:
$ cd myaddon $ cd addons-source $ git checkout myaddon60 $ gh repo set-default user/addons-source $ gh pr view 1234
Respond to comments as soon as you can and as clearly as you can. With any luck, there will be a little clean up here and there, and then your PR will get merged. Once it has, it's time to let others know it exists, if they don't already.
Announce Your Addon
At some point after the PR gets merged, you should be able to do a git pull of the maintenance/gramps60 branch in your addons-source repository and see your addon in the tree.
At the same time, the addons-source maintainer will have also packaged up the addon and inserted the package into the addons repository (see the MAINTAINERS.md file in addons-source or Addon MAINTAINERS). And again, a git pull from addons should show your addon as a package.
Now it is time to announce your addon to those who may not have heard about it yet.
Gramps Forum
Join the Gramps Forum if you have not already. Announce your addon to forum users with general information on why you created it, what it does for the user, and how to use it.
Gramps Wiki
Create an account on the Gramps Wiki if you don't already have one.
List Your Addon
Add a short description of your addon to the Addons list in the wiki by editing the current release listing: i.e., 6.0_Addons, or if the addon is meant for a future release, 6.1_Addons when available. Examine other addon entries while editing the wiki page, and refer to the Addon list legend to understand the meaning of each column. When ready, use the following template to include your addon in the list:
|- <!-- Copy this section and list your Addon --> |<!-- Plugin / Documentation --> |<!-- Type --> |<!-- Image --> |<!-- Description --> |<!-- Use --> |<!-- Rating (out of 4) --> |<!-- Contact --> |<!-- Download --> |-
Document Your Addon
Document the addon in the wiki using the page name format Addon:NewProjectName. Examine some of the the other addon documentation pages for suggestions, and for the general format to use.
Consider including the following information in your wiki page:
<!-- Copy this section to your Addon support page-->
{{Third-party plugin}} <!-- This is a mediawiki template that expands out
to display the standard addon message you see at
the top of each addon page-->
<!--add these sections if needed-->
== Usage ==
=== Configure Options ===
==Features==
== Prerequisites ==
== Issues ==
<!--default categories-->
[[Category:Addons]]
[[Category:Plugins]]
[[Category:Developers/General]]
Support Your Addon Through Bug Tracker
Create a user account on the Gramps MantisBT (Mantis BugTracker), and please check it regularly. There is no automated notification of issues (or possible feature requests) related to your addon when reported by users.
Users tend to not understand coding and they make assumptions. So be kind and guiding if a report is ambiguous or inaccurate. A negative remark from an addon developer or anyone can be very discouraging.
Maintain Your Addon as Gramps Evolves
|
Autoincrementing Version Numbers When submitting an update to the addons packaging repository, the patch part of the version number MAJOR.MINOR.PATCH in your .gpr.py registration file is incremented during the addon build process (e.g., 1.1.3 to 1.1.4). You can see this step in addons-source/make.py. Discussion of this feature can be found at Should addons PR include version numbers. |
Remember that Gramps addons exist for many reasons and there are many Gramps developers that support their addons in various ways -- translations, triage, keeping in sync with master, download infrastructure, and so on.
Here are just some of the reasons why the addons exist; they provide:
- A quick way for anyone to share their work; the Gramps project has never denied adding a addon.
- A method to continuously update and develop a stand-alone component, often before being officially accepted.
- A place for controversial plugins that will never be accepted into core, but are loved by many users (e.g., the Data Entry Gramplet).
- A place for experimental components to live.
Examples of Common Enhancements
And here are just some of the kinds of enhancements that might make sense:
- Copy all the Gramplet's output to a system clipboard via context pop-up menu:
* Enhancement Request 11573 * Resulting Pull Request
- Add a custom View Mode toolbar icon via the
.gpr.py:
* Discussion for Pull Request 1017 * example Pull
Change Code, Submit PR
Enhancements are added to addons-source the same way as the original addon: create a Pull Request with the changes. We recommend putting each enhancement (or bug fix) on a different branch of your local repository. This isolates the changes to be reviewed to only what has actually changed, making them easier to review.
Before committing changes to your addon, you should run through a simple checklist again:
- Make sure that outside changes do not affect your commit:
git pull --rebase - Verify only the files you changed are in this list:
git status - Commit the changes with an appropriate message describing why the change was made:
git commit -m "A message describing the changes"
Then, submit another PR just like before.
Resources
- Git introduction
- Getting started with Gramps development
- Portal:Developers
- gramps.gen.plug._pluginreg Registration Module
- PluginData in _pluginreg.py
- Gramps Addons site for Gramps 4.2 and newer
- https://github.com/gramps-project/addons-source - Source code (Git)
- https://github.com/gramps-project/addons - downloadable .tgz files
- Gramps Addons site for Gramps 4.1 and older
- For 4.1.x and earlier, see Addons development old.
Addon Development Tutorials and Samples
- Develop an Addon Gramplet (add a custom filtering option)
- Develop an Addon Rule for custom filters
- Develop an Addon Tool
- Develop an Addon Quick View
- Develop an Addon Report (tutorial, samples)
- Adapt a builtin Report
Addons External to Github
To Be Written.

