Jump to content

Multisites with same templates and different databases


shivrajsa
 Share

Recommended Posts

Hello,

I am new to PW and learning this great tool for web development.

I have already created a site for portfolio showcase using PW

Same site templates will be used for different portfolio showcase with different sites / domain and different database.

For all the sites front end design/display will be same.

So, in future if I wan to modify display of sites, I have to edit template file [ i.e. /site/template/file.php ] for each domain, which is not a good solution.

I want a solution where I will modify at single place and that will be reflected in every domain / site.

Is there any way to achieve this ? Please guide

Link to comment
Share on other sites

You should be able to point to different databases in your config.php depending on hostname. Something like this _should_ work, but I haven't tried it:

<?php
// config.php
if($_SERVER['HTTP_HOST'] == 'firstsite.com') {
    $config->dbHost = 'localhost';
    $config->dbName = 'db_for_first_site';
    $config->dbUser = 'user';
    $config->dbPass = 'password';
  
} else if ($_SERVER['HTTP_HOST'] == 'secondsite.com') {
    $config->dbHost = 'localhost';
    $config->dbName = 'db_for_second_site';
    $config->dbUser = 'anotheruser';
    $config->dbPass = 'password';
}

 

  • Like 1
Link to comment
Share on other sites

Welcome @shivrajsa,

The simplest way would be for the template files in each /site/templates/ directory to consist only of include() statements, which draw from a central templates directory at /templates/. Ryan suggests something like this here:

Or, as also mentioned in that thread, you could consider using symlinks.

  • Like 1
Link to comment
Share on other sites

4 hours ago, shivrajsa said:

Thank you @abdusand @Robin S .

For @abdus answer, how can we use different domains on same site folder ? because all template files and config file will be in one folder. I am curious to understand this solution.

For @Robin S , I explored little about symlinks and I discovered, it has to be allowed by hosting provider before going live.

 

I tried it, it works just fine. Here's how you do it

  • Create a new database for the other site(s). Add new database user and set correct permissions & privileges.
    I duplicated mine by dumping into .sql file, changing its name then reimporting in Adminer panel
  • Go to config.php, update $config->httpHosts to include other domains, then add new database info like so:
    $config->dbHost = 'localhost';
    $config->dbPort = '3306';
    
    $config->httpHosts = array('pw.dev', 'pw2.dev');
    
    if($_SERVER['HTTP_HOST'] == 'pw.dev') {
        $config->dbName = 'pw';
        $config->dbUser = 'pw';
        $config->dbPass = 'password';
    
    } else if ($_SERVER['HTTP_HOST'] == 'pw2.dev') {
        $config->dbName = 'pw_dev';
        $config->dbUser = 'pw_dev';
        $config->dbPass = 'password';
    }

     

  • Update your HTTP server configuration. 
    I use Caddy Server, which makes these changes trivial.
     

    # old 
    pw.dev:80 {
            root /www/pw/
            # other configs
    }
    
    # add new host
    pw.dev:80, pw2.dev:80 {
            root /www/pw/
            # other configs
    }
    
    # both hosts share the same root!

     

  • Reload HTTP server (Apache, nginx, Caddy etc) and enjoy!

Here it is in action:

2017-04-07_11-56-11.mp4 (1MB video, 00:24 sec)

  • Like 1
Link to comment
Share on other sites

Thank you again @abdusIt seems amazing.

This topic is little advance for me considering my knowledge, so I have few more questions.

I am wondering if such type of server configuration is allowed by hosting provider and where can I edit this server configuration in CPanel.

I got this doc, but it talks about different directory for each domain

https://blog.cpanel.com/managing-multiple-domains-from-a-single-cpanel-account/

Also, just a quick query, can I use candy server on my shared hosting account ?

 

 

 

Link to comment
Share on other sites

2 hours ago, shivrajsa said:

Thank you again @abdusIt seems amazing.

This topic is little advance for me considering my knowledge, so I have few more questions.

I am wondering if such type of server configuration is allowed by hosting provider and where can I edit this server configuration in CPanel.

I got this doc, but it talks about different directory for each domain

https://blog.cpanel.com/managing-multiple-domains-from-a-single-cpanel-account/

Also, just a quick query, can I use candy server on my shared hosting account ?

You're probably not allowed to make changes in server, or install new packages if you're on a shared hosting (judging by the use of CPanel). But I am guessing it's possible, because reading the guide on the link you posted, there's this screenshot. This probably allows pointing to same directory  However, you will probably need to upgrade your hosting account for multiple domains.

Also if you use this setup, databases will be unique but since both setups point to same /site directory, assets folders will eventually clash since both sites are unaware of the other's page ids. To solve this you may need to change site path as well. I'll look into how when I am back on PC.

Edit: solved it below

Link to comment
Share on other sites

Note that "there are times" when $_SERVER['HTTP_HOST'] and similar are undefined, eg. when running PW from CLI (bootstrapping), because of this, I normally use something like this:

if(strstr(getcwd(),'/full/path/to/dev')) {
	// DEV settings
} else if(strstr(getcwd(),'/full/path/to/stage')) {
	// STAGE settings
} else {
	// PRODUCTION settings
}
[credit]
  • Like 2
Link to comment
Share on other sites

2 hours ago, abdus said:

You're probably not allowed to make changes in server, or install new packages if you're on a shared hosting (judging by the use of CPanel). 

Also if you use this setup, databases will be unique but since both setups point to same /site directory, assets folders will eventually clash since both sites are unaware of the other's page ids. To solve this you may need to change site path as well. I'll look into how when I am back on PC.

