danielebarchiesi@0:
APIs are a form of plugins that are tightly associated with a module. Instead of a module providing any number of plugins, each module provides only one file for an API and this file can contain hooks that the module should invoke.
danielebarchiesi@0: danielebarchiesi@0:Modules support this API by implementing hook_ctools_plugin_api($module, $api). If they support the API, they return a packet of data:
danielebarchiesi@0: danielebarchiesi@0:danielebarchiesi@0: function mymodule_ctools_plugin_api($module, $api) { danielebarchiesi@0: if ($module == 'some module' && $api = 'some api') { danielebarchiesi@0: return array( danielebarchiesi@0: 'version' => The minimum API version this system supports. If this API version is incompatible then the .inc file will not be loaded. danielebarchiesi@0: 'path' => Where to find the file. Optional; if not specified it will be the module's directory. danielebarchiesi@0: 'file' => an alternative version of the filename. If not specified it will be $module.$api.inc danielebarchiesi@0: ); danielebarchiesi@0: } danielebarchiesi@0: } danielebarchiesi@0:danielebarchiesi@0: danielebarchiesi@0:
This implementation must be in the .module file.
danielebarchiesi@0: danielebarchiesi@0:Modules utilizing this can invole ctools_plugin_api_include() in order to ensure all modules that support the API will have their files loaded as necessary. It's usually easiest to create a small helper function like this:
danielebarchiesi@0: danielebarchiesi@0:danielebarchiesi@0: define('MYMODULE_MINIMUM_VERSION', 1); danielebarchiesi@0: define('MYMODULE_VERSION', 1); danielebarchiesi@0: danielebarchiesi@0: function mymodule_include_api() { danielebarchiesi@0: ctools_include('plugins'); danielebarchiesi@0: return ctools_plugin_api_include('mymodule', 'myapi', MYMODULE_MINIMUM_VERSION, MYMODULE_VERSION); danielebarchiesi@0: } danielebarchiesi@0:danielebarchiesi@0: danielebarchiesi@0:
Using a define will ensure your use of version numbers is consistent and easy to update when you make API changes. You can then use the usual module_invoke type commands:
danielebarchiesi@0: danielebarchiesi@0:danielebarchiesi@0: mymodule_include_api(); danielebarchiesi@0: module_invoke('myhook', $data); danielebarchiesi@0:danielebarchiesi@0: danielebarchiesi@0:
If you need to pass references, this construct is standard:
danielebarchiesi@0: danielebarchiesi@0:danielebarchiesi@0: foreach (mymodule_include_api() as $module => $info) { danielebarchiesi@0: $function = $module . '_hookname'; danielebarchiesi@0: // Just because they implement the API and include a file does not guarantee they implemented danielebarchiesi@0: // a hook function! danielebarchiesi@0: if (!function_exists($function)) { danielebarchiesi@0: continue; danielebarchiesi@0: } danielebarchiesi@0: danielebarchiesi@0: // Typically array_merge() is used below if data is returned. danielebarchiesi@0: $result = $function($data1, $data2, $data3); danielebarchiesi@0: } danielebarchiesi@0:danielebarchiesi@0: danielebarchiesi@0:
TODO: There needs to be a way to check API version without including anything, as a module may simply danielebarchiesi@0: provide normal plugins and versioning could still matter.