Setting up a CraftCMS website and plugins with Composer

January 30, 2018

CraftCms has become my CMS of choice for most website projects. It's easy to work with, flexible and powerful. Composer is a great way to handle PHP libraries (Craft plugins) and packages. I am always looking for ways to streamline project setup so I came up with a way to use Composer to install Craft and also handle plugin installation. With a little setup and a quick command line command you can have Craft up and running in no time.

Composer & Craft

Using Craft with Composer makes it much easier to install and manage plugins. With Composer you can quickly install Craft and Craft plugins. You can download the example composer.json and post-install.php files before starting.


Setup Composer to install Craft

  1. Open a terminal session and cd into your project directory. Run composer init and step through the options to initialize composer.

  2. Update the composer.json, add the following repositories, require and scripts sections. This sets up composer to get the latest Craft build.

    
    {
        "name": "dgrigg/mysite",
        "type": "project",
        "authors": [
            {
                "name": "Derrick Grigg",
                "email": "derrick@dgrigg.com"
            }
        ],
        "minimum-stability": "dev",
        "repositories": [
            {
                "type": "package",
                "package": {
                    "name": "craftcms/cms",
                    "version": "master",
                    "dist": {
                        "type": "zip",
                        "url": "https://craftcms.com/latest.zip?accept_license=yes"
                    }
                }
            }
        ],
        "require": {
            "craftcms/cms" : "dev-master"
        },
        "scripts": {
            "post-install-cmd": [
                "@php post-install.php"
            ],
            "post-update-cmd": [
                "@php post-install.php"
            ]
        }
    }
    
  3. Create a file in the same directory as the composer.json file called post-install.php and paste the following code into it. Any time composer runs an install or update the post-install.php script will be run to move any downloaded plugins from the vendor directory to the craft/plugins/ directory. Note that the source value needs to end with a trailing slash for rsync to copy the directory correctly (sorry Windows users, you may need to tinker with command line copy issues to get the same results without rsync). Also, for many plugins the actual plugin directory that Craft requires is not the top level repository directory.

    <?php
    /*********************************************************************
    Setup each folder for craft, this is done folder by folder to prevent 
    overwriting changed files during installation. Craft core files 
    (ie app) should only be installed once, any updates to core files 
    should only happen via the Craft updater or manually.
    *********************************************************************/
    $craft = [
        [
            'source' => 'vendor/craftcms/cms/craft/app/',
            'destination' => 'craft/app'
        ],
        [
            'source' => 'vendor/craftcms/cms/craft/config/',
            'destination' => 'craft/config'
        ],
        [
            'source' => 'vendor/craftcms/cms/craft/plugins/',
            'destination' => 'craft/plugins'
        ],
        [
            'source' => 'vendor/craftcms/cms/craft/storage/',
            'destination' => 'craft/storage'
        ],
        [
            'source' => 'vendor/craftcms/cms/craft/templates/',
            'destination' => 'craft/templates'
        ],
        [
            'source' => 'vendor/craftcms/cms/public/',
            'destination' => 'public'
        ]
    ];
    $plugins = [];
    echo 'Install craft' . PHP_EOL;
    foreach($craft as $folder) {
        echo 'Installing Craft: ' . $folder['destination'] . PHP_EOL;
        if (is_dir($folder['destination']))
        {
            echo 'Whoops ... ' . $folder['destination'] . ' already exists!' . PHP_EOL;
          } else {
            shell_exec(strtr('rsync -az source destination', $folder));
        }
    }
    echo 'Install plugins' . PHP_EOL;
    foreach($plugins as $plugin) {
        echo 'Installing plugins: ' . $plugin['destination'] . PHP_EOL;
        shell_exec(strtr('rsync -az source destination', $plugin));
    }
    shell_exec('find craft/plugins | grep .git | xargs rm -rf');
    
  4. From the command line run composer update. This will download and install Craft into your project directory.

  5. Follow the Craft installation instructions from Step 2 on to set the correct permissions and setup your local database. 


Adding plugins via Composer

There are two ways to install plugins via composer. The first, and easiest option, is to install Craft plugins that can be found on Packagist via the command line. The other option is to add the plugin repo information into the composer.json file and then run a composer update. 

Installing plugins from Packagist

You can easily install Craft plugins that are hosted on Packagist using the command line. Packages installed from Packagist will not normally need to be included in the post-install.php script as they have a special installer that will move them into the craft/plugins directory. To install a plugin via the command line use the require command.


composer require boboldehampsink/import

The require command will add the package to the composer.json file and then download and install the plugin. If the plugin uses the composer/installers package it will automatically move the plugin into the plugins directory. If the installer is not used you will need to include the plugin in the post-install.php script to have it moved into the plugins directory.

Installing plugins not on Packagist

There are many popular Craft plugins that are not on Packagist. Most open source ones can be found on GitHub. Some are configured to work with Composer, most are not. 

To use repos that have been setup for Composer (they have a composer.json file) use the following synatx in the repostiories section.

