Here is the short answer for how I installed CMB2 as a dependency with Composer for my plugin.
{
"require": {
"cmb2/cmb2": "^2.2"
},
"autoload" : {
"files": [
"vendor/cmb2/cmb2/init.php"
]
},
"extra": {
"installer-paths": {
"vendor/cmb2/cmb2": ["cmb2/cmb2"]
}
}
}
Details of composer.json
Require
The require section, tells Composer the package (and version) we are installing. We are requiring cmb2/cmb2.
Autoload
We need to execute the CMB2 init.php
code every time, so we specifically tell Composer it should load (and run) the code in vendor/cmb2/cmb2/init.php
. This gets the plugin started for us.
Extra
Interestingly, on the first project where I installed CMB2 as a dependency I didn’t need this section. I was baffled when on the next project, CMB2 was installing in /wp-content/plugins
instead of /vendor
. The problem on the second project is that the package composer/installers was also being installed.
What does composer/installers do?
The package composer/installers
looks for the value type
in composer.json
. In the case of CMB2, the value is
"type": "wordpress-plugin"
When a registered type (like wordpress-plugin
) is found, the install path is modified. Since CMB2 is primarily a plugin, this makes sense. In my first project, since the package composer/installers
was not included, the type
value was ignored.
Override the Override
Since composer/installers
overrides the install location for CMB2 because of "type": "wordpress-plugin"
, we have to override that override value to put it back in the original location.
Installed without installing
Troubleshooting this was even more complex because I’m not actually including composer/installers
. Instead, I’m including johnbillion/extended-cpts, which in turn has composer/installers
as a dependency therefore composer/installers
was being installed.
Why Include CMB2 at All?
This is a valid question. Since CMB2 is a stand-alone plugin, I could add a note that this additional plugin is necessary to use the code. Alternatively, I could use something like TGM Plugin Activation to prompt the user to install CMB2 on activation of my plugin. However, CMB2 has a nice mechanism in place to load only the latest version of itself when it is included in multiple forms (i.e. as part of a plugin, part of a theme, or as a separate plugin). This coupled with the convenience of reducing the steps the user needs to complete (and coupled with the fact I’m only including a couple of extra lines in composer.json
) makes this a practical decision for me.
Hey Sal, thanks for sharing this!
I rarely, if ever, need CMB2 on the front end so I’m wondering if you’ve figured out a way for Composer to load CMB2 only in WP Admin?
Like you, I am currently loading CMB2 via Composer. However, I am thinking about requiring it in a more conventional way so that I can load it only on the back end.
How would you handle it?
Hey Tim,
That is a good question. Historically, since CMB2 is pretty lightweight, I load the code on the front-end even though it doesn’t do anything (unless you have a metatbox displayed on the front-end). It is a cool idea to only load any of the code on the back end. To do this, my thought would be skip the
autoload
part of composer.json and instead do the include from within your code only on the back end (and include a check that the file exists, like in the Getting Started section on https://github.com/CMB2/CMB2/wiki/Basic-Usage).Require the files in a function loaded during admin_init
Comma on line 3 of the composer json code you have will make it fail.
Good call – thanks Sam. I’ve now corrected this.
Sal, things like this on your site are so great! I need to lookup syntax a fair amount and I increasingly find myself doing that on your site. Keep creating these little teachable articles. Thanks!