Jump to content

Multiple sites from one install


apeisa
 Share

Recommended Posts

Is there any way to run multiple sites from one install?

Meaning you have one pw-site, let's say www.domain.com. There you have "campaign site" called www.domain.com/campaign/. All good so far. But what if pages from www.domain.com/campaign/ should be found from www.campaign.com?

Is that currently possible or would it require new pw-installation?

Link to comment
Share on other sites

But what if pages from www.domain.com/campaign/ should be found from www.campaign.com?

I think in this case you'd point both domain.com and campaign.com to the same IP. If your needs were simple, your template file could just check what host it's being served from, i.e.

<?php
if(strpos($config->httpHost, 'campaign.com') != false) {
    // display or load something for campaign.com
} else {
    // display or load something for domain.com
}

If your needs were more complex, then you could create an autoload module to handle your flow control. That module's init() would modify $_GET['it'] that hold's the path to the page requested. That $_GET['it'] var is the means by which PW's .htaccess file sends the requested URL to ProcessWire. Since an autoload module is init()'d before the page is loaded, it has the opportunity to change it, i.e.

<?php

public function init() {
    if(strpos(wire('config')->httpHost, 'campaign.com') !== false) {
        // change path like /about/contact/ to /campaign.com/about/contact/ 
        $_GET['it'] = '/campaign.com/' . ltrim($_GET['it'], '/'); 
    }
}

Then your campaign.com site structure would just be created below a page named '/campaign.com/' in your site tree. I've not tested this out, but I can't see any reason why it wouldn't work. Also, I'm sure the same thing could be accomplished via the .htaccess file rather than an autoload module, but I'd have to do more research on that before I could post an example.

Link to comment
Share on other sites

I could also need something similar. I just used symlinks on domain folders on server to point to one pw install. I then have redirects to /en/ /de/ ...

For the other domain I chose /de-ch/ and /en-ch/. But I would like to put them in subfolders like /domain1/de/ and /domain/en/ etc. but then the additional path would show in url, which I didn't see any easy way. But then I also didn't come ask here :). I was thinking about something like configurable routing lik ein codeigniter for example.

Link to comment
Share on other sites

  • 2 months later...

I mentioned in my multi-language post that I was thinking about writing a MODx like «context» module to create and manage multiple page trees (each as a separate «context». On access one of the context would be selected for content delivery depending on several parameters like language or for example the domain the page is accessed through. In the settings of each context - similar to a .htaccess mod_rewrite condition - a regexp could be provided to determine the right page tree to be used. So the matching context’s home page would be served.

I’m not sure, if this would be a possible solution for the problem discussed here?

Link to comment
Share on other sites

  • 1 month later...

This might get little bit more complicated, than manipulating only $_GET['it']. Mainly because of urls: $page->url should return /page-name/ instead of /campaign.com/page-name/ (if I am under "subsite"). Otherwise I would end up links like www.campaign.com/campaign.com/page-name/ and it would actually try to load page campaign.com/campaign.com/page-name

Oliver: not sure I understand that context thing well enough to say if it could work here. It sounds like it could :)

Link to comment
Share on other sites

Hmm, tested this now. As Ryan assumed, the www.campaigndomain.com serving files from www.site.com/campaigndomain.com was a breeze. But manipulating urls on the fly isn't so easy. I tried to hook before page render and manipulate url and path, but wasn't yet successful in that.

Link to comment
Share on other sites

I created simple module to add these subsites. You need to use $page->subUrl or $page->subPath if you want working urls/paths. Not sure if it would be better to use $page->url and $page->path... and how that could be achieved?

Anyways, I have this version up and running nicely:

<?php

class Multisite extends WireData implements Module, ConfigurableModule {

public static function getModuleInfo() {

return array(
'title' => 'Multisite',
'version' => 001,
'summary' => 'Allows multiple sites with different domains run from single PW-site and database.',
'singular' => true,
'autoload' => true,
);
}

public function init() {

$subdomains = explode("\n", strtolower($this->subdomains));

foreach($subdomains as $subdomain) {

$httpHost = strtolower(wire('config')->httpHost);
if(strpos($httpHost, $subdomain) !== false) {

$this->subdomain = $subdomain;

// change path like /about/contact/ to /campaign.com/about/contact/
$_GET['it'] = "/{$subdomain}/" . ltrim($_GET['it'], '/');

// hook for path method to make path() and url() methods context aware
$this->addHookAfter('Page::path', $this, 'modifyPath');

}
}
}

public function modifyPath($event) {
$event->return = str_replace("{$this->subdomain}/", '', $event->return);;
}

static public function getModuleConfigInputfields(array $data) {

$fields = new InputfieldWrapper();
$modules = wire('modules');

$field = $modules->get("InputfieldTextarea");
$field->name = "subdomains";
$field->label = "Other sites running from same install";
$field->description = "Add each domain for their own line. Don't add http or https, just simple domain like: www.example.com tai campaign.example.com";
$field->notes = "IMPORTANT: create homepage for each of these domains right on the root. Name should be exactly same as the domain you use here.";
$field->attr('value', $data['subdomains']);
$fields->add($field);

return $fields;
}
}
Edited by apeisa
Updated the code using hook on Page::path method
  • Like 2
Link to comment
Share on other sites

Got one little problem: it seems that my subUrl method is not available through page field it is working.

This is still valid question though: Is there easy way to manipulate value that all url methods return? Using subUrl is fine, but I cannot use my old snippets and functions...

Link to comment
Share on other sites

This is still valid question though: Is there easy way to manipulate value that all url methods return? Using subUrl is fine, but I cannot use my old snippets and functions...

I was a little worried about making path() or url() hookable since they can feasibly be called hundreds or thousands of times in a request. I found a way to make functions hookable without adding any real overhead, except it requires defining two functions rather than one. But it'll be perfect for high-traffic function calls like this. So I've made Page::path hookable in this manner, and it's ready to go in the latest commit. Note that you'll want to hook the method, not the property. In the Page class, calling $page->path or $page->url resolves automatically to $page->path() or $page->url(), so if you are adding a hook, you want to hook the method.

I'm thinking we really only need $page->path() hookable (?), since it is what is used by $page->url(). The only difference between $page->url() and $page->path() is that $page->url() calls $page->path() and then prepends $config->urls->root to it. So $page->path is relative to the PW installation root, and $page->url is relative to the server's web root. Though in most installations, the two are the same, as most don't run PW from a subdirectory. The only other difference is that $page->url() trims off the trailing slash if its template says it should (I don't ever use that feature myself).

  • Like 1
Link to comment
Share on other sites

  • 2 months later...

Oliver: dev branch was last updated 4 months ago. Ryan uses it whenever there are big features that needs some testing (like there was with languages or/and repeater). Currently master branch is the "most edge" version.

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...