Difference between revisions of "Addons development"
Codefarmer (talk | contribs) m (Remove stray incomplete sentence) |
GaryGriffin (talk | contribs) m (→Develop your addon) |
||
| (65 intermediate revisions by 7 users not shown) | |||
| Line 1: | Line 1: | ||
{{man tip|Information on developing Gramps addons|If you are looking for addons to install, visit: [[Third-party Addons]]}} | {{man tip|Information on developing Gramps addons|If you are looking for addons to install, visit: [[Third-party Addons]]}} | ||
{{man warn|Note that this article anticipates that most addons will be developed under Linux.|([[Getting started with Gramps development|Linux is the principal development platform.]]) While it is possible to do so under Windows or MacOS, some of the steps will differ and the documented processes have not been as thoroughly reviewed. So developer beware.<br>See [[Portal:Developers]]}} | {{man warn|Note that this article anticipates that most addons will be developed under Linux.|([[Getting started with Gramps development|Linux is the principal development platform.]]) While it is possible to do so under Windows or MacOS, some of the steps will differ and the documented processes have not been as thoroughly reviewed. So developer beware.<br>See [[Portal:Developers]]}} | ||
| − | If you are developing a [[Third-party Addons|Third-party Addon]]; this page documents the API, methods, and best practices for Gramps 4.2 and later. | + | {{man note|More upto date information:|* https://github.com/gramps-project/addons-source/blob/maintenance/gramps{{Stable_branch}}/CONTRIBUTING.md<br> |
| + | * https://github.com/gramps-project/addons-source/blob/maintenance/gramps{{Stable_branch}}/MAINTAINERS.md}} | ||
| + | If you are developing a [[Third-party Addons|Third-party Addon]]; this page documents the API, methods, and best practices for Gramps 4.2 and later. Developers should review the overarching policy for [[Howto: Contribute_to_Gramps|contributing to Gramps]]. | ||
==What can addons extend?== | ==What can addons extend?== | ||
Addons for Gramps can extend the program in many different ways. You can add any of the following [https://github.com/gramps-project/gramps/blob/master/gramps/gen/plug/_pluginreg.py types] of addons: | Addons for Gramps can extend the program in many different ways. You can add any of the following [https://github.com/gramps-project/gramps/blob/master/gramps/gen/plug/_pluginreg.py types] of addons: | ||
| − | + | <!-- sync with https://gramps-project.org/wiki/index.php?title=Addon_list_legend&action=edit§ion=2 --> | |
| − | + | * '''Importer''' (IMPORT) - adds additional file format import options to Gramps | |
| − | # | + | * '''Exporter''' (EXPORT) - adds additional file format export options to Gramps |
| − | # | + | * '''[[Gramps_Glossary#gramplet|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 [[Gramps_Glossary#viewmode|View ''(mode)'']]''' (VIEW) - adds a new view mode to the list of views available within a [[Gramps_Glossary#view|View Category]] |
| − | + | * '''[[Map_Services|Map Service]]''' (MAPSERVICE) - adds new mapping options to Gramps | |
| − | + | * '''Plugin lib''' (GENERAL) - libraries that are present giving extra functionality. Can add, replace and or modifies builtin Gramps options. | |
| − | # | + | * '''[[Gramps_{{man version}}_Wiki_Manual_-_Reports_-_part_8#Quick_Views|Quickreport'''/'''Quickview]]''' (QUICKREPORT) - a view that you can run by right-clicking on object, or if a person quickview, then through the Quick View Gramplet |
| − | + | * '''[[Gramps_{{man version}}_Wiki_Manual_-_Reports_-_part_1|Report]]''' (REPORT) - adds a new output report / includes '''Website''' - output a static genealogy website based on your Gramps Family Tree data. | |
| − | #Relationships | + | * '''[[Gramps_{{man version}}_Wiki_Manual_-_Filters#Add_Rule_dialog|Rule]]''' (RULE) - adds new [[Gramps_Glossary#filter|filter]] rules. {{new|5.1}} |
| − | + | * '''[[Gramps_{{man version}}_Wiki_Manual_-_Tools|Tool]]''' (TOOL) - adds a utility that helps process data from your family tree. | |
| − | + | * '''Doc creator''' (DOCGEN) | |
| − | + | * '''Relationships''' (RECALC) | |
| − | + | * '''Sidebar''' (SIDEBAR) | |
| + | * '''[[Database_Backends|Database]]''' (DATABASE) - add support for another database backend. {{new|5.0}} | ||
| + | * '''Thumbnailer''' (THUMBNAILER) {{new|5.2}} | ||
| + | * '''Citation formatter''' (CITE) {{new|5.2}} | ||
==Writing an addon== | ==Writing an addon== | ||
| Line 30: | Line 35: | ||
# [[#List_and_document_your_addon_on_the_wiki|Document your addon]] and publish it to the addon list | # [[#List_and_document_your_addon_on_the_wiki|Document your addon]] and publish it to the addon list | ||
# [[#List_your_addon_in_the_Gramps_Plugin_Manager|Register your addon with the Plugin Manager]] | # [[#List_your_addon_in_the_Gramps_Plugin_Manager|Register your addon with the Plugin Manager]] | ||
| − | # [[# | + | # [[#Announce_the_addon|Announce it on the Gramps Forum]] - Let users know it exist and how to use it. |
# [[#Support_it_through_issue_tracker|Support it through the issue tracker]] | # [[#Support_it_through_issue_tracker|Support it through the issue tracker]] | ||
# [[#Maintain_the_code_as_Gramps_continues_to_evolve|Maintain the code]] as Gramps continues to evolve | # [[#Maintain_the_code_as_Gramps_continues_to_evolve|Maintain the code]] as Gramps continues to evolve | ||
| Line 38: | Line 43: | ||
== Develop your addon == | == Develop your addon == | ||
| − | The [http://github.com/gramps-project/addons-source addons-source] git repository has the following structure: | + | The [http://github.com/gramps-project/addons-source addons-source] repository holds the source code for the addons with branches holding the version for different gramps. If you are working on an addon for gramps for the current Gramps {{man version}} public release, be sure to use the maintenance/gramps{{Stable_branch}} git branch, as the default is master branch for the developmental pre-release. (Currently gramps 6.1, which is not the typical target for addons.) |
| + | |||
| + | Example commands are shown below referring to the public release rather than the master branch. | ||
| + | |||
| + | The developers are currently merging changes to the most recent maintenance branch into master as necessary, so you don't have to do anything for that unless you are in a hurry. | ||
| + | |||
| + | The [http://github.com/gramps-project/addons-source addons-source] git repository has the following structure, with the code for each addon in its own folder: | ||
* /addons-source | * /addons-source | ||
| Line 45: | Line 56: | ||
** ... | ** ... | ||
| − | The [http://github.com/gramps-project/addons addons] git repository has the following structure: | + | The [http://github.com/gramps-project/addons addons] git repository holds built versions of the addons for each release of Gramps. This is only needed if intending to create a repo. The addons repo has the following structure: |
* /addons | * /addons | ||
| − | ** /gramps42 | + | ** [https://github.com/gramps-project/addons/tree/master/gramps42 /gramps42] |
| + | *** /download | ||
| + | *** /listings | ||
| + | ** [https://github.com/gramps-project/addons/tree/master/gramps50 /gramps50] | ||
| + | *** /download | ||
| + | *** /listings | ||
| + | ** [https://github.com/gramps-project/addons/tree/master/gramps51 /gramps51] | ||
*** /download | *** /download | ||
*** /listings | *** /listings | ||
| − | ** / | + | ** [https://github.com/gramps-project/addons/tree/master/gramps52 /gramps52] |
*** /download | *** /download | ||
*** /listings | *** /listings | ||
| − | ** / | + | ** [https://github.com/gramps-project/addons/tree/master/gramps{{Stable_branch}} /gramps{{Stable_branch}}] |
*** /download | *** /download | ||
*** /listings | *** /listings | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
=== Get a local copy of Gramps and its addons === | === Get a local copy of Gramps and its addons === | ||
| Line 69: | Line 80: | ||
# Get an https://github.com/join account if you don't already have one. | # Get an https://github.com/join account if you don't already have one. | ||
| − | # | + | # Clone the addons-source git repository and submit a PR on that repo for updates. |
See also [[Brief_introduction_to_Git|git introduction]] for instructions on installing git and getting basic settings configured. Also [https://help.github.com/articles/generating-an-ssh-key/ Connecting to GitHub with SSH] will help with setting up credentials for GitHub. | See also [[Brief_introduction_to_Git|git introduction]] for instructions on installing git and getting basic settings configured. Also [https://help.github.com/articles/generating-an-ssh-key/ Connecting to GitHub with SSH] will help with setting up credentials for GitHub. | ||
To fully build and advertise a new addon will require local copies of the three repositories, the 'addons-source', 'addons' and the main Gramps source 'gramps'. | To fully build and advertise a new addon will require local copies of the three repositories, the 'addons-source', 'addons' and the main Gramps source 'gramps'. | ||
| Line 79: | Line 90: | ||
git clone [email protected]:gramps-project/gramps.git gramps | git clone [email protected]:gramps-project/gramps.git gramps | ||
| − | or if you want to use | + | or if you want to use the HTTPS protocol: |
| − | git clone https://github.com/gramps-project/addons-source.git addons-source | + | git clone <nowiki>https://github.com/gramps-project/addons-source.git</nowiki> addons-source |
| − | git clone https://github.com/gramps-project/addons.git addons | + | git clone <nowiki>https://github.com/gramps-project/addons.git</nowiki> addons |
| − | git clone https://github.com/gramps-project/gramps.git gramps | + | git clone <nowiki>https://github.com/gramps-project/gramps.git</nowiki> gramps |
| − | To switch to a local copy of the | + | To switch to a local copy of the gramps{{Stable_branch}} maintenance branch: |
cd addons-source | cd addons-source | ||
| − | git checkout -b | + | git checkout -b gramps{{Stable_branch}} origin/maintenance/gramps{{Stable_branch}} |
or to work in the master branch: | or to work in the master branch: | ||
cd addons-source | cd addons-source | ||
| − | git checkout -b | + | git checkout -b gramps61 origin/master |
| − | === Other | + | === Other prerequisites === |
{{man warn|These instructions, the make.py script etc.|are designed to operate in a Linux environment. {{man menu|They won't work on Windows without modifications.}}}} | {{man warn|These instructions, the make.py script etc.|are designed to operate in a Linux environment. {{man menu|They won't work on Windows without modifications.}}}} | ||
* Gramps uses Python version 3.2 or higher. You must have at least that version installed. If you have installed Gramps 4.2 or higher on your Linux system already, then a sufficient version of Python will be present. If you have more than one version of Python installed, then you must use the correct version for these scripts. On some systems, both Python 2.x and 3.x are installed. It is possible that the normal invocation of <code>python</code> starts up Python 2.x, and that to start up Python 3.x requires invoking with <code>python3</code> or <code>python3.4</code> etc. You can test the version by <code>python –version</code> or <code>python3 –version</code>. If this is so, replace any usage of 'python' in the examples below with the appropriate invocation. | * Gramps uses Python version 3.2 or higher. You must have at least that version installed. If you have installed Gramps 4.2 or higher on your Linux system already, then a sufficient version of Python will be present. If you have more than one version of Python installed, then you must use the correct version for these scripts. On some systems, both Python 2.x and 3.x are installed. It is possible that the normal invocation of <code>python</code> starts up Python 2.x, and that to start up Python 3.x requires invoking with <code>python3</code> or <code>python3.4</code> etc. You can test the version by <code>python –version</code> or <code>python3 –version</code>. If this is so, replace any usage of 'python' in the examples below with the appropriate invocation. | ||
| Line 114: | Line 125: | ||
Create your NewProjectName.py and NewProjectName.gpr.py files. | Create your NewProjectName.py and NewProjectName.gpr.py files. | ||
| − | 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 development see [[Portal:Developers]] and [[Writing a plugin|Writing a Plugin]] specifically. | + | Follow the development API for your tool, [[Report-writing_tutorial|report]], view, or [[Gramplets development]]. 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|Writing a Plugin]] specifically. |
=== Test your addon as you develop === | === Test your addon as you develop === | ||
| Line 130: | Line 141: | ||
* Remove the files using the ''clean'' command that should not be added to GitHub (eg files(template.pot/ locale etc)): | * Remove the files using the ''clean'' command that should not be added to GitHub (eg files(template.pot/ locale etc)): | ||
| − | : <code>./make.py | + | : <code>./make.py gramps{{Stable_branch}} clean NewProjectName</code> |
* Add the project to the repository: | * Add the project to the repository: | ||
: <code>git add NewProjectName</code> | : <code>git add NewProjectName</code> | ||
| Line 149: | Line 160: | ||
* to make sure that outside changes do not affect your commit | * to make sure that outside changes do not affect your commit | ||
: <code>git pull --rebase</code> | : <code>git pull --rebase</code> | ||
| − | : <code>git push origin | + | : <code>git push origin gramps{{Stable_branch}}</code> |
Also you may want to [[Addons_development#Package_your_addon |Package your addon]] so it can be downloaded via the plugin manager. | Also you may want to [[Addons_development#Package_your_addon |Package your addon]] so it can be downloaded via the plugin manager. | ||
| Line 155: | Line 166: | ||
=== Config === | === 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' | + | 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 of your addon, you would do this: | At the top of the source file of your addon, you would do this: | ||
| Line 170: | Line 181: | ||
config.save() | config.save() | ||
| − | This will create the file "grampletname.ini" and put in the same directory as the addon. If the config file already exists, it remains intact. | + | This will create the file "grampletname.ini" and put in the same directory as the addon. If the config file already exists, it remains intact. The natural location for <code>.ini</code> files would be in the directory in which the addon is installed. (Using the main <code>gramps.ini</code> file for addon preferences could potentially lead to a conflict between addons.) Other locations and file formats are possible. [https://gramps.discourse.group/t/add-option-for-boolean-options-in-gramplet/6371/19 The Gramps architect recommends leaving this decision to the addon developer]. |
In the addon, you can then: | In the addon, you can then: | ||
| Line 227: | Line 238: | ||
To build and compile translations for all projects to their download/Addon.addon.tgz files: | To build and compile translations for all projects to their download/Addon.addon.tgz files: | ||
| − | : <code>python3 make.py | + | : <code>python3 make.py gramps{{Stable_branch}} build all</code> |
To compile translations for all projects : | To compile translations for all projects : | ||
| − | : <code>python3 make.py | + | : <code>python3 make.py gramps{{Stable_branch}} compile all</code> |
== Create a Gramps Plugin Registration file == | == Create a Gramps Plugin Registration file == | ||
| Line 239: | Line 250: | ||
<pre> | <pre> | ||
register(PTYPE, | register(PTYPE, | ||
| − | gramps_target_version = " | + | gramps_target_version = "6.0", |
version = "1.0.0", | version = "1.0.0", | ||
ATTR = value, | ATTR = value, | ||
| Line 245: | Line 256: | ||
</pre> | </pre> | ||
| − | [https://github.com/gramps-project/gramps/blob/master/gramps/gen/plug/_pluginreg.py#L76 PTYPE] | + | [https://github.com/gramps-project/gramps/blob/master/gramps/gen/plug/_pluginreg.py#L76 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. But you must have '''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|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: | Here is a sample Tool GPR file: | ||
| Line 258: | Line 273: | ||
description = _("Attaches a shared source to multiple objects."), | description = _("Attaches a shared source to multiple objects."), | ||
version = '1.0.0', | version = '1.0.0', | ||
| − | gramps_target_version = ' | + | gramps_target_version = '6.0', |
status = STABLE, | status = STABLE, | ||
fname = 'AttachSourceTool.py', | fname = 'AttachSourceTool.py', | ||
authors = ["Douglas S. Blank"], | authors = ["Douglas S. Blank"], | ||
authors_email = ["[email protected]"], | authors_email = ["[email protected]"], | ||
| + | maintainers = ["Douglas S. Blank"], | ||
| + | maintainers_email = ["[email protected]"], | ||
category = TOOL_DBPROC, | category = TOOL_DBPROC, | ||
toolclass = 'AttachSourceWindow', | toolclass = 'AttachSourceWindow', | ||
| Line 270: | Line 287: | ||
</pre> | </pre> | ||
| − | You can see examples of the kinds of addons [https://github.com/gramps-project/gramps/plugins here] (for example, see [https://github.com/gramps-project/gramps/plugins/drawreport/drawplugins.gpr.py gramps/plugins/drawreport/drawplugins.gpr.py]) and see the full documentation [https://github.com/gramps-project/gramps/gen/plug/_pluginreg.py | + | You can see examples of the kinds of addons [https://github.com/gramps-project/gramps/plugins here] (for example, see [https://github.com/gramps-project/gramps/plugins/drawreport/drawplugins.gpr.py gramps/plugins/drawreport/drawplugins.gpr.py]) and see the full documentation in the [https://github.com/gramps-project/gramps/blob/3f0db9303f29811b43325c30149c8844c7ce24b6/gramps/gen/plug/_pluginreg.py#L23 master/gramps/gen/plug/_pluginreg.py] 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. | 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 === | === Report plugins === | ||
| − | The possible report categories are (gen/plug/_pluginreg.py): | + | The possible report categories are ([https://github.com/gramps-project/gramps/blob/892fc270592095192947097d22a72834d5c70447/gramps/gen/plug/_pluginreg.py#L141-L149 gen/plug/_pluginreg.py]): |
<pre> | <pre> | ||
#possible report categories | #possible report categories | ||
| Line 284: | Line 301: | ||
CATEGORY_BOOK = 4 | CATEGORY_BOOK = 4 | ||
CATEGORY_GRAPHVIZ = 5 | CATEGORY_GRAPHVIZ = 5 | ||
| + | CATEGORY_TREE = 6 | ||
REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, | REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, | ||
| − | CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ] | + | CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ, CATEGORY_TREE] |
</pre> | </pre> | ||
| Line 308: | Line 326: | ||
description = _("Provides a library for doing something."), | description = _("Provides a library for doing something."), | ||
version = '1.0', | version = '1.0', | ||
| − | gramps_target_version = ' | + | gramps_target_version = '6.0', |
status = STABLE, | status = STABLE, | ||
fname = 'library.py', | fname = 'library.py', | ||
| Line 365: | Line 383: | ||
category = "WEBSTUFF", | category = "WEBSTUFF", | ||
version = '1.0', | version = '1.0', | ||
| − | gramps_target_version = ' | + | gramps_target_version = '6.0', |
data = ["a", "b", "c"], | data = ["a", "b", "c"], | ||
) | ) | ||
| Line 398: | Line 416: | ||
description = _("Provides a collection of stylesheets for the web"), | description = _("Provides a collection of stylesheets for the web"), | ||
version = '1.0', | version = '1.0', | ||
| − | gramps_target_version = ' | + | gramps_target_version = '6.0', |
fname = "stylesheet.py", | fname = "stylesheet.py", | ||
load_on_reg = True, | load_on_reg = True, | ||
| Line 443: | Line 461: | ||
<span id=internationalization> | <span id=internationalization> | ||
| + | |||
| + | == List the Prerequistes your addon depends on == | ||
| + | |||
| + | ''In your gpr file, you can have a line like: | ||
| + | |||
| + | <code>depends_on = ["libwebconnect"],</code> | ||
| + | |||
| + | which is a list of plug-in identifier's from other gpr files. This example will ensure that [[Addon:Web_Connect_Pack#Prerequisites|libwebconnect]] is loaded before your addon. If that ID can't be found, or you have a cycle (circular import), then your addons won't be loaded. The Gramps architect summarizes: "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 [https://github.com/gramps-project/addons-source/blob/1304b65a7d758bfe17339c26260473ac3e9c4061/RUWebConnectPack/RUWebPack.gpr.py#L17 RUWebPack.gpr.py#L17] | ||
| + | |||
| + | This means that common Prerequisites can be shared between addons. So that code can be maintained in its own gpr/addon file instead of synchronizing the maintenance of multiple copies across various silos. | ||
| + | |||
| + | Additional requirements properties were implemented in the [[Gramplets_development#Register_Options|Registration Options]] to specify prerequisites for plug-ins: [https://github.com/gramps-project/gramps/blob/0f8d4ecd429431b4df64910962f8764af9ff1766/gramps/gen/plug/_pluginreg.py#L689-L719 requires_mod (modules), requires_gi (GObject introspection) and requires_exe (executable).] {{new|5.2}} | ||
| + | |||
| + | <!-- | ||
| + | |||
| + | [] for addon prerequistes have a look at converting them to use "depends_on = " like in the following addons | ||
| + | https://github.com/gramps-project/addons-source/search?utf8=%E2%9C%93&q=depends_on&type= | ||
| + | https://github.com/gramps-project/gramps/search?utf8=%E2%9C%93&q=depends_on&type= | ||
| + | |||
| + | which can be a comma separated list for multiple dependencies/prerequisites (so that addons that share prerequisites import the same library?) (maybe move spell check into an addon etc? tip of the day... possibilities...) | ||
| + | |||
| + | depends_on = ["libwebconnect"] | ||
| + | |||
| + | mentioned in the following | ||
| + | https://sourceforge.net/p/gramps/mailman/message/27070037/ | ||
| + | ''In your gpr file, you can have a line like: | ||
| + | |||
| + | depends_on = ["libwebconnect"] | ||
| + | |||
| + | which is a list of id's from other gpr files. This example will ensure that libwebconnect is loaded before your plugin. If it can't be found, or you have a cycle, then your plugin won't be loaded. | ||
| + | |||
| + | If it is a common function, perhaps libhtml is the right place to put it, and you can put a depends_on on that. | ||
| + | |||
| + | -Doug'' | ||
| + | |||
| + | |||
| + | example output is on terminal only: | ||
| + | |||
| + | Cannot resolve the following plugin dependencies: | ||
| + | Plugin 'UK Web Connect Pack' requires: ['libwebconnect'] | ||
| + | |||
| + | [](feature) For plugins/addons if prerequisites not available display a page stating why/what is missing that includes the addon description and a url to the support page. | ||
| + | |||
| + | [] Gramps CLI info "gramps -v" needs a section that list third-party addons with version numbers and if prerequisites have been met. | ||
| + | |||
| + | []update the Addon:Prerequisites Checker Gramplet to test for your Prerequisites. | ||
| + | |||
| + | --> | ||
| + | |||
== Get translators to translate your addon into multiple languages == | == Get translators to translate your addon into multiple languages == | ||
</span> | </span> | ||
| Line 448: | Line 517: | ||
* Initialize and update the <code>template.pot</code> for your addon: | * Initialize and update the <code>template.pot</code> for your addon: | ||
: <code>cd ~/addons-source</code> | : <code>cd ~/addons-source</code> | ||
| − | : <code>./make.py | + | : <code>./make.py gramps{{Stable_branch}} init NewProjectName</code> |
* You should edit the header of <code>template.pot</code> with your information, so it gets copied to individual language files. | * You should edit the header of <code>template.pot</code> with your information, so it gets copied to individual language files. | ||
* Initialize a language for your addon (say French, fr): | * Initialize a language for your addon (say French, fr): | ||
| − | : <code>./make.py | + | : <code>./make.py gramps{{Stable_branch}} init NewProjectName fr</code> |
* Update it from gramps and other addons: | * Update it from gramps and other addons: | ||
| − | : <code>./make.py | + | : <code>./make.py gramps{{Stable_branch}} update NewProjectName fr</code> |
* Edit the translations file manually: | * Edit the translations file manually: | ||
: <code>/NewProjectName/po/fr-local.po</code> | : <code>/NewProjectName/po/fr-local.po</code> | ||
* Compile the language: | * Compile the language: | ||
| − | : <code>./make.py | + | : <code>./make.py gramps{{Stable_branch}} compile NewProjectName</code> |
* Add or update your local language file, and commit changes: | * Add or update your local language file, and commit changes: | ||
: <code>git add NewProjectName/po/fr-local.po</code> | : <code>git add NewProjectName/po/fr-local.po</code> | ||
: <code>git commit NewProjectName/po/fr-local.po -m "Added fr po file"</code> | : <code>git commit NewProjectName/po/fr-local.po -m "Added fr po file"</code> | ||
* If you have been given 'push' rights to GitHub 'gramps-project/addons-source', then; | * If you have been given 'push' rights to GitHub 'gramps-project/addons-source', then; | ||
| − | : <code>git push origin | + | : <code>git push origin gramps{{Stable_branch}}</code> |
| + | |||
| + | {{man tip|From Gramps 6.x translations can be done on Weblate. This is experimental. 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.|https://hosted.weblate.org/projects/gramps-project/addons/}}<!-- https://gramps-project.org/bugs/view.php?id=13646#c68218 Nick Hall "Weblate is set up to translate the gramps{{Stable_branch}} branch. Changes to gramps52 must still use the old manual process." --> | ||
== Package your addon == | == Package your addon == | ||
| Line 468: | Line 539: | ||
To create a downloadable package: | To create a downloadable package: | ||
| − | : <code>./make.py | + | : <code>./make.py gramps{{Stable_branch}} build NewProjectName</code> or |
| − | : <code>./make.py | + | : <code>./make.py gramps61 build NewProjectName</code> for the master branch. |
This will automatically include the following files in your build: | This will automatically include the following files in your build: | ||
| Line 479: | Line 550: | ||
* locale/*/LC_MESSAGES/*.mo | * locale/*/LC_MESSAGES/*.mo | ||
| − | Starting with Gramp 5.0, if you have additional files beyond those listed above, you should create a MANIFEST file in the root of your addon folder listing the files (or pattern) one per line, like this sample MANIFEST file | + | Starting with Gramp 5.0, if you have additional files beyond those listed above, you should create a MANIFEST file in the root of your addon folder listing the files (or pattern) one per line, like this sample MANIFEST file. Include the Addon folder name in each line. |
<pre> | <pre> | ||
| − | README.md | + | Addon/README.md |
| − | extra_dir/* | + | Addon/extra_dir/* |
| − | help_files/docs/help.html | + | Addon/help_files/docs/help.html |
</pre> | </pre> | ||
| Line 495: | Line 566: | ||
<pre> cd '~/addons' | <pre> cd '~/addons' | ||
| − | git add | + | git add gramps{{Stable_branch}}/download/NewProjectName.addon.tgz |
git commit -m "Added new plugin: NewProjectName"</pre> | git commit -m "Added new plugin: NewProjectName"</pre> | ||
or (for the master branch); | or (for the master branch); | ||
<pre> cd '~/addons' | <pre> cd '~/addons' | ||
| − | git add | + | git add gramps61/download/NewProjectName.addon.tgz |
git commit -m " Added new plugin: NewProjectName"</pre> | git commit -m " Added new plugin: NewProjectName"</pre> | ||
== List your addon in the Gramps Plugin Manager== | == List your addon in the Gramps Plugin Manager== | ||
| − | {{man warn|Gramps needs to have been built|Make sure you have already built | + | {{man warn|Gramps needs to have been built|Make sure you have already built gramps{{Stable_branch}} or master. Change to the appropriate git branch in your gramps directory, and run <code>python3 setup.py build</code> See [[Linux:Build_from_source]]}} |
To create a listing: | To create a listing: | ||
: <code>cd '~/gramps-addons'</code> or wherever you have built your addon | : <code>cd '~/gramps-addons'</code> or wherever you have built your addon | ||
| − | : <code>GRAMPSPATH=path/to/your/gramps/install ./make.py | + | : <code>GRAMPSPATH=path/to/your/gramps/install ./make.py gramps{{Stable_branch}} listing NewProjectName</code> |
or (for the master branch); | or (for the master branch); | ||
: <code>cd '~/gramps-addons'</code> or wherever you have built your addon | : <code>cd '~/gramps-addons'</code> or wherever you have built your addon | ||
| − | : <code>GRAMPSPATH=path/to/your/gramps/install ./make.py | + | : <code>GRAMPSPATH=path/to/your/gramps/install ./make.py gramps61 listing NewProjectName</code> |
That will create a series of files in the <tt>../listings/</tt> directory. | That will create a series of files in the <tt>../listings/</tt> directory. | ||
| Line 519: | Line 590: | ||
<pre> cd '~/addons' | <pre> cd '~/addons' | ||
| − | git add | + | git add gramps{{Stable_branch}}/listings/* |
git commit -m "Added new plugin to listings: NewProjectName"</pre> | git commit -m "Added new plugin to listings: NewProjectName"</pre> | ||
or (for the master branch); | or (for the master branch); | ||
<pre> cd '~/addons' | <pre> cd '~/addons' | ||
| − | git add | + | git add gramps61/listings/* |
git commit -m " Added new plugin to listings: NewProjectName"</pre> | git commit -m " Added new plugin to listings: NewProjectName"</pre> | ||
| Line 529: | Line 600: | ||
===List your addon=== | ===List your addon=== | ||
| − | Add a short description of your addon to the Addons list by editing the current release listing eg: [[ | + | Add a short description of your addon to the Addons list by editing the current release listing eg: [[6.0_Addons]] or if the addon is meant for a future release [[6.1_Addons]] when available. |
==== Example addon template ==== | ==== Example addon template ==== | ||
| Line 574: | Line 645: | ||
</pre> | </pre> | ||
| − | == Announce | + | == Announce the addon == |
| − | Join the [[Contact# | + | Join the [[Contact#Forum|Gramps Forum]] and announce it to the users with general information on why you created and how to use it. |
== Support it through issue tracker == | == Support it through issue tracker == | ||
| Line 586: | Line 657: | ||
== Maintain the code as Gramps continues to evolve == | == Maintain the code as Gramps continues to evolve == | ||
| − | Remember that Gramps addons exist for many reasons and there are many | + | {{man tip|When submitting an update the patch part of the version number MAJOR.MINOR.PATCH is updated during the addon build process e.g. 1.1.3 to 1.1.4|This means when your plugin has become part of the default gramps addons there is no need to run `make` yourself as it is part of the regular addon build process. You can find this step in [https://github.com/gramps-project/addons-source/blob/master/make.py#L125 addons-source/make.py].[https://gramps.discourse.group/t/should-addons-pr-include-version-number-update/2591]}} |
| − | Gramps developers that do support addons in various ways (translations, | + | |
| − | triage, keeping in sync with master, download infrastructure, etc). | + | Remember that Gramps addons exist for many reasons and there are many Gramps developers that do support addons in various ways (translations, triage, keeping in sync with master, download infrastructure, etc). |
Some reasons why the addons exist; they provide: | Some reasons why the addons exist; they provide: | ||
| Line 595: | Line 666: | ||
* A place for controversial plugins that will never be accepted into core, but are loved by many users (eg, Data Entry Gramplet). | * A place for controversial plugins that will never be accepted into core, but are loved by many users (eg, Data Entry Gramplet). | ||
* A place for experimental components to live. | * A place for experimental components to live. | ||
| + | |||
== Example code adding common enhancements == | == Example code adding common enhancements == | ||
* Copy all the Gramplet's output to a system clipboard via context pop-up menu : Enhancement request {{bug|11573}}, [https://github.com/gramps-project/gramps/pull/1014/commits/72012e13b4ca15caca4b7f36fdb9702c1fd470fd example pull] | * Copy all the Gramplet's output to a system clipboard via context pop-up menu : Enhancement request {{bug|11573}}, [https://github.com/gramps-project/gramps/pull/1014/commits/72012e13b4ca15caca4b7f36fdb9702c1fd470fd example pull] | ||
| Line 603: | Line 675: | ||
* [[Getting started with Gramps development]] | * [[Getting started with Gramps development]] | ||
* [[Portal:Developers]] | * [[Portal:Developers]] | ||
| − | * [https://gramps-project.org/docs/gen/gen_plug.html?highlight=include_in_listing#module-gramps.gen.plug._pluginreg Registration Module] | + | * [https://gramps-project.org/docs/gen/gen_plug.html?highlight=include_in_listing#module-gramps.gen.plug._pluginreg gramps.gen.plug._pluginreg Registration Module] |
| + | * [https://github.com/gramps-project/gramps/blob/master/gramps/gen/plug/_pluginreg.py#L55 PluginData in _pluginreg.py] | ||
;Gramps Addons site for Gramps 4.2 and newer | ;Gramps Addons site for Gramps 4.2 and newer | ||
| Line 609: | Line 682: | ||
* https://github.com/gramps-project/addons - downloadable .tgz files | * https://github.com/gramps-project/addons - downloadable .tgz files | ||
;Gramps Addons site for Gramps 4.1 and older | ;Gramps Addons site for Gramps 4.1 and older | ||
| − | * For 4.1.x and earlier, see [[Addons development old]]. | + | * For 4.1.x and earlier, see [[Addons development old]]. |
| + | |||
| + | = Addon Development Tutorials and Samples = | ||
| + | |||
| + | * [[Gramplets development|Develop an Addon Gramplet]] example code: | ||
| + | ** of a [https://gramps.discourse.group/t/looking-for-an-example-of-a-gramplet-with-a-custom-filter-configuration-option/5967 custom filtering option]) | ||
| + | ** toolbar: Photo Tagging gramplet - [[Addon:Photo_Tagging_Gramplet#Toolbar|documentation]] ([https://github.com/gramps-project/addons-source/blob/bd1ce5cceb8b8a24ae5b612f311db42dfa0ed679/PhotoTaggingGramplet/PhotoTaggingGramplet.py#L233 source]) | ||
| + | * [[Develop_an_Addon_Rule|Develop an Addon Rule]] for custom filters | ||
| + | * [[Develop_an_Addon_Tool|Develop an Addon Tool]] | ||
| + | * [[Quick_Views|Develop an Addon Quick View]] | ||
| + | * Develop an Addon Report ([[Report-writing_tutorial|tutorial]], [https://gramps.discourse.group/t/sample-report-for-new-developers/3046 samples]) | ||
| + | * [[Adapt_a_builtin_Report|Adapt a builtin Report]] | ||
[[Category:Developers/General]] | [[Category:Developers/General]] | ||
| Line 616: | Line 700: | ||
[[Category:Reports]] | [[Category:Reports]] | ||
[[Category:Gramplets]] | [[Category:Gramplets]] | ||
| − | [[Category:Addons]] | + | [[Category:Addons|*]] |
Latest revision as of 06:10, 18 June 2026
|
Information on developing Gramps addons If you are looking for addons to install, visit: Third-party Addons |
|
Note that this article anticipates that most addons will be developed under Linux. (Linux is the principal development platform.) While it is possible to do so under Windows or MacOS, some of the steps will differ and the documented processes have not been as thoroughly reviewed. So developer beware. |
More upto date information: |
If you are developing a Third-party Addon; this page documents the API, methods, and best practices for Gramps 4.2 and later. Developers should review the overarching policy for contributing to Gramps.
Contents
- 1 What can addons extend?
- 2 Writing an addon
- 3 Develop your addon
- 4 Create a Gramps Plugin Registration file
- 5 List the Prerequistes your addon depends on
- 6 Get translators to translate your addon into multiple languages
- 7 Package your addon
- 8 List your addon in the Gramps Plugin Manager
- 9 List and document your addon on the wiki
- 10 Announce the addon
- 11 Support it through issue tracker
- 12 Maintain the code as Gramps continues to evolve
- 13 Example code adding common enhancements
- 14 Resources
- 15 Addon Development Tutorials and Samples
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 modifies builtin Gramps options.
- Quickreport/Quickview (QUICKREPORT) - a view that you can run by right-clicking on object, or if a person quickview, then through the Quick View Gramplet
- Report (REPORT) - adds a new output report / includes Website - output 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
Writing an addon
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:
- Develop your addon
- Create a Gramps Plugin Registration file (.gpr.py)
- Invite translation of your addon into multiple natural languages
- Package your addon
- Document your addon and publish it to the addon list
- Register your addon with the Plugin Manager
- 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 upon each of these steps individually.
Develop your addon
The addons-source repository holds the source code for the addons with branches holding the version for different 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, as the default is master branch for the developmental pre-release. (Currently gramps 6.1, which is not the typical target for addons.)
Example commands are shown below referring to the public release rather than the master branch.
The developers are currently merging changes to the most recent maintenance branch into master as necessary, so you don't have to do anything for that unless you are in a hurry.
The addons-source git repository has the following structure, with the code for each addon in its own folder:
- /addons-source
- /IndividualNameOfAddon1
- /IndividualNameOfAddon2
- ...
The addons git repository holds built versions of the addons for each release of Gramps. This is only needed if intending to create a repo. The addons repo has the following structure:
- /addons
Get a local copy of Gramps and its addons
These steps show how to download the addon sources.
- Get an https://github.com/join account if you don't already have one.
- Clone the addons-source git repository and submit a PR on that repo for updates.
See also git introduction for instructions on installing git and getting basic settings configured. Also Connecting to GitHub with SSH will help with setting up credentials for GitHub. To fully build and advertise a new addon will require local copies of the three repositories, the 'addons-source', 'addons' and the main Gramps source 'gramps'.
This wiki assumes that all three git repositories local locations are put into the same base directory and named with the repository names in order for the make.py script commands to work as shown. From the base directory, run the following commands to create a copy of each repository. If you want to use SSH;
git clone [email protected]:gramps-project/addons-source.git addons-source git clone [email protected]:gramps-project/addons.git addons git clone [email protected]:gramps-project/gramps.git gramps
or if you want to use the HTTPS protocol:
git clone https://github.com/gramps-project/addons-source.git addons-source git clone https://github.com/gramps-project/addons.git addons git clone https://github.com/gramps-project/gramps.git gramps
To switch to a local copy of the gramps60 maintenance branch:
cd addons-source git checkout -b gramps60 origin/maintenance/gramps60
or to work in the master branch:
cd addons-source git checkout -b gramps61 origin/master
Other prerequisites
|
These instructions, the make.py script etc. are designed to operate in a Linux environment. They won't work on Windows without modifications. |
- Gramps uses Python version 3.2 or higher. You must have at least that version installed. If you have installed Gramps 4.2 or higher on your Linux system already, then a sufficient version of Python will be present. If you have more than one version of Python installed, then you must use the correct version for these scripts. On some systems, both Python 2.x and 3.x are installed. It is possible that the normal invocation of
pythonstarts up Python 2.x, and that to start up Python 3.x requires invoking withpython3orpython3.4etc. You can test the version bypython –versionorpython3 –version. If this is so, replace any usage of 'python' in the examples below with the appropriate invocation. - The make.py used in construction of the addons requires that the LANGUAGE environment variable be set to 'en_US.UTF-8'.
- The make.py used in construction of the addons requires that the GRAMPSPATH environment variable be set to your path to the Gramps source tree.
- intltool must be installed;
sudo apt-get install intltool
For example if your home directory is '/home/name' and you use the suggested path names, use
GRAMPSPATH=/home/name/gramps LANGUAGE='en_US.UTF-8' python3 make.py ...
to replace the ./make.py in the examples below.
Create your addon subdirectory
- Make a new project directory in addons-source:
mkdir NewProjectName
Follow the development API for your tool
Create your NewProjectName.py and NewProjectName.gpr.py files.
Follow the development API for your tool, report, view, or Gramplets development. 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.
Test your addon as you develop
|
10436 Symlinks to folders in gramps plugin dir are not scanned |
To test your addon as you develop it is suggested that 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 will search this folder (and subdirectories) for .gpr.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. 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 see your addon source.
- Remove the files using the clean command that should not be added to GitHub (eg files(template.pot/ locale etc)):
./make.py gramps60 clean NewProjectName
- Add the project to the repository:
git add NewProjectName
- Commit it with an appropriate message
git commit -m "A message describing what this addon is"
Before committing additional edits to your addon, you should:
- to make sure that outside changes do not affect your commit
git pull --rebase
- only the files you changed should be in this list
git status
- Commit it with an appropriate message
git commit -m "A message describing the changes"
If you have been given 'push' rights to GitHub 'gramps-project/addons-source', and when you are sure you are done and want to publish to the repository:
- to make sure that outside changes do not affect your commit
git pull --rebasegit push origin gramps60
Also you may want to Package your addon so it can be downloaded via the plugin manager.
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' builtin configure system.
At the top of the source file of 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 in the same directory as the addon. If the config file already exists, it remains intact. The natural location for .ini files would be 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. 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, 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 config as configman
config = configman.get_manager("grampletname")
x = config.get("section.option-name1")
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. Note that these instructions will only work for Python strings, if you have a glade file, it will not get translated.
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 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 have become obsolete in Gramps 4; gettext, ngettext, and sgettext always return translated strings in unicode for consistent portability between Python 2 and Python3.
See the python documentation for documentation of 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 not available in Python 3.
sgettext is a Gramps extension that filters out clarifying comments for translators, such as
_("Remaining names | rest")
Where "rest" is the English string that we want to present and "Remaining names" is a hint for translators.
Commands to compile translations
To build and compile translations for all projects to their download/Addon.addon.tgz files:
python3 make.py gramps60 build all
To compile translations for all projects :
python3 make.py gramps60 compile all
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. But you must have 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]
)
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 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):
#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 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
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 name library.py will be imported at time of registration (when 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,
)
The code in the file library.py will be imported when Gramps begins. 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, and neither of these is available when just importing a file.
If "load_on_reg" was not True, then this code would be unavailable until manually loaded. There is no automatic mechanism in Gramps to load GENERAL plugins automatically.
In addition to importing a file at startup, one 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, like this:
# 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 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:
- 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 a 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 the published secondary plugins API's (type GENERAL, with the following categories):
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:
register(GENERAL, category="Filters", ... load_on_reg = True )
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 the Prerequistes your addon depends on
In your gpr file, you can have a line like:
depends_on = ["libwebconnect"],
which is a list of plug-in identifier's from other gpr files. This example will ensure that libwebconnect is loaded before your addon. If that ID can't be found, or you have a cycle (circular import), then your addons won't be loaded. The Gramps architect summarizes: "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 RUWebPack.gpr.py#L17
This means that common Prerequisites can be shared between addons. So that code can be maintained in its own gpr/addon file instead of synchronizing the maintenance of multiple copies across various silos.
Additional requirements properties were implemented in the Registration Options to specify prerequisites for plug-ins: requires_mod (modules), requires_gi (GObject introspection) and requires_exe (executable). — ⚡new for version 5.2
Get translators to translate your addon into multiple languages
If you designed for localization, the addon will begin supporting a single language. Make your addon inviting for volunteers to translate it into their native language.
- Initialize and update the
template.potfor your addon:
cd ~/addons-source./make.py gramps60 init NewProjectName
- You should edit the header of
template.potwith your information, so it gets copied to individual language files. - Initialize a language for your addon (say French, fr):
./make.py gramps60 init NewProjectName fr
- Update it from gramps and other addons:
./make.py gramps60 update NewProjectName fr
- Edit the translations file manually:
/NewProjectName/po/fr-local.po
- Compile the language:
./make.py gramps60 compile NewProjectName
- Add or update your local language file, and commit changes:
git add NewProjectName/po/fr-local.pogit commit NewProjectName/po/fr-local.po -m "Added fr po file"
- If you have been given 'push' rights to GitHub 'gramps-project/addons-source', then;
git push origin gramps60
Package your addon
To create a downloadable package:
./make.py gramps60 build NewProjectNameor./make.py gramps61 build NewProjectNamefor the master branch.
This will automatically include the following files in your build:
- *.py
- *.glade
- *.xml
- *.txt
- locale/*/LC_MESSAGES/*.mo
Starting with Gramp 5.0, if you have additional files beyond those listed above, you should create a MANIFEST file in the root of your addon folder listing the files (or pattern) one per line, like this sample MANIFEST file. Include the Addon folder name in each line.
Addon/README.md Addon/extra_dir/* Addon/help_files/docs/help.html
Note: Running the command |
This will leave your 'addons-source' with untracked changes according to git. You should delete the 'NewProjectName/locale' directory. The updated 'NewProjectName/NewProjectName.gpr.py ' is ready to add and commit the next time you make other changes.
rm –rf –v 'NewProjectName/locale'
Then add the package to GitHub:
cd '~/addons'
git add gramps{{Stable_branch}}/download/NewProjectName.addon.tgz
git commit -m "Added new plugin: NewProjectName"
or (for the master branch);
cd '~/addons' git add gramps61/download/NewProjectName.addon.tgz git commit -m " Added new plugin: NewProjectName"
List your addon in the Gramps Plugin Manager
|
Gramps needs to have been built Make sure you have already built gramps60 or master. Change to the appropriate git branch in your gramps directory, and run |
To create a listing:
cd '~/gramps-addons'or wherever you have built your addonGRAMPSPATH=path/to/your/gramps/install ./make.py gramps60 listing NewProjectName
or (for the master branch);
cd '~/gramps-addons'or wherever you have built your addonGRAMPSPATH=path/to/your/gramps/install ./make.py gramps61 listing NewProjectName
That will create a series of files in the ../listings/ directory.
Then add the updated listing to GitHub:
cd '~/addons'
git add gramps{{Stable_branch}}/listings/*
git commit -m "Added new plugin to listings: NewProjectName"
or (for the master branch);
cd '~/addons' git add gramps61/listings/* git commit -m " Added new plugin to listings: NewProjectName"
List and document your addon on the wiki
List your addon
Add a short description of your addon to the Addons list by editing the current release listing eg: 6.0_Addons or if the addon is meant for a future release 6.1_Addons when available.
Example addon template
Examine the listing for other addons and refer to the Addon list legend for details of on the meaning of each columns.
|- <!-- 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 of Addon:NewProjectName examine the other addon support pages for the general format to use.
Example addon article
Consider including the following information:
<!-- 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-->
<!--sections only add if needed-->
== Usage ==
=== Configure Options ===
==Features==
== Prerequisites ==
== Issues ==
<!--default categories-->
[[Category:Addons]]
[[Category:Plugins]]
[[Category:Developers/General]]
Announce the addon
Join the Gramps Forum and announce it to the users with general information on why you created and how to use it.
Support it through issue tracker
Become a user on the Gramps MantisBT (Mantis BugTracker). and please check it regularly. There is no automated notification of issues (and 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 the code as Gramps continues to evolve
|
When submitting an update the patch part of the version number MAJOR.MINOR.PATCH is updated during the addon build process e.g. 1.1.3 to 1.1.4 This means when your plugin has become part of the default gramps addons there is no need to run `make` yourself as it is part of the regular addon build process. You can find this step in addons-source/make.py.[1] |
Remember that Gramps addons exist for many reasons and there are many Gramps developers that do support addons in various ways (translations, triage, keeping in sync with master, download infrastructure, etc).
Some 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 (eg, Data Entry Gramplet).
- A place for experimental components to live.
Example code adding common enhancements
- Copy all the Gramplet's output to a system clipboard via context pop-up menu : Enhancement request 11573, example pull
- add a custom View Mode toolbar icon via the
.gpr.py: Pull 1017 Discussion, example Pull
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 example code:
- of a custom filtering option)
- toolbar: Photo Tagging gramplet - documentation (source)
- 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

