How to extend CiviCRM’s functionality with custom features?
Before Civi 4.x, developers usually extended Civi functionality using Drupal modules. However, Civi works on top of Drupal, Joomla and Wordpress in multiple versions. (There’s also a standalone version of Civi in the works.) So, one important consideration when extending Civi functionality: how make it work with every underlying CMS?
Different CMSs use different names to describe pieces of code that can be snapped in for new functionality– e.g. modules, plug-ins, etc. Civi uses the term “extensions.”
1. Using Drupal (limited to Drupal, of course)
Drupal offers some ways to extend Civi without writing too much code. “Webforms” and “Views” are fairly well-developed; you can also use “Rules” and “Entities” (“a work in progress”).
2. Using templates, etc.
These templates can include simple PHP, can make API calls, etc. However, Civi recommends against doing too much fancy code work at this level.
Civi delivers its templates using Smarty. Usually this means one .php file and one .tpl file for each page you want to modify.
Best approach: define a path for custom templates and ADD a new (over-riding) template file. Avoid modifying the existing template!
You can write a full-bore extension either a) to modify or extend existing functionality, or b) to provide completely new functionality. The Create an extension page in documentation is a good place to start.
Civi’s community is small compared with, say, Drupal’s – so if two different developers want to build an extension with similar functionality, Civi might know about this and encourage them to work together. See Civi's "extensions" page for more information on available extensions.
Examples of extensions:
- Generate a custom “mail-merge” document. Ordinarily, Civi provides a set of tokens (name, date of donation, etc.) that can be used to generate a set of documents for a set of records. You can use extensions to create a custom token (say “Date of first donation” or “Total donations in the last FY”) to add to the list of existing tokens.
- Extend the functionality of a form: e.g., provide an entry field & appropriate functionality for a discount code, when the user is signing up for an event.
CiviCRM encourages developers to create extensions without CMS-specific calls, so that the extension will work for all CMSs.
Civi lets you extend an existing object by type (for example, you could create a subtype of “Organization” called “Committee”) - but you can’t create entirely new objects.
When you’re upgrading to a new version of Civi, you must test to ensure that your extensions still work. In general, they do. The author is responsible for tagging the version(s) with which the extension is compatible. (Civi’s Extension Manager won’t allow discovery for extensions that don’t have the appropriate version tag.)
Extensions work with hooks (in Joomla: “event system”) that the CMS provides, allowing call-outs to some custom piece of code when carrying out a specific task. In general, hooks must be implemented through an extension. (However, in Drupal, it could be done through a module. This could make sense if dealing with Drupal-specific data, e.g. the Drupal permissions system.) Multiple modules can be listening to the same hooks.
Naming convention: the hook referred to as hook_civicrm_buildform() for the volunteer entity would be called volunteer_civicrm_buildform().
Civi offers several dozen hooks, all well documented: see Civi hook reference
Unlike a hook, an API is a way of getting data into and out of Civi. Use of APIs for Civi is well-documented: see API reference
(Note that API explorer will actually make the call and show you the result – very helpful to be sure you’re getting what you expected without errors, but be sure you’re working on a test server, otherwise you might modify your production data!!)
Bundling up your extension
A new extension requires a lot of boilerplate code, for things like install, upgrade, hooks, menu, page, form. (Your particular extension may or may not need all of this boilerplate.) A new tool, “Civix,” helps you generate that boilerplate code, including the directory structure. It’s a command-line tool, available on GitHub.