Multiple Site Type Controllers

Site Type Controllers require Concrete 9.0 or greater.

Site Type Controllers are available to sites that use the multiple site hosting feature found in Concrete 9.0 and above. Click here to learn more about multiple site hosting.

Any time you create a site using multiple site hosting, Concrete looks for a controller that exists for that site handle.

To override the default controller used for creating a site of any type, add this code to a package on_start() method or within application/bootstrap/app.php:

$manager = $this->app->make('Concrete\Core\Site\Type\Controller\Manager');

Any time a site is added, this controller will be used – unless a custom controller binding has been defined for a site of that type. If we have a site type named "restaurant" and we want to use a custom controller for that site type, we can register it like this

$manager = $this->app->make('Concrete\Core\Site\Type\Controller\Manager');
$manager->extend('restaurant', function ($app) {
    return $app->make('My\Custom\Site\Type\Controller\RestaurantController');

A site type controller is any class that implements the Concrete\Core\Site\Type\Controller\ControllerInterface class.

Controller Functionality

Why would you want to do this? Defining a custom site type controller allows the developer to run custom code at certain points during a site's lifecycle. Here are the standard methods available in the controller interface:

public function add(Site $site, Request $request): Site;

public function update(Site $site, Request $request): Site;

public function delete(Site $site): bool;

public function addType(Type $type): Type;

public function getFormatter(Type $type): FormatterInterface;

Define those methods in your custom type, and you'll be able to define custom code when a site of this type is added, updated, deleted, or displayed – or even when this type of site is added to the site types list.

Example Functionality

The default controller that ships with multiple site hosting creates a custom folder for each site when that site is added. It does so by running this code:

 * {@inheritdoc}
 * @see \Concrete\Core\Site\Type\Controller\ControllerInterface::add()
public function add(Site $site, Request $request): Site
    $this->addSiteFolder($site, $request);

    return $site;

protected function addSiteFolder(Site $site, Request $request): FileFolder
    $filesystem = new Filesystem();
    $root = $filesystem->getRootFolder();
    $folder = $filesystem->addFolder($root, $site->getSiteName());

    // apply the default permissions.
        new \Concrete\Core\Permission\Registry\Entry\Object\Object\FileFolder($folder),
        new SiteFileFolderAccessRegistry($site, $this->groupService)

    return $folder;

Don't want this functionality, or you want to make it work differently? Define your own custom controller and you'll be able to control the experience fully.