Packaging anything from whole sites to one element

Teleport version

Teleport is a command-line scripting tool for MODX Revolution. With Revo 2.4, it really gets some power. It can be used to make tranport packages, but it can also be used for just about any kind of management tasks. An example given in the GitHub README is creating users.

We'll be a bit less ambitious, and simply create a transport package for a Template, its supporting CSS, JS, font and image files, and a single resource to use it. And we'll begin with the presumption that you already have a MODX installation with the working template that you want to package.

I'm working on my Mac localhost, with a MAMP web stack installed. All you need is a command line terminal and the ability to run PHP from the command line. In my case, I just needed to add one line to my .profile file to let me use a simple "php" at the command line -

alias php="/Applications/MAMP/bin/php/php5.6.10/bin/php"

Command line PHP version


The first thing I did was create the necessary file structure for Teleport. In my home directory, I created a new "teleport" directory, and in that I put "profile", "tpl" and "workspace" directories.

Teleport directories

As you can see, my next step was to download the teleport.phar file from github. The link to download it is in the Installation section of the README. Make sure to get it there, so you get the latest version. Now you can run Teleport from your terminal.

Teleport version


Now you are ready to start using Teleport. And now you need to create a profile for your project. This is a .json file that goes ... wait for it ... in the profile directory! It basically tells Teleport where your MODX installation is located.

Fortunately, we don't need to write this .json file ourselves, Teleport will create one for us. Just give it a project name and the path to your MODX installation's core, much like the config.core.php files.

php teleport.phar --action=Profile --name="SmallBusiness" --code=smallbusiness --core_path=/Applications/MAMP/htdocs/templates.modx/core/ --config_key=config

Teleport create profile


Aren't you glad you didn't have to write that? Actually, I cheat so that I don't even have to write out the command. I keep a text file of Teleport commands, and just edit the bits that are different for different projects, and then copy the whole line and paste it into my terminal window.


Well, the easy part is over... now comes the really nasty part. You need another .json file, a .tpl.json file to be exact, to tell Teleport exactly what you want it to do. At this time there just isn't any way of getting around diving into the JSON yourself. However, it is possible to cheat and copy sections that are similar to what you want from the tpls in the GitHub repository.

For my case, I need one Template, one Resource, and an entire directory of files. To make a long story short, I copied bits from a couple of those tpls in the repository, and fiddled with it until it worked. Here's what I ended up with.

{<br>{<br>"name": "smallbusiness",<br>"description": "Bootstrap SmallBusiness template",<br>"author": "sottwell",<br>"attributes": {<br>"changelog": {<br>"sourceType": "fileContent",<br>"source": "{+properties.modx.core_path}components/test/docs/changelog.txt"<br>},<br>"readme": {<br>"sourceType": "fileContent",<br>"source": "{+properties.modx.core_path}components/test/docs/readme.txt"<br>},<br>"license": {<br>"sourceType": "fileContent",<br>"source": "{+properties.modx.core_path}components/test/docs/license.txt"<br>},<br>"requires": {<br>"pdoTools": "~2.1.9"<br>}<br>},<br>"vehicles": [<br>{<br>"vehicle_class":"xPDOObjectVehicle",<br>"object":{<br>"class":"modTemplate",<br>"criteria":["id = 2"],<br>"graph":{<br>"Category":[],<br>"PropertySets":{<br>"PropertySet":[]<br>}<br>},<br>"package":"modx"<br>},<br>"attributes":{<br>"preserve_keys":false,<br>"update_object":true,<br>"unique_key":"templatename",<br>"related_objects":true,<br>"related_object_attributes":{<br>"Category":{<br>"preserve_keys":false,<br>"update_object":true,<br>"unique_key":"category"<br>},<br>"PropertySets":{<br>"preserve_keys":true,<br>"update_object":true,<br>"unique_key":["element", "element_class", "property_set"],<br>"related_objects":true,<br>"related_object_attributes":{<br>"PropertySet":{<br>"preserve_keys":false,<br>"update_object":false,<br>"unique_key":"name"<br>}<br>}<br>}<br>}<br>}<br>},<br>{<br>"vehicle_class": "xPDOObjectVehicle",<br>"object": {<br>"class": "modResource",<br>"criteria": [<br>"id = 22"<br>],<br>"graph": {<br>"Template": [<br>],<br>"ContentType": [<br>],<br>"TemplateVarResources": {<br>"TemplateVar": [<br>]<br>},<br>"ResourceGroupResources": {<br>"ResourceGroup": [<br>]<br>},<br>"ContextResources": {<br>"Context": [<br>]<br>}<br>},<br>"package": "modx"<br>},<br>"attributes": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": [<br>"context_key",<br>"uri"<br>],<br>"related_objects": true,<br>"related_object_attributes": {<br>"Template": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": "templatename"<br>},<br>"ContentType": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": "name"<br>},<br>"TemplateVarResources": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": [<br>"tmplvarid",<br>"contentid"<br>],<br>"related_objects": true,<br>"related_object_attributes": {<br>"TemplateVar": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": "name"<br>}<br>}<br>},<br>"ResourceGroupResources": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": [<br>"document_group",<br>"document"<br>],<br>"related_objects": true,<br>"related_object_attributes": {<br>"ResourceGroup": {<br>"preserve_keys": false,<br>"update_object": true,<br>"unique_key": "name"<br>}<br>}<br>},<br>"ContextResources": {<br>"preserve_keys": true,<br>"update_object": true,<br>"related_objects": true,<br>"related_object_attributes": {<br>"Context": {<br>"preserve_keys": true,<br>"update_object": false<br>}<br>}<br>}<br>}<br>}<br>},<br>{<br>"vehicle_class":"xPDOFileVehicle",<br>"object":{<br>"source":"{+properties.modx.context_web_path}assets/theme",<br>"target":"return MODX_ASSETS_PATH;"<br>},<br>"attributes":{<br>"vehicle_class":"xPDOFileVehicle"<br>}<br>}<br>]<br>}

