Multi-Site, adding entries into index.config.php

Recommended Posts

swampmusic    4

Hi Folks,

We have a multi-site #1, multiple sites, multiple databases platform in development/concept at the moment.

A company can sign up, register, and PW then creates a db, copies over a site folder with /wire symlink. All seems to work well, after sign up they can then enter into their subdomain site. ( Because of this dirty hack below that inserts the new subdomain into PW's hostSiteConfig array. Without this, the subdomain is not correctly registered as a PW site & instance I think).

Does anyone know how to dynamically add an entry into the index.config.php file ? Knowing the little I have learnt so far about PW, Ryan has probably left us a really smart way to do it, but I haven't figured it out or found it yet. 

I have done a dirty hack on it, which I'm not very happy or proud off. Anybody know of a better way around the problem ?  ... below is more or else the code I am using in the pilot version.

// some error traps taken out for brevity on the booleans below...
$hostsArray = ProcessWireHostSiteConfig();
// $sitename normally populated from the customers signup/registration
// hard coded here for this example...
$sitename ='somesubdomain';
$a = $sitename . '.' . 'localhost:8020';     // machine name, port & protocol normally comes from $config, hard coded for example.
$b = 'site-' . $sitename . '/site';
$newSite = array($a => $b);
$hostsArray = array_merge($hostsArray, $newSite);
// very dirty hack starting....
// creating a string copy of the array used in
// index.config.php
foreach($hostsArray as $key => $value) {
$newString .= "'" . $key . "' => '" . $value . "', ";
$newString = "return array(" . $newString . ');}';
// dirty hack getting worse :-(
$newConfigIndex = file_get_contents($config->paths->root . 'index.config.php');
$startpos = strpos($newConfigIndex, 'return array(');
// quality coders starting to feel sick at this point i suspect... sorry! ;-(
$newConfigIndex = substr_replace($newConfigIndex, $newString, $startpos);
$boolConfigIndex = file_put_contents($config->paths->root . 'index.config.php', $newConfigIndex);
// crikey! did he really just do that !!!!!!

Share this post

Link to post
Share on other sites
kongondo    5,014

I haven't looked at your code closely, but if you need to write to a file, you need to write to a file. You have file_put_contents and fwrite. I see no other way around it irrespective of the software you use. ProcessWire itself writes to /site/config.php/ during install. I use this multi-site setup myself. I've been meaning to write some code or a module to automate the process but never got round to it. You could do with some error checking and backing up the original file as part of the updating the file.

  • Like 1

Share this post

Link to post
Share on other sites
kongondo    5,014
2 minutes ago, abdus said:

Why not create a simple JSON/YAML config file, one for each domain,

Cool idea! But it seems the requirement is also to automate the process?

Share this post

Link to post
Share on other sites
swampmusic    4

@abdus, it has to be done from php file dynamically during the registration process. I think PW is monitoring the index.config.php file. Once new domain has been added into it, it then seems to work ok for a customer to log onto their new site and not get the error in admin that you get when a multi-site site is not in the index.config.php

@kongondo, thx re: ideas on code.

Normally in PW we have  been left with hooks and API's to deal with things when we need to dig a bit deeper. I just can't find anything for the index.config.php file. Seems a bit odd if I need to hack it like this, otherwise creating multi-sites must always be a manual process.

Share this post

Link to post
Share on other sites
abdus    596

@kongondo You wont be creating these files manually of course, you extend logic for the signup form to create the files for you. Then in index.config.php, you parse, merge and return the array. Something like this

function ProcessWireHostSiteConfig() {
    $configDir = __DIR__ . '/.config/';

    $files = wire()->files;
    $siteConfigs = $files->find($configDir, [
        'extensions' => ['yaml']

    $sites = [];
    foreach ($siteConfigs as $cfg) {
        $config = yaml_parse_file($cfg);

        // needs better sanitization
        $isValidConfig = true;
        if (!$isValidConfig) continue;

        $sites[$config->domain] = $config->siteDir;

    $sites['*'] = 'site';
    return $sites;


  • Like 2

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By swampmusic
      Having a problem with a basic multi-site instance.
      The multi-sites are dynamically created and run as sub-domains and all is ok with them. They are created during a sign up process by end users.
      During the sign up process - once the new site & db has been created, I had planned to load the new site instance and add a new user to it, using code similar to this..
      $newSiteInstance = new ProcessWire($path, $newSiteUrl);   $u = $newSiteInstance->users->add($sitename); $u->pass = $pass; $u->email = $email; $u->addRole('content-viewer'); $x = $newSiteInstance->users->save($u);  This won't work in the registration script. It throws an error ... "SQLSTATE[42S02]: Base table or view not found".
      However, if I halt the script, load the new site incognito/other browser, then continue the script, all works perfectly.
      So $newSiteInstance = new ProcessWire($path, $newSiteUrl); doesn't seem to work for me unless a site has already been loaded in a browser or instantiated somehow.
      I am missing something here ? Does a site need to be bootstrapped before new instance will work on it ? 
      Sorry, pretty new to this php/PW arena.  Having fun though
      Any ideas folks ?
    • By Robin S
      I'm having trouble getting a multi-site installation (I'll call them "site1" and "site2") working on a shared cPanel host.
      The installation was working on my local hosting environment with two virtualhosts pointed at the same folder, allowing me to access both sites. On the cPanel server I'm wanting to use subdomains for both sites: site1.mydomain.com and site2.mydomain.com
      So in my cPanel hosting I have site1.mydomain.com as the primary domain for the account, and I have added site2.mydomain.com as a cPanel domain Alias (I believe this was called a "Parked Domain" in previous versions of cPanel). Before I edit index.config.php to perform the redirect to site2 I am able to see site1 at both site1.mydomain.com and site2.mydomain.com. But after I edit index.config.php to redirect I get:
      Maybe someone has experience with setting up a multi-site installation on cPanel. Is adding the domain for site2 as an alias/parked domain the right move? Something else I need to configure in cPanel?
    • By FrancisChung
      Hi there,
      I'm trying to set up different instances of our website so I thought I'd try it out locally first before deploying out to the real world.
      I'm interested in a multi-site/independent DB setup so I'm following the instructions (Step1 Alternative)  in https://processwire.com/api/modules/multi-site-support/
      The steps I've taken are :
      1) I've copied my /site folder to /site-dev.
      2) Modified index.config.php and moved it to the webroot
      3) Modified config.php in site-dev and changed the DB credentials.
      I thought this was all the steps I needed to take but it didn't work.
      I've also added an entry in /private/etc/hosts for dev.localhost to point to
      Is there something else I have overlooked?
      Thanks in advance!
      index.config.php function ProcessWireHostSiteConfig() {           return array(                   /*                  * Some Examples (you should remove/replace them if used). * Just note that the values must begin with 'site-'.                  *                  */                  'dev.localhost' => 'site-dev',   /* * Default for all others (typically /site/) * */ '*' => 'site',                   );   }   config.php $config->dbHost = 'localhost';  $config->dbName = 'SSS-Live';  
    • By sarah_hue
      wow, this is weird: I am running two sites with one ProcessWire installation. Both are using VersionControl module. I moved both sites to another webserver right after installing VersionControl.
      On site #1 ... sometimes (!) file upload is not possible (the pink status bar gets stuck at 100 %) already uploaded files (before moving to the new server) cannot be deleted file descriptions cannot be changed no error messages are given, not even in debug mode While on site #2 ...everything's fine: uploading, deleting, changing the description... I read Douglas' post on a glitch in dev 2.5.19, but I'm using the regular 2.5(.0).
      nghi's post on a similar problem describes pretty much what I'm experiencing here, but if there was something wrong in the suhosin.ini, site #2 would encounter the very same problem.
      If I use VersionControl to set the file field back to an earlier version where the file was not uploaded yet, the file disappears and is deleted from /assets/file/[page-id]/. Same vice-versa when setting to a version before a file was deleted: It is recreated on the page and in the filesystem.
      Permissions are -rw-rw-rw- for all files.
      Any ideas?
    • By valan
      I'm developing relatively big site with a number of weakly connected web-services. By "weakly connected" I mean that they share same users and some common catalog but the rest (and bigger part) is not shared (service-specific catalogs, languages, etc).
      As site becomes too big and complicated I think to move these weakly connected web-services to their own sites, e.g. one PW core but several sites with their own dbs. Users as well as shared catalog remain at "main" site, being maintainable via PW admin.
      Before this move I'd like to consult with you guys. Specifically - would this code work at "web-service" sites?
      $temp = $wire; // temporary save "current site $wire" include("../../../site-main/index.php"); // bootstrap PW main domain $wire. Main domain and Service domain sites are in one directory, ../../../ path prefix used to navigate from current templates directory to common parent folder of all sites. $mainWire = $wire; // set variable to be used for access/manipulations at main site $wire     = $temp; // set $wire back to "current site $wire" $user1 = $mainWire->users->get('email=email@example.com')->first(); // returns User instance from main site / main domain db $user2 = $wire->users->get('email=email@example.com')->first(); // returns User instance from current site / current domain db I am aware of http://modules.processwire.com/modules/service-pages/ but due to security&performance reasons I think that if "hardcode" above works then it should be a better choice.
      P.S. wire/index.config.php
      function ProcessWireHostSiteConfig() {     return array(              'maindomain.com'     => 'site-main',              'www.maindomain.com' => 'site-main',              'service1.com'       => 'site-service1',              'www.service1.com'   => 'site-service1',              'service2.com'       => 'site-service2',              'www.service2.com'   => 'site-service2'              // etc other services             ); }