Many CiviCRM customizations have been packaged and distributed as Drupal modules. This can be desirable when a customization delves into both the CMS and CRM functionality, but -- when a customization focuses only on CiviCRM -- Drupal modules are a drag: they need to be patched for CMS upgrades (D6/D7) as well as CRM upgrades (Civi 2.x/Civi 3.x), and they don't work with CiviCRM's other CMS's (Joomla and WordPress).
Fortunately, dlobo has been making progress on support for native modules (built around the "CiviCRM Extension" system) in 4.1 and 4.2. An example module is here:
Of course, this still poses a challenge: a native module needs to use native tools for packaging code, adding new web pages, developing templates, etc. -- and all those tools come with a learning curve. To improve the learning curve, I've taken a first stab at implementing a code-generator:
For example, to make a new module with a new web-page, one would go to the command-line and enter:
- civix init com.example.mymodule
- cd com.example.mymodule
- civix add-page HelloWorld civicrm/hello
That works for development on one CiviCRM site; to create a redistributable .zip file, just do one more step:
- civix build
At this point, civix is a proof-of-concept -- it works for me, but it hasn't been stress-tested, and it lacks some important features (such as creating web-forms, web-services, or DB tables). Before doing another development session to tackle these features, I wanted to circulate the PoC for a few reactions.
So: what do you think?
Comments
Tim - sounds like a great idea - although I'm miles behind you (as usual) on this & haven't even got my head around the new packaging!
FWIW, we might be in the same spot -- we know a bit about the Drupal approach to modules, and a bit about the CiviCRM approach to core code, but this approach is somewhere in between -- it's a new mix of mostly old pieces. It's useful to figure out how common use-cases (eg "declaring a new page" or "adding a new table") play out with this new mix. That requires some reading/thinking/testing. As I started down that path, I wanted to record the results/lessons.
My thinking with "civix" is that the results should be recorded as little metaprograms rather than wordy explanations. The little metaprograms ("civix add-page ControllerName web/path") should be simpler to understand than the explanations ("Update this XML, and create these 2 files, and make sure 5 things match up.")
The approach isn't unique -- I think a lot of frameworks (Rails, Symfony, etc) have new developers get started with similar code-generators. I don't think this feature would ever be as robust with civix as with those those frameworks, but (for the near term) it could be useful in bridging some gaps in our development resources.
Is there a way to port existing "drupal but civi only" modules?
It depends on how strictly it's "only civi". Some expectations:
[Edit] Lobo can probably give some better comments on that... he's been porting "cividiscount" which was a Drupal module.
Hi,
That looks awesome. I was wondering if it's possible to put some CMS specific code too and still benefit from civi extensions?
if it's a function, I can always wrap if into a if function_exists ('drupal_specific') {} ...
that would allow to add elsif function_exists ('joomla_equivalent') by the author of the one wanting to run it on J!
(or implementing a common parent class being overrided by the CMS specific class in the init, like civi does in the core)
For the hooks, is there a way to easily expose some D6/D7/J!/WP specific code containing the hooks to the CMS?
"For the hooks, is there a way to easily expose some D6/D7/J!/WP specific code containing the hooks to the CMS?"
That is an interesting challenge. I don't think there's an "easy" way. Some ideas (of varying quality):
I think that's solvable, but it feels like a lower-priority issue -- though I'd be happy if someone proved me wrong.
Agree, way easier to say that it's separate modules.
Would be nice to put in place a convention already. ie. generate a folder CMS (whatever the name) with a README
"Put inside this folder your folders containing Drupal6 Drupal7 Joomla & WP modules that are needed in conjonction of this civicrm extension if needed.
The installation of these modules into their CMS will not be automated but is likely to need symlinks. Please add here the specific instalation instructions"
It is not solving the problem automatically, but at least the specific is going to be stored in the same way by different modules and might make easier the manual steps.
Is it possible to define dependencies (either a version of civi, or module(s) installed on the CMS?
Hooks are normally prefixed with the module name. How does that work in civi extensions?
Almost the same. Hooks are still implemented as stand-alone functions. The only difference is that you can choose the prefix. Specifically, in org.civicrm.module.cividiscount/info.xml, there's a configurable element:
But decided that making it as close to a drupal module (since thats a large part of the developer community) seemed a better decision. A bit easier for those folks to write the drupal extension :)
lobo
So the hooks are prefixed with the extension name. so for the cividiscount extension, the
name is cividiscount and its packages under org.civicrm.module.cividiscount (though u could also package it as cividiscount.zip also)
lobo
totten, this is great work - thanks very much.
For others reading this, you might want to help out with the Make It Happen initiative that enables totten's approach to be really useful - http://civicrm.org/participate/mih#cmsagnostic. My company put up $2k as the lead sponsor for this MIH, and only $660 more is needed for it to be fully funded. Developers and consultants in particular should consider contributing since it will make it much easier to get a larger takeup on custom modules and thus share the support needed for them. As well, I see this as a good way to start making more custom functionality available for WordPress and Joomla! installations without having to learn their programming models.
Just a quick note: The material covered here has been extended on the wiki:
http://wiki.civicrm.org/confluence/display/CRMDOC42/Create+a+Module+Extension