"repositories": [
   {
      "url": "git@github.com:Firstborn/Craft-CMS-Migration-Manager.git",
      "type": "git"
   }
],
"require": {
   "firstborn/craft-cms-migration-manager": "dev-master"
}

To use repos that have not been setup for Composer (ie they don't have a composer.json file) use the following synatx in the repostiories section. The package name is the name used in the require section.

"repositories": [
   {    
      "type": "package",    
      "package": {        
          "name": "benjamminf/craft-neo",        
          "version": "master",        
          "source": {            
               "url": "git@github.com:benjamminf/craft-neo.git",            
               "type": "git",            
               "reference": "master"        
          }    
      }
   }
],
"require": {
   "benjamminf/craft-neo": "dev-master"
}

You can also use the https url format to download plugins with no composer file.

"repositories": [
   {    
      "type": "package",    
      "package" : {        
          "name" : "benjamminf/craft-neo",        
          "version" : "master",        
          "dist": {            
               "type": "git",            
               "url": "https://github.com/benjamminf/craft-neo"        
          }    
      }
   }
],
"require": {
   "benjamminf/craft-neo": "dev-master"
}

or download from a repo zip file

"repositories": [
   {
      "type": "package",    
      "package" : {        
          "name" : "verbb/super-table",        
          "version" : "master",        
          "dist": {            
               "type": "zip",            
               "url": "https://github.com/verbb/super-table/archive/craft-2.zip"        
          }    
      }
   }
"require": {
   "verbb/super-table": "dev-master"
}

In all three non composer supported cases note that you need to specify a branch name in the version value. Once you have updated the composer.json file you need to update the post-install.php file to tell composer where to put the plugins after downloading them. Simply update the plugins array with the plugin name and where you want it to go.


$plugins = [
    [
        'source' => 'vendor/firstborn/craft-cms-migration-manager/migrationmanager/',
        'destination' => 'craft/plugins/migrationmanager'
    ],
    [
        'source' => 'vendor/verbb/super-table/supertable/',
        'destination' => 'craft/plugins/supertable'
    ],
    [
        'source' => 'vendor/benjamminf/craft-neo/',
        'destination' => 'craft/plugins/neo'
    ]
];

Run the composer update command from the command line and the plugins will be downloaded and moved into the correct location in Craft. Once that is complete go into the plugins section in the Craft Admin panel and enable the new plugins. 


  1. Find the plugin you want

  2. There are two ways to  

  3. Go to the plugins section in the CraftCMS admin panel and enable the plugins.

  4. To update plugins (ie version changes) at some later time, run composer update. For packages where no version was specified (ie dev-master) the latest version from the repository will be downloaded.

Additional composer considerations

Plugin Versions

If you set the version for a plugin in composer.json file as dev-[branch] every time that composer update is run the latest commit on that plugin's repository branch will be downloaded and installed into Craft. 

There may be times when you only want a to use a specific version of a plugin and not have the latest version installed every time composer updates. You can specify a version in the require section by including a tag.

    "require": {
         "firstborn/craft-cms-migration-manager" : "dev-master#v1.0.6"
    },

In this example, version 1.0.6 of the Migration Manager plugin will always be used. You can also specify a branch to use by replacing dev-master with dev-[branch-name].

Using local directories

Sometimes you may need to include a plugin that is being locally developed. Use this syntax in the repositories section. The

{
    "type": "path",
    "url": "/www/craft-plugins/Craft-CMS-Migration-Manager"
}

In the require section use the normal syntax but point the branch to your local dev branch

"require": {
    "firstborn/craft-cms-migration-manager" : "dev-my-local-branch"
}


That wraps up how to use composer to install Craft and Craft plugins. The next section quickly covers how to setup plugins to support Composer to make it easier for yourself and others to use them.


Craft Plugin development

When creating new Craft plugins it is easy to add support for Composer. In the root project folder run the composer init command and enter the vendor/plugin name. If you are using a repository to store the plugin use the account/repo (ie firstborn/craft-cms-migration-manager) as the name. Continue stepping through the init options, select library for the package type. If you plan on utilizing the composer/installers package to make plugin installation easier for people, include that when it asks for dependencies, or add it later to the require section. 

Composer Installer considerations

If you intend to use the composer/installers the plugin contents must be at the root of the repo (not in a sub folder). The plugin name does not need to match the repository name. Add the following to the composer.json file.

    "type": "craft-plugin",
    "require": {
        "composer/installers": "~1.0"
    }

When the plugin is required via composer in another project the composer installer will automatically move the plugin from the default vendors directory to the craft/plugins directory. If the repository name does not match the plugin name (following Craft plugin conventions) you can use the installer-name to change the destination directory in the craft/plugins directory.

Publishing on Packagist

To make your plugin as easy to find and install as possible I highly recommend using Packagist. You will need to create an account and then publish your repo. You can follow the directions here.


Wrap Up

I hope this post has been helpful. It may initially look like a lot of setup but once you dive in it provides a much better workflow for setting up Craft and plugins. In case you missed the link at the top, you can download the example composer.json and post-install.php files to make your start up faster.