Changes

Jump to: navigation, search

Addons development

8,367 bytes added, 05:46, 1 June 2016
Test your addon as you develop: remove space
''{{man warn|Warning:|This page documents the API, methods, and best practices for developing an 3rda [[Third-party addon Addons|Third-party Addon]] for GRAMPS 3Gramps 4.2and later. For 4.2 and earlier, due March 2010see [[Addons_development_old]].''}}
= Addons development =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:
Addon's 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.
Note that this wiki expects that addons are developed under Linux; while it is possible to do so under Windows, some of the steps will vary and the process has not been fully debugged, so user beware.
== Develop your addon ==
The [http://github.com/gramps-project/addons subversion -source addons-source] git repository has the following structure:
* /addons-source** /''IndividualNameOfAddon1''** /''IndividualNameOfAddon2''** ... The [http://github.com/gramps-project/addonsaddons] git repository has the following structure: ** /trunkaddons*** /contribgramps42
*** /download
*** /brancheslistings*** /gramps32gramps50**** /contribdownload**** /downloadlistings
The contrib subdirectories hold '''addon-source''' repository holds the source code for the addons with branches holding the version for a particular versiondifferent gramps. If you are working on a an addon for gramps32 then you should gramps for gramps42, be working in gramps-addons/branches/gramps32/contribsure to use the gramps42 git branch, as the default is master branch (currently gramsp 5.x). If you Example commands are working in gramps/trunk then you should use gramps-addons/trunk/contribshown below.
These steps show how Once you have your addon working in one branch, (say gramps42), then you will also want to copy it to the other branch (master), after you have tested it to download work properly and work with edited the addon development tools'.gpr.py' file appropriately.
# Checkout the gramps-=== Get a local copy of Gramps and its addons files from the [https://sourceforge.net/projects/gramps-addons/ gramps-addons] project:## cd into gramps trunk, 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/gramps32 directory:### cd gramps-addons/branches/gramps32/contrib# Make a new project directory in gramps-addon/branches/gramps32/contrib:## mkdir NewProjectName# Initialize the addon:## ./make.py init NewProjectName===
NOTE: These steps show how to use makedownload the addon sources.py as shown throughout this document, you may have to use:
GRAMPSPATH=# Get an https:/path/togithub.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 python make-devel mailing list]]See also [[Brief_introduction_to_Git|git introduction]] for instructions on installing git and getting basic settings configured.py Also https://help.github.com/articles/generating-an-ssh-key/ 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'.
if This wiki assumes that the default ("../../..") is not correctthree git repositories local locations are all to be put into the users' home directory and named with the repository names.
Follow The three directories '''must''' be named as shown, and in the development API same base directory in order for your tool, [[Report-writing_tutorial|report]], view, or [[Gramplets]]. Place all of your associated the make.pyscript to work properly, .glade, etc. files however they don't have to be located directory in this the users home directory. For general information on GRAMPS development see [[Portal:Developers]] and [[Writing a Plugin]] specifically.
To test From your addon as you develop it it is suggested that you replace your GRAMPS user plugin directory with a link to your addon development home directory, like so:;
cd ~/git clone git@github.com:gramps-project/gramps32/addons-source.git addons-source mv plugins/* /wherever/trunk/git clone [email protected]:gramps-project/addons.git addons/branches/gramps32/contrib/ rm git clone [email protected]:gramps-rf plugins ln -s /wherever/trunkproject/gramps-addons/branches/gramps32/contrib plugins.git gramps
GRAMPS will search this folder (and subdirectories) for .grp.py files, and add them to the plugin list.or if you do not have a Github account:
If you have code that you want to share between git clone https://github.com/gramps-project/addons, you don't need to do anything special-source. Currently, GRAMPS adds each directory in which a git addons-source git clone https://github.gprcom/gramps-project/addons.py is found onto the PYTHONPATH which is searched when you perform an importgit addons git clone https://github. Thus "import NewProjectName" will work from another addon. You should always make sure you name your addons with a name appropriate for Python importscom/gramps-project/gramps.git gramps
To commit This will create a copy of the addons-source tree in your changes so that others can use your addonhome directory at "~/addons-source", follow these steps:and the other trees at their respective locations as well.
# Get an http://sourceforge.net account if you don't already have one.# Request SVN write access for the gramps-addon project from https://sourceforge.net/project/memberlist.php?group_id=285429# Remove the files that should not be added to SVN:## ./make.py clean NewProjectName# Add the project To switch to a local copy of the repositorygramps42 branch:## svn add NewProjectName## svn commit -m "A message describing what this addon is"
Before making additional edits to your addon, you should: cd addons-source git checkout -b gramps42 origin/maintenance/gramps42
# svn updateor to work in the master branch:  cd addons-source git checkout -b gramps42 origin/master === Other pre-requisites ===* 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.* 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;: <code>sudo apt-get install intltool</code> For example if your home directory is '/home/name' and you use the suggested path names, use: <code>GRAMPSPATH=/home/name/gramps LANGUAGE='en_US.UTF-8' python3 make.py ...</code>to replace the <code>./make.py</code> in the examples below. === Create your addon subdirectory ===* Make a new project directory in addons-source:: <code>mkdir NewProjectName</code> ===Follow the development API for your tool===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]] specifically. === Test your addon as you develop ===To test your addon as you develop it is suggested that you insert your NewProjectName plugin into your Gramps user plugin directory with a link to your addon development directory, like so:  cd ~/.gramps/gramps42/plugins ln -s ~/addons-source/NewProjectName NewProjectName 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. Currently, Gramps adds each directory in which a .gpr.py is found onto the PYTHONPATH which is searched when you perform an import. Thus "import NewProjectName" will work from another addon. You should always make sure you name your addons with a name appropriate for Python imports. === Commit your changes ===To commit your changes so that others can see your addon source. * Remove the files that should not be added to GitHub:: <code>./make.py gramps42 clean NewProjectName</code>* Add the project to the repository:: <code>git add NewProjectName</code>* Commit it with an appropriate message: <code>git commit -m "A message describing what this addon is"</code> Before committing additional edits to your addon, you should: * to make sure that outside changes do not affect your commit: <code>git pull --rebase</code>* only the files you changed should be in this list# svn : <code>git status</code>* Commit it with an appropriate message# svn : <code>git commit -m "A message describing the changes"</code> 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: <code>git pull --rebase</code>: <code>git push origin gramps42</code> Also you may want to [[Addons_development#Package_your_addon |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' 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:
<pre> from TransUtils gramps.gen.const import get_addon_translatorGRAMPS_LOCALE as glocale _ = glocale.get_addon_translator(__file__).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
# ngettext# ugettext# ungettext NOTE: currently we don;t have a method of using a context in any of these functions. The translation functions that are supported are defined as follows.  '''gettext(message)''' If a fallback has been set, forward gettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes. '''lgettext(message)''' If a fallback has been set, forward lgettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes. '''ugettext(message)'''sgettext
If a fallback has been setThese have become obsolete in Gramps 4; gettext, forward ugettext() to the fallback. Otherwisengettext, and sgettext always return the translated message as a Unicode string. Overridden strings in derived classesunicode for consistent portability between Python 2 and Python3.
'''See the [http://docs.python.org/3/library/gettext.html#the-gnutranslations-class python documentation] for documentation of gettext and ngettext(singular, plural, n)'''. 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 a fallback has been set, forward ngettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes. '''lngettext(singular, plural, n)sgettext''' If is a fallback has been setGramps extension that filters out clarifying comments for translators, forward ngettext() to the fallback. Otherwise, return the translated message. Overridden in derived classes.such as '''ungettext _(singular, plural, n"Remaining names | rest")''' If a fallback has been set, forward ungettext() 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 = "34.2",
version = "1.0.0",
ATTR = value,
</pre>
[https://github.com/gramps-project/gramps/blob/master/gramps/gen/plug/_pluginreg.py#L76 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.
Here is a sample Tool GPR file:
description = _("Attaches a shared source to multiple objects."),
version = '1.0.0',
gramps_target_version = '34.2',
status = STABLE,
fname = 'AttachSourceTool.py',
</pre>
You can see examples of the kinds of addons [httphttps://gramps.svn.sourceforgegithub.netcom/viewvcgramps-project/gramps/trunk/src/plugins/ here] (for example, see [httphttps://gramps.svn.sourceforgegithub.netcom/viewvcgramps-project/gramps/trunk/src/plugins/drawreport/drawplugins.gpr.py?view=markup trunk/srcgramps/plugins/drawreport/drawreportdrawplugins.gpr.py]) and see the full documentation [httphttps://grampsgithub.svn.sourceforge.netcom/viewvcgramps-project/gramps/trunk/src/gen/plug/_pluginreg.py?view=markup here] in the comments and docstrings.
Note that this .gpr.py will automatically use translations if you have them (see below). That is, the function "_" is predefined to use your locale translations; you only need to mark the text with _("TEXT") and include a translation of "TEXT" in your translation file. For example, in the above example, _("Attach Source") is marked for translation. If you have developed and packaged your addon with translation support, then that phrase will be converted into the user's language.
=== Report plugins ===The possible report categories are (gen/plug/_pluginreg.py):<pre>#possible report categoriesCATEGORY_TEXT = 0CATEGORY_DRAW = 1CATEGORY_CODE = 2CATEGORY_WEB = 3CATEGORY_BOOK = 4CATEGORY_GRAPHVIZ = 5REPORT_CAT = [ CATEGORY_TEXT, CATEGORY_DRAW, CATEGORY_CODE, CATEGORY_WEB, CATEGORY_BOOK, CATEGORY_GRAPHVIZ]</pre> Each report category has a set of standards and interface. The categories CATEGORY_TEXT and CATEGORY_DRAW use the Document interface of Gramps. See also [[Report API]] for a draft view on this. The application programming interface or API for reports is treated at [[Report-writing_tutorial]]. For general information on Gramps development see [[Portal:Developers]] and [[Writing a plugin]] specifically. === General Plugins plugins ===
The plugin framework also allows you to create generic plugins for use. This includes the ability to create libraries of functions, and plugins of your own design.
==== Example: A Library library of Functions functions ====
In this example, a file name library.py will be imported at time of registration (when Gramps starts):
description = _("Provides a library for doing something."),
version = '1.0',
gramps_target_version = '34.32',
status = STABLE,
fname = 'library.py',
Here, you could connect signals to the dbstate, open windows, etc.
Another example of what one can do with the plugin interface is to create a general purpose plugin framework for use by other plugins. Here is the basis for a plugin system that: * allows plugins to list data files* allows the plugin to process all of the data files First, the gpr.py file: <pre> register(GENERAL, id = "ID", category ="CATEGORY", load_on_reg =True, process = Registered "FUNCTION_NAME", )</pre> This example uses three new features: # GENERAL plugins can have a category# GENERAL Categories ===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:
The following are the known secondary plugins (type GENERAL, with the following categories):<pre># anew.gpr.py
* register(GENERAL, id = 'a new plugin', category = "CSSWEBSTUFF", version = '1.0', gramps_target_version = '5.0',* data = ["Filter: Persona", "Filter: Familyb", "Filter: Sourcec"], etc. )</pre>
For exampleThis doesn't have load_on_reg = True, nor does it have a fname or process, but it does set the data directly in the .gpr.py file. Then we have the following results:
<pre>
register>>> from gui.pluginmanager import GuiPluginManager>>> PLUGMAN = GuiPluginManager.get_instance()>>> PLUGMAN.get_plugin_data(GENERAL'WEBSTUFF')["a", "b", "c", category="CSSStylesheet.css","Another.css"] >>> PLUGMAN.process_plugin_data('WEBSTUFF')["A", "B", "C", "STYLESHEET.CSS", "ANOTHER.)CSS"]
</pre>
==== Example: A plugin for other plugins =Registered GENERAL Categories ===
Another example of what one can do with The following are the plugin interface is to create a general purpose plugin framework for use by other published secondary plugins. Here is API's (type GENERAL, with the basis for a plugin system thatfollowing categories):
* allows plugins to list data files* allows the plugin to process all of the data files==== WEBSTUFF ====
First, the A sample gpr.py file:
<pre>
register(GENERAL,
id = 'system stylesheets',
category = "CSSWEBSTUFF",
name = _("CSS Stylesheets"),
description = _("Provides a collection of stylesheets for the web"),
version = '1.0',
gramps_target_version = '35.30',
fname = "stylesheet.py",
load_on_reg = True,
)
</pre>
 
This example uses three new features:
 
# GENERAL plugins can have a category
# GENERAL plugins can have a load_on_reg function that returns data
# GENERAL plugins can have a function (called "process") which will process the data
Here is the associated program:
</pre>
These functions can be accessed through the PluginManager, by the name of the category given, 'CSS'==== Filters ==== For example:
<pre>
>>> from gui.pluginmanager import GuiPluginManagerregister(GENERAL,>>> PLUGMAN category= GuiPluginManager.get_instance()>>> PLUGMAN.get_plugin_data('CSS')["Stylesheet.cssFilters", "Another.css"]>>> PLUGMAN .process_plugin_data('CSS')["STYLESHEET.CSS", "ANOTHER.CSS"] load_on_reg = True)
</pre>
 
If you (or someone else) create additional 'CSS' general plugins, 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 'CSS' category:
<pre>
def load_on_reg(dbstate, uistate, plugin): # anewreturns a function that takes a namespace, 'Person', 'Family', etc.gpr.py
register def filters(GENERAL, namespace): id = 'a new plugin', category = print "CSSOk...", version = '1plugin.0'category, gramps_target_version = '3.3'namespace,uistate data = [" # return a", "b", "c"],Filter object here ) return filters
</pre>
This doesn't have load_on_reg = True= Get translators to translate your addon into multiple languages == * Initialize and update the template.pot for your addon:: <code>cd ~/addons-source</code>: <code>./make.py gramps42 init NewProjectName</code>* You should edit the header of template.pot with your information, nor does so it have gets copied to individual language files.* Initialize a fname or processlanguage for your addon (say French, but fr):: <code>./make.py gramps42 init NewProjectName fr</code>* Update it does set from gramps and other addons:: <code>./make.py gramps42 update NewProjectName fr</code>* Edit the data directly in translations file manually:: <code>/NewProjectName/po/fr-local.po</code>* Compile the language:: <code>.gpr/make.py gramps42 compile NewProjectName</code>* Add or update your local language file, and commit changes:: <code>git add NewProjectName/po/fr-local. Then we po</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;: <code>git push origin gramps42</code> == Package your addon == To create a downloadable package: : <code>./make.py gramps42 build NewProjectName</code> or: <code>./make.py gramps50 build NewProjectName</code> for the master branch. Note that the  This will automatically include the following resultsfiles 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:
<pre>
>>> PLUGMANREADME.get_plugin_data('CSS')md["a", "b", "c", "Stylesheet.css", "Another.css"]extra_dir/*>>> PLUGMAN.process_plugin_data('CSS')["A", "B", "C", "STYLESHEET.CSS", "ANOTHERhelp_files/docs/help.CSS"]html
</pre>
== Get translators {{man note|Note:|Running the command '''make.py xxx build''' will increment the third number in your dotted version number of all addons in the gpr.py file. Consider this number to translate be a "build number".}} 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.: <code>rm –rf –v 'NewProjectName/locale'</code> Then add the package to GitHub:  <pre> cd '~/addons' git add gramps42/download/NewProjectName.addon.tgz git commit -m "Added new plugin: NewProjectName"</pre>or (for the master branch);<pre> cd '~/addons' git add gramps50/download/NewProjectName.addon into multiple languages ==.tgz git commit -m " Added new plugin: NewProjectName"</pre> 
# Initialize and update the template.pot for your addon:## ./make.py init NewProjectName# Initialize a language for == List your addon (say French, fr):## ./make.py init NewProjectName fr# Update it from gramps and other addons:## ./make.py update NewProjectName fr# Edit contrib/NewProjectName/po/fr-local.po# Compile in the language:## ./make.py compile NewProjectName# Add or update your local language file, and commit changes:## svn add NewProjectName/po/fr-local.po## svn commit NewProjectName/po/fr-local.po -m "Added fr po file"Gramps Plugin Manager==
== Package {{man warn|Gramps needs to have been built|Make sure you have already built gramps42 or master. Change to the appropriate git branch in your addon ==gramps directory, and run 'python3 setup.py build' See [[Linux:Build_from_source]]}}
To create a downloadable packagelisting:
python : <code>cd '~/gramps-addons'</code> or wherever you have built your addon: <code>GRAMPSPATH=path/to/your/gramps/install ./make.py gramps42 listing NewProjectName</code>or (for the master branch);: <code>cd '~/gramps-addons'</code> or wherever you have built your addon: <code>GRAMPSPATH=path/to/your/gramps/install ./make.py build gramps50 listing NewProjectName</code>
That will build and copy your addon to create a series of files in the <tt>../downloadlistings/</tt> directory.
NOTE: Running the '''make.py build''' will increment the third number in your dotted version number of all addons in Then add the gpr.py file. Consider this number updated listing to be a "build number".GitHub:
<pre> cd '~/addons'New git add gramps42/listings/* git commit -m "Added new plugin to listings: NewProjectName"</pre>or (for Gramps 3.3the master branch);<pre> cd '~/addons': You need git add gramps50/listings/* git commit -m " Added new plugin to then make your addon available in listings of various languages. To do that:NewProjectName"</pre>
python make.py listing== List and document your addon on the wiki==
That will create a series of files Document the addon in the wiki using the name {{man menu|Addon:NewProjectName}}../listings/
Then add the package to SVN:Edit [[4.2_Addons]] or [[5.0_Addons]] and describe your addon.
svn add ../download/NewProjectName.You can point to the addon.tgz in GitHub as the downloadable file../listings/* cd .. svn commit -m "Message describing changes"
== Miscellaneous commands ==
To build and compile translations for all projectsto their download/Addon.addon.tgz files:
python : <code>python3 make.py gramps42 build all</code>
To compile translations for all projects to their download/Addon.addon.tgz files:
python : <code>python3 make.py gramps42 compile all</code>
== List and document your addon Support it through issue tracker ==
Edit [[Plugins3Visit https://gramps-project.2]] 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