By overriding $config->paths and $config->urls, I got it to work. Both sites use different directories for uploads unaware of each other. I couldn't override $config->site->assets, which would have been a much better option, anyone know how?

<?php
$config->dbHost = 'localhost';
$config->dbPort = '3306';

$config->httpHosts = array('pw.dev', 'pw2.dev');

if($_SERVER['HTTP_HOST'] == 'pw.dev') {
    $config->dbName = 'pw';
    $config->dbUser = 'pw';
    $config->dbPass = 'password';
    $config->paths->files = $config->paths->site . '/assets/files-first/';
    $config->urls->files = $config->urls->site . '/assets/files-first/';
} else /*if ($_SERVER['HTTP_HOST'] == 'pw2.dev')*/ {
  	// remember to default to some site if HTTP_HOST is not set!
    $config->dbName = 'pw_dev';
    $config->dbUser = 'pw_dev';
    $config->dbPass = 'password';
    $config->paths->files = $config->paths->site . '/assets/files-second/';
    $config->urls->files = $config->urls->site . '/assets/files-second/';
}
1 hour ago, szabesz said:

Note that "there are times" when $_SERVER['HTTP_HOST'] and similar are undefined

Checking path is quite good, I'll probably implement some setup like this to set up a staging environment. Right now I'm just using reverse SSH tunnel to redirect localhost to web. 

One thing however, since both sites use the same templates, paths wouldn't be different, but you can create a symlink to solve that. 

  • Like 3
Link to comment
Share on other sites

1 hour ago, abdus said:

One thing however, since both sites use the same templates, paths wouldn't be different, but you can create a symlink to solve that.

Yeah, valid point ;) I just did not follow the thread properly and only spotted the usage of the variable which I also used to use to tell apart my local machine from the server but recently switched to checking the path instead.

  • Like 1
Link to comment
Share on other sites

It seems very simple solution, i.e.  pointing multiple domain to same directory where all sites will have same templates and managing their database settings in config file.

I think keeping assets folder different is a good idea if we ever want to export assets related to specific site. I will give it a try soon.

Thank you @abdus and all for help and guidance.

  • Like 1
Link to comment
Share on other sites

You might need to override paths for other site specific directories, such as cache, logs, sessions to get a better separation. If it were possible override assets directory altogether, that would be much better, but for now, this should suffice.

If anyone knows how to override /site/assets/ path, I'd love to be enlightened.

  • Like 1
Link to comment
Share on other sites

Thank you @abdus

I am also thinking on another strategy .i.e "Multiple sites with same database" but problem I see is, there will be same database of users who will have edit rights for all the sites.

I want to assign edit rights to separate user for each site. And other users will not have access to that particular site.

I will open another thread for this discussion so that it is easy to track. 

Based on the simplicity and maintainability of solution, I will select my strategy. 

Link to comment
Share on other sites

@abdus

your code throws an error for me: `Uncaught Error: Call to undefined function ProcessWire\config()`

And this code works ( note the $config instead of config() ):

$config->paths->assets = $config->paths->root . 'test/';
$config->urls->assets = $config->urls->root . 'test/';

 

Link to comment
Share on other sites

34 minutes ago, gebeer said:

@abdus

your code throws an error for me: `Uncaught Error: Call to undefined function ProcessWire\config()`

And this code works ( note the $config instead of config() ):


$config->paths->assets = $config->paths->root . 'test/';
$config->urls->assets = $config->urls->root . 'test/';

 

I'm using PW from dev branch with Functions API enabled. In your config.php add

$config->useFunctionsAPI = true 

https://processwire.com/blog/posts/processwire-3.0.39-core-updates/

 

Were you able to override assets directory altogether? 

Link to comment
Share on other sites

Paths echo whatever you set them to, but try uploading a file, do you get /site/test/files directories? In my case I didnt get new directories even though paths seem to change, it kept uploading to /site/assets/files

Link to comment
Share on other sites

@abdus As the $config variable inherits all methods and properties from WireData, you can try and use the set method

$config->paths->set('assets', $config->paths->root . 'test/');

I don't have the time to try this right now. So give it a try yourself and let me know.

Link to comment
Share on other sites

Nope, no change

<?php
// doesnt work
$config->paths->set('assets', $config->paths->site . '/assets-second/');
$config->urls->set('assets', $config->urls->site . '/assets-second/');

 

Link to comment
Share on other sites

  • 7 months later...

I really like what you guys came up with here, I think I'm going to implement this on a bunch of websites. 

One thing to note is that when you are using multi-instance like I do, and you connect from a PW site that is not part of your 'multisite' setup, the $_SERVER['HTTP_HOST'] condition in config.php won't trigger and you will not get the data you are after. One way to get around this is to create the instance like this:

$site = new ProcessWire('/srv/users/me/apps/website/public/', 'http://website.dev/');

Adding the domain as the second parameter will set a variable called $httpHost (to 'website.dev' in my example) in wire\core\ProcessWire.php which is available to config.php. Therefore, if you alter the condition in config.php to this, multi-instance should work:

if ($_SERVER['HTTP_HOST'] == 'website.dev' || $httpHost == 'website.dev') {
    $config->dbName = 'name';
    $config->dbUser = 'user';
    $config->dbPass = 'pass';
    //etc
}

I have not tested this extensively but it seems to work fine.

Link to comment
Share on other sites

Has anyone managed to overwrite the cache path and URL? It does not seem to work so all sites will be sharing the same cache, which might be problematic.

Edit: looks like template cache does use the custom cache path/URL and other forms of cache use the default cache folder.

Link to comment
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
 Share

×
×
  • Create New...