Changes

Jump to: navigation, search

Addons development

5,176 bytes added, 21:54, 5 August 2015
List and document your addon on the wiki
''{{out of date}}{{man warn|Warning:|This page documents the API, methods, and best practices for developing an a 3rd-party addon for GRAMPS Gramps 3.2, due March 2010.''and later }}
= Addons development =for Gramps can extend the program in many different ways. You can add any of the following [http://sourceforge.net/p/gramps/source/ci/master/tree/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 types of addons:#Report# Doc creatorQuickreport# ExporterTool# GrampletImporter# ImporterExporter# Map serviceDoc creator# Plugin lib# QuickreportMap service# RelationshipsGramps View# ReportRelationships# ToolGramplet# ViewSidebar
Writing an addon is fairly straightforward if you have just a little bit of Python experience. And sharing your addon is the right thing to do. The general steps to writing an addon and sharing your own addons are:
# Package your addon
# List and document your addon
# Support it through the issue tracker# Maintain the code as GRAMPS Gramps continues to evolve
We'll now look at each of these steps in detail.
== Develop your addon ==
===Gramps 4.1 and earlier=== The [http://svn.code.sf.net/p/gramps-addons /code/ gramps-addons] subversion repository has the following structure:
* /gramps-addons
*** /download
** /branches
*** /gramps33gramps41*** /gramps32gramps34
**** /contrib
**** /download
The contrib subdirectories hold the source code for the addons for a particular version. If you are working on a addon for gramps33 <code>gramps41</code> then you should be working in <code>gramps-addons/branches/gramps33gramps41/contrib</code>. If you are working in gramps {{man warn|Note|that Gramps/trunk then is no longer used on Sourceforge. To work on Gramp/master you should will need to switch to Github and use [https://github.com/gramps-project/addons-source addons-source] See below}} ===Gramps 4.2 and later=== The [http://github.com/gramps-project/addons-source addons-source] git repository has the following structure: * /addons-source** /''IndividualNameOfAddon1''** /''IndividualNameOfAddon2''** ... The [http:/trunk/contribgithub.com/gramps-project/addons addons] git repository has the following structure: * /addons** /gramps42*** /download*** /listings** /gramps50*** /download*** /listings
These steps show how to download and work addon-source holds the source code for the addons with branches holding the version for different gramps. If you are working on a addon development toolsfor gramps for gramps42 or later then you should be working in addons-source.
# Checkout ==== Setup the gramps-addons files from the [https://sourceforge.net/projects/gramps-addons/ gramps-addons] project:## cd into gramps trunk, addon development tools for example:### cd ~/gramps/trunk## Checkout gramps-addons:### svn co https://gramps-addons.svn.sourceforge.net/svnroot/gramps-addons gramps-addons## Change to trunk or branches/gramps33 directory:### cd gramps-addons/branches/gramps33/contrib# Make a new project directory in gramps-addon/branches/gramps33/contrib:## mkdir NewProjectName# Initialize the addon:## ./makeGramps 4.py init NewProjectName1 and earlier ====
NOTE: These steps show how to use makedownload and work with the addon development tools.py as shown throughout this document, you may have to use:
{{man tip| 1=Tip |2=To use make.py as shown throughout this document, you may have to use:<br /><pre>GRAMPSPATH=/path/to/gramps python make.py ...</pre> <br /> if the default ("../../..") is not correct.}}
if * Checkout the default ("gramps-addons files from the [https://sourceforge.net/projects/gramps-addons/ gramps-addons] project:** cd into gramps trunk, for example:*** <pre>cd ~/gramps/trunk</pre>** Checkout gramps-addons:*** <pre>svn co https://svn./code.sf.net/p/gramps-addons/code gramps-addons</pre>** Change to trunk or branches/gramps41 directory:*** <pre>cd gramps-addons/branches/gramps41/contrib</pre>* Make a new project directory in gramps-addon/branches/gramps41/contrib:** <pre>mkdir NewProjectName</pre>* Initialize the addon:** <pre>./make.") is not correct.py init NewProjectName</pre>
===Follow the development API for your tool===Follow the development API for your tool, [[Report-writing_tutorial|report]], view, or [[Gramplets]]. Place all of your associated .py, .glade, etc. files in this directory. For general information on GRAMPS Gramps development see [[Portal:Developers]] and [[Writing a Plugin]] specifically.
=== Test your addon as you develop ===To test your addon as you develop it it is suggested that you replace your GRAMPS Gramps user plugin directory with a link to your addon development directory, like so:
cd ~/.gramps/gramps33gramps41/ mv plugins/* /wherever/trunk/gramps-addons/branches/gramps33gramps41/contrib/
rm -rf plugins
ln -s /wherever/trunk/gramps-addons/branches/gramps33gramps41/contrib plugins
GRAMPS Gramps will search this folder (and subdirectories) for .grp.py files, and add them to the plugin list.
If you have code that you want to share between addons, you don't need to do anything special. Currently, GRAMPS Gramps adds each directory in which a .gpr.py is found onto the PYTHONPATH which is searched when you perform an import. Thus "import NewProjectName" will work from another addon. You should always make sure you name your addons with a name appropriate for Python imports.
=== Commit your changes ===To commit your changes so that others can use your addon, .====Gramps 4.1 and earlier====For Gramps 4.1 and earlier follow these steps:
# Get an http://sourceforge.net account if you don't already have one.
# Request SVN write access for the gramps-addon project by emailing one of the admins of the project (listed under the gramps-addon title next to the group icon) from httpshttp://sourceforge.net/projectprojects/gramps-addons/memberlist.php?group_id=285429
# Remove the files that should not be added to SVN:
## <pre>./make.py clean NewProjectName</pre>
# Add the project to the repository:
## <pre>svn add NewProjectName</pre>## <pre>svn commit -m "A message describing what this addon is"</pre>
Before making additional edits to your addon, you should:
# <pre>svn update</pre># <pre>svn status</pre># <pre>svn commit -m "A message describing the changes"</pre> Also you may want to [[Addons_development#Package_your_addon |Package your addon]] so it can be downloaded via the plugin manager. ====Gramps 4.2 and later====For Gramps 4.2 and later follow these steps:# Get an https://github.com/join account if you don't already have one.# Request GIT write access for the https://github.com/gramps-project/addons-source project by emailing the [[Contact#Mailing_lists|gramps-devel mailing list]]See also [[Brief_introduction_to_Git|git introduction]].  git clone [email protected]:gramps-project/addons-source.git addons-source or if you do not have a Github account:  git clone https://github.com/gramps-project/addons-source.git addons-source To switch to a local copy of the gramps42 branch:  git checkout -b gramps42 origin/maintenance/gramps42
=== Config ===
Some addons may want to have persistent data (data settings that remain between sessions). You can handle this yourself, or you can use Gramps' built-in configure system.
In At the top of the source file that defines the settingsof your addon, you would do this:
from config import configas configman cm config = configconfigman.register_manager("view_placetreeview_0grampletname") cm# register the values to save: config.register("section.variable1option-name1", value1) cmconfig.register("section.variable2option-name2", value2)
...
cm# load an existing file, if one: config.initload() # 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.
This will create the file "view_placetreeview_0.ini" and put in the same directory as the addon. In the addon, you can then:
x = cmconfig.get("section.variable1option-name1") cmconfig.set("section.variable1option-name1", 3)
and when this code is exiting, you might want to save the config. In a Gramplet that would be:
def on_save(self):
cmconfig.save()
If your code is a system-level file, then you might want to save the config in the Gramps system folder:
cm config = configconfigman.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 configas configman cm config = configconfigman.get_manager("view_placetreeview_0grampletname") x = cmconfig.get("section.variable1option-name1")
=== Localization ===
For any addon which you have translations into other languages, you will need to add a way to retrieve the translation. You need to add this to the top of your NewProjectName.py file:
==== For Gramps 3: ====
from TransUtils import get_addon_translator
_ = get_addon_translator(__file__).gettext
 
==== For Gramps 4: ====
 
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.get_addon_translator(__file__).gettext
<pre>
from TransUtils import get_addon_translator
_ = get_addon_translator().gettext
</pre>
Then you can use the standard "_()" function to translate phrases in your addon.
You can use one of a few different types of translation functions:
# gettext
# lgettext
# ngettext
# lngettext
# ngettextsgettext Gramps 3 also provides: 
# ugettext
# ungettext
NOTE: currently we don;t These have a method of using a context become obsolete in any of these functions. The translation functions that are supported are defined as follows.  '''gettext(message)''' If a fallback has been set, forward Gramps 4; gettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes. '''lgettext(message)''' If a fallback has been set, forward lgettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes. '''ugettext(message)''' If a fallback has been set, forward ugettext() to the fallback. Otherwise, return the translated message as a Unicode string. Overridden in derived classes. '''ngettext(singular, plural, n)''' If a fallback has been set, forward ngettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes. '''lngettext(singular, plural, n)''' If a fallback has been set, forward ngettext() to the fallback. Otherwise, and sgettext always return the translated message. Overridden strings in derived classesunicode for consistent portability between Python 2 and Python3.
'''ungettext(singular, plural, n)'''See the [http://docs.python.org/3/library/gettext.html#the-gnutranslations-class python documentation] for documentation of gettext and ngettext. The "l" versions return the string encoded according to the [http://docs.python.org/3/library/locale.html#locale.setlocale currently set locale]; the "u" versions return unicode strings in Python2 and are not available in Python 3.
If '''sgettext''' is a fallback has been setGramps extension that filters out clarifying comments for translators, forward ungettextsuch as _("Remaining names | rest") Where "rest" is the English string that we want to the fallback. Otherwise, return the translated message as present and "Remaining names" is a Unicode string. Overridden in derived classeshint for translators.
== Create a Gramps Plugin Registration file ==
<pre>
register(PTYPE,
gramps_target_version = "3.34",
version = "1.0.0",
ATTR = value,
</pre>
[http://sourceforge.net/p/gramps/source/ci/master/tree/gramps/gen/plug/_pluginreg.py#l78 PTYPE ] is TOOL, GRAMPLET, REPORT, QUICKREPORTQUICKVIEW, IMPORT, EXPORT, DOCGEN, GENERAL, MAPSERVICE, VIEW, or RELCALC. 
ATTR depends on the PTYPE. But you must have '''gramps_target_version''' and '''version'''. gramps_target_version should be a string of the form "X.Y" version number matching Gramps X major, Y minor integer. version is a string of the form "X.Y.Z" representing the version of your addon. X, Y, and Z should all be integers.
description = _("Attaches a shared source to multiple objects."),
version = '1.0.0',
gramps_target_version = '3.34',
status = STABLE,
fname = 'AttachSourceTool.py',
</pre>
You can see examples of the kinds of addons [http://gramps.svn.sourceforge.net/viewvcp/gramps/trunksource/ci/master/tree/srcgramps/plugins/ here] (for example, see [http://gramps.svn.sourceforge.net/viewvcp/gramps/trunksource/ci/srcmaster/tree/gramps/plugins/drawreport/drawplugins.gpr.py?view=markup trunkgramps/srcsource/ci/master/tree/gramps/plugins/drawreport/drawreportdrawplugins.gpr.py]) and see the full documentation [http://gramps.svn.sourceforge.net/viewvcp/gramps/trunksource/srcci/master/tree/gramps/gen/plug/_pluginreg.py?view=markup here] in the comments and docstrings.
Note that this .gpr.py will automatically use translations if you have them (see below). That is, the function "_" is predefined to use your locale translations; you only need to mark the text with _("TEXT") and include a translation of "TEXT" in your translation file. For example, in the above example, _("Attach Source") is marked for translation. If you have developed and packaged your addon with translation support, then that phrase will be converted into the user's language.
 
=== Report plugins ===
The possible report categories are (gen/plug/_pluginreg.py):
<pre>
#possible report categories
CATEGORY_TEXT = 0
CATEGORY_DRAW = 1
CATEGORY_CODE = 2
CATEGORY_WEB = 3
CATEGORY_BOOK = 4
CATEGORY_GRAPHVIZ = 5
REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE,
CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ]
</pre>
 
Each report category has a set of standards and interface. The categories CATEGORY_TEXT and CATEGORY_DRAW use the Document interface of Gramps. See also [[Report API]] for a draft view on this.
The application programming interface or API for reports is treated at [[Report-writing_tutorial]]. For general information on Gramps development see [[Portal:Developers]] and [[Writing a plugin]] specifically.
=== General plugins ===
description = _("Provides a library for doing something."),
version = '1.0',
gramps_target_version = '3.34',
status = STABLE,
fname = 'library.py',
category = "WEBSTUFF",
version = '1.0',
gramps_target_version = '3.34',
data = ["a", "b", "c"],
)
description = _("Provides a collection of stylesheets for the web"),
version = '1.0',
gramps_target_version = '3.34',
fname = "stylesheet.py",
load_on_reg = True,
== Get translators to translate your addon into multiple languages ==
# * Initialize and update the template.pot for your addon:## ** <pre>./make.py init NewProjectName</pre># * Initialize a language for your addon (say French, fr):## ** <pre>./make.py init NewProjectName fr</pre># * Update it from gramps and other addons:## ** <pre>./make.py update NewProjectName fr</pre># * Edit <pre>contrib/NewProjectName/po/fr-local.po</pre># * Compile the language:## ** <pre>./make.py compile NewProjectName</pre># * Add or update your local language file, and commit changes:## ** <pre>svn add NewProjectName/po/fr-local.po</pre>## ** <pre>svn commit NewProjectName/po/fr-local.po -m "Added fr po file"</pre>
== Package your addon ==
python make.py build NewProjectName
That This will automatically include the following files in your build and copy your addon to ../download:
NOTE: Running the '''make* *.py build''' will increment the third number in your dotted version number of all addons in the gpr* *.py fileglade* *.xml* *. Consider this number to be a "build number"txt* locale/*/LC_MESSAGES/*.mo
''New for Gramps 3Starting with Gramp 5.3'': You need to then make 0, if you have additional files beyond those listed above, you should create a MANIFEST file in the root of your addon available in listings of various languages. To do thatfolder listing the files (or pattern) one per line, like this sample MANIFEST file:
python make<pre>README.py listingmdextra_dir/*help_files/docs/help.html</pre>
That {{man note|Note:|Running the command '''make.py build''' will create a series increment the third number in your dotted version number of files all addons in the gpr.py file. Consider this number to be a "build number"./listings/ }}
Then add the package to SVN:
svn add ../download/NewProjectName.addon.tgz ../listings/*
cd ..
svn commit -m "Message describing changes"
 
== List your addon in the Gramps Plugin Manager==
''New for Gramps 3.4'': You need to then make your addon available in listings of various languages.
 
{{man warn|Gramps needs to have been built|Make sure you have already built gramps34 or gramps41 or master}}
 
To create a listing:
 
cd gramps-addons/branches/gramps41/contrib # or wherever you have built your addon
GRAMPSPATH=path/to/your/gramps/install python make.py listing NewProjectName
 
That will create a series of files in the <tt>../listings/</tt> directory.
 
Then add the updated listing to SVN:
 
svn add ../listings/*
cd ..
svn commit -m "Message describing changes"
 
== List and document your addon on the wiki==
 
Document the addon in the wiki using the name {{man menu|Addon:NewProjectName}}.
 
Edit [[Plugins3.4]] or [[4.2_Addons]] and describe your addon.
 
You can point to the addon.tgz in SVN or GIT as the downloadable file.
== Miscellaneous commands ==
To build and compile translations for all projectsto their download/Addon.addon.tgz files:
python make.py build all
To compile translations for all projects to their download/Addon.addon.tgz files:
python make.py compile all
== List and document your addon Support it through issue tracker ==
Edit [[Plugins3Visit https://gramps-project.3]] org/bugs/view_all_bug_page.php and describe your addonbecome a user. You can point Suggest to the addon.tgz in SVN as the downloadable file. Document the addon in the wiki using the name "Addon:NewProjectName"check it regularly.
== Support it through issue tracker Maintain the code as Gramps continues to evolve ==
Visit http://www.gramps-project.org/bugs/view_all_bug_page.php Remember that Gramps addons exist for many reasons and become a user. Suggest to check it regularlythere are manyGramps developers that do support addons in various ways (translations,triage, keeping in sync with master, download infrastructure, etc).
== Maintain Some reasons why the code as GRAMPS continues addons exist; they provide:* A quick way for anyone to evolve ==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.
= Resources =
* [[Brief_introduction_to_Git|Git introduction]]
 
;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 3.2 to Gramps 4.1.* httphttps://gramps-addons.svn.sourceforge.net/viewvcp/gramps-addons/ - Source code (SVN browse) and downloadable .tgz files
[[Category:Developers/General]]
[[Category:Developers/Tutorials]]
[[Category: Plugins]][[Category:Reports]][[Category:Gramplets]][[Category:Addons]]

Navigation menu