Introducing Alpacka

Just before Christmas, we published our first package to Packagist (the collection of PHP libraries that can be used in other projects through composer). It’s called Alpacka and we’d like to give you a quick introduction of why we built it and how you can use it in your projects.

Alpacka is meant to be used by MODX add-on developers. It contains a bunch of code that we have been copy/pasting across our own extras - like the code to parse a chunk, to get context-specific settings, and to parse path placeholders in upload paths. By putting this into a standalone composer package, we can stop duplicating code and tests, make sure all packages get the same bug fixes, and make a great leap towards more standardised code. As we're not the only ones to work on MODX extras, we've decided to share this publicly under the MIT license with the community.

The primary way Alpacka is meant to be used currently is by extending the modmore\Alpacka\Alpacka class in your service class. This provides you with lots of useful methods, some of which you may have planned to write (or copy/paste from another project) anyway.

On top of the public methods you can use, it also takes care of your standard constructor. It will automatically set up a config array with common properties, and loads your xPDO model and the default lexicon in your namespace. This makes for a greatly slimmed down service class and more consistent use of variable names.

To add Alpacka to your add-on, you will need to use composer. If you haven't used composer before, you can read more about it here. We recommend entering your core/components/packagename/model/ directory, and then using the following command to download and install the package:

composer require modmore/alpacka

Once installed, you will need to require the composer autoloader in your project, and then update your service class to extend modmore\Alpacka\Alpacka.

Here's an example of the minimum service class you need:

require_once dirname(dirname(__FILE__)) . '/vendor/autoload.php';

use modmore\Alpacka\Alpacka;

class Packagename extends Alpacka {
   protected $namespace = 'packagename';

   public function __construct($instance, array $config = array())
       parent::__construct($instance, $config);
       $this->setVersion(1, 2, 3, 'pl');

Once you’ve done that, you get a whole bunch of really cool and common utilities you may want to use in your package.

Here’s a sample of what you can now use (assuming $service is an instance of your service class):

  • Use the very common $service->getChunk() method to parse a chunk, optionally falling back to files in your core/components/packagename/templates/ directory.
  • Sanitising folder or file names with the $service->sanitise() method.
  • Use the enhanced $service->getOption() method that checks context-specific settings, so long as you call $service->setWorkingContext() or $service->setResource() before-hand with the current context or resource respectively. There’s also a $service->getBooleanOption() method that casts the option value to a boolean, even if it’s not a true boolean but a string like “true”, “false” or “on”.
  • Use $service->parsePathVariables() to transform a path with placeholders like assets/uploads/[[+alias]]/ to a full path.

Alpacka also includes a Version class (calling $this->setVersion() in your class creates an instance of that on $this->version). We’ve been using that as part of our cache busting, but you can probably think of other cases where having the version number in a normalised format is useful.

More information about specific features in Alpacka, and how you can use them, can be found in the wiki on GitHub. We plan to document more features there in the next few weeks.

Further plans for Alpacka include providing a useful upload handler or base processor that takes care of a ton of things we currently do across our extras, and we’ll be extracting some of the cool things coming in Commerce into Alpacka or other standalone packages. We’d also like to venture into client-side standardisation in the future and share that with the community, but for now we're focusing these efforts server-side.

As Alpacka is currently still being developed and implemented into all of our extras, it might go through some fairly big changes still that may break your extra upon updates. We also haven’t finished including all the tests (and writing more) to get proper code coverage, but that’s on the to do list.

We’d love to hear what other useful utilities you would like to see added to Alpacka; issues and pull requests are very much welcome on the GitHub repository.

We've already started releasing updates for our packages that integrate Alpacka (ContentBlocks 1.3 and the upcoming release of MoreGallery).

If you’re using Alpacka in one of your extras, be sure to drop us a note - we’d love to see if others find this sort of projects useful!