An approach: composer-downloads-plugin
civinfinite with a
composer.json file which declares:
zip file will be downloaded and extracted into your extension's folder (under
For example, suppose that you install
civinfinite on a Civi-D7 site under:
If you run
composer install, then the assets will be at:
At runtime, you can determine the URL as:
Similarly, if you're registering an Angular module for use in Civi (
*.ang.php), then the registration can reference that path:
'ext' => 'civinfinite',
'basePages' => ,
'js' => ['extern/ngInfiniteScroll/src/infinite-scroll.js'],
There are many different techniques for managing JS/CSS assets in PHP projects -- D7 modules have
libraries; Backdrop and WordPress modules tend to embed assets within modules;
composer has various add-ons like
composer-asset-plugin, etc. Each of these has strengths and weaknesses.
I would submit that the relative strength of this technique is that it is easy for both developers and site-builders to reason about the behavior. (Tangentially, it's also faster than other composer-based techniques because it has no affect on the size of the dependency graph. But the main purpose is to make it easier to reason.)
For example: Consider that there are different ways in which people may deploy an extension:
- One may download an extension as a
*.zip file with all assets bundled in. (This is what happens when using the in-app extension UI or
cv dl or
Extension API.) One may not be running
composer at all.
- One may clone the extension's git repo and run
- One may have a
composer.json in a site-root (and some open-ended mix of dependencies, plugins, configuration options), and then you add the extension as a dependency.
As a developer, it's hard to predict which mix of techniques are being used by downstream site-builders. In the
composer-downloads-plugin approach, you can rely on the JS/CSS assets always being in the same place (relative to your code).
As a site-builder, this approach does not require you to add (or change/update) any "repositories" or "plugins" or configuration-options in a composer root-project. You don't even need to have a composer root-project. (You probably should for other reasons... but the extension and its assets aren't going to force you into it.) If a developer changes some small detail of the assets in their package, then it's not your concern.
This approach complies with a simple, pre-existing contract:
- The developer decides what code goes inside their extension.
- The site-builder decides which extensions to get - and where to put them.
A developer is free to use
composer-downloads-plugin without requiring any changes to that basic contract.