The main point of all of this is four sections: attributes for the package as a whole, then three vehicles for the three things I want packaged. I suspect that a lot of the attributes for the vehicles can be omitted, but I'm not going to meddle with it until I know that for sure.


The file starts out with the project name, a description, and the author. Then it gets into some attributes. I've told it to add the three basic text files, changelog.txt, readme.txt and license.txt, and told it where to find them.

{...<br>"attributes": {<br>"changelog": {<br>"sourceType": "fileContent",<br>"source": "{+properties.modx.core_path}components/test/docs/changelog.txt"<br>},<br>"readme": {<br>"sourceType": "fileContent",<br>"source": "{+properties.modx.core_path}components/test/docs/readme.txt"<br>},<br>"license": {<br>"sourceType": "fileContent",<br>"source": "{+properties.modx.core_path}components/test/docs/license.txt"<br>},<br>...

A new feature for Teleport with Revo 2.4 is dependencies. A template needs a snippet to generate the menu. In this case, I used pdoMenu, part of the pdoTools package. So I've specfied a dependency of pdoTools, with mention of the latest version at this time.

...<br>"requires": {<br>"pdoTools": "~2.1.9"<br>}<br>...


Then we get into the vehicles. These basically tell Teleport what objects you want it to add to the package. The only changes I made to the template and resource vehicles that I copied was the "criteria" field, where I specified the IDs of the template and the resource I wanted.

...<br>{<br>"vehicle_class":"xPDOObjectVehicle",<br>"object":{<br>"class":"modTemplate",<br>"criteria":["id = 2"],<br>...<br>{<br>"vehicle_class": "xPDOObjectVehicle",<br>"object": {<br>"class": "modResource",<br>"criteria": ["id = 22"],<br>...

The file vehicle is a lot simpler; all it needs to know is where to get the files from, and where to install them. I said I wanted the assets/theme directory, and it gets installed right back into the assets directory.

And the Extraction

Fortunately after all of that, we can go back to feeding Teleport a single line, and it will make up our package for us. More copy/paste of a slightly edited command. Just tell it the profile and tpl files to use.

php teleport.phar --action=Extract --profile=profile/bootstrap_small_business.profile.json --tpl=tpl/bootstrap_small_business.tpl.json --name=BootstrapSmallBusiness --version=1.0.0 --release=pl

The name argument will set the name of the package, along with the version and release. By default the profile code and tpl name are concatenated with an _ to form the package name.

The package .zip file will be put in the "workspace" directory. It's an ordinary package and can be installed in the MODX Manager's installer like any other package.

Teleport extraction


There are a few things I need to find out yet. I'd like to have better control over the uninstall process. And I'd like to be able to do more with the dependencies, like offer an option between pdoTools and Wayfinder in this case. Actually the whole dependencies thing isn't quite behaving as it should, so I need to find out what I'm missing in the process. However, for a beginning, this makes up a nice template package.