apeisa

Multisite

Recommended Posts

Multisite and Jumplinks

Can't remember if this was brought up before, but I think there may be a need to have Jumplinks v2 support Multisite. Besides there being two dev branches and referrals to how things can get messy, I think an implementation on the Jumplinks-side would be easy enough.

Do you think it would be simple enough to have the jumplink editor list valid domains from config so the user can select which domain(s) the jumplink belong(s) to?

Also, I'd be interested to know how many use the core multisite method (multiple site dirs sharing a single core) vs those who use this module, as I'd need a different method to obtain the valid domains for those using the core method.

Lastly, is the current dev2 going to make it to master any time soon?

Share this post


Link to post
Share on other sites

Hi, all,

we are trying to automate the module config setting for admin users that only have access to the page tree. The idea is that these admin users should be able to create new pages with the specific multisite template and the page name is automatically added to the multisite config array on page creation.

Sadly the hook does not work :-(  It is placed in the ready.php:

$this->addHookAfter('Pages::add', function($event) {
	  $page = $event->arguments[0];

    if ($page->template == 'project_home') { //check template of page added
    
      // get new domain from page name
      $new_domain = $page->name; 

      // get config data and save it to var
      $config = wire('modules')->getModuleConfigData('Multisite'); 
      $data = $config['subdomainsArray']; 
      
      // add new domain to config data and save it
      array_push($data, $new_domain);
      wire('modules')->saveModuleConfigData('Multisite', $data); 
    }
});

Any clues?

Share this post


Link to post
Share on other sites

@mikel I guess you use the current master. This version is not supported anymore.

New versions (dev, dev2)  https://github.com/somatonic/Multisite/tree/dev2#add-multisitedomains this config was changed to be in site/config.php for various reasons . So the domain array is added to $config and it doesn't matter where. it could also be in a module.

I'm not sure what doesn't work in your example, it could be that it is in ready.php or the hook ::add should be ::added. Just wanted to mention that this if you use the master version it won't be compatible in future versions.

  • Like 1

Share this post


Link to post
Share on other sites

Hi, Soma,

thanks for the quick reply. The hint (::added) was correct. It pointed me to other problems, so we could work everything out. 
Here is the working code for automating the modules config (placement in ready.php):

$this->addHookAfter('Pages::added', function($event) {
	  $page = $event->arguments[0];

    if ($page->template == 'NAME_OF_TEMPLATE') { //check template of page added
    
      // get new domain from page name
      $new_domain = $page->name; 

      // get config data and save it to var
      $config = wire('modules')->getModuleConfigData('Multisite'); 
  
      // add new domain to config data and save it
      $config['subdomains'].= "\n".$new_domain;
      wire('modules')->saveModuleConfigData('Multisite', $config); 
    }
});

I will work on Hooks for Pages::trashed and Pages::renamed.

As this is a client project, we will not upgrade unless we get paid for it, so we will stick with this solution for some time ;-)

So here are the other two mentioned hooks. Both are working:

$this->addHookBefore('Pages::renamed', function($event) {
	  $page = $event->arguments[0];

    if ($page->template == 'NAME_OF_TEMPLATE') { //check template of page added
    
      // get old domain from page name
      $old_domain = $page->namePrevious;
      
      // get new domain from page name
      $new_domain = $page->name; 

      // get config data and save it to var
      $config = wire('modules')->getModuleConfigData('Multisite'); 
      
      // replace changed domain in config data and save it
      $config['subdomains'] = str_replace($old_domain, $new_domain, $config['subdomains']);
      wire('modules')->saveModuleConfigData('Multisite', $config); 
    }
});

$this->addHookBefore('Pages::trashed', function($event) {
	  $page = $event->arguments[0];

    if ($page->template == 'NAME_OF_TEMPLATE') { //check template of page added
      
      // get domain from page name
      $domain = $page->name; 

      // get config data and save it to var
      $config = wire('modules')->getModuleConfigData('Multisite'); 
      
      // remove deleted domain from config data and save it
      $config['subdomains'] = str_replace("\n".$domain, '', $config['subdomains']);
      wire('modules')->saveModuleConfigData('Multisite', $config); 
    }
});

 

Share this post


Link to post
Share on other sites

Forked this module a few days ago and ended up in a complete rewrite. Still under development and testing but working properly here.

What is different?

  1. Do not worry about page naming. The root page is defined via ID.
  2. Full multilanguage support *
  3. take in account $template->slashUrl settings
  4. take in account LanguageSupportPagenames::useHomeSegment settings
  5. Fallback to default 404 page if custom 404 is not set
  6. Throws exception in case of misconfiguration
  7. Access of pages residing in a MultisitePageTree for other domains other than the corresponding root page is disallowed except for superuser
  8. Pages inside a MultisitePageTree accessible only via the modified url if called from the corresponding domain (throws 404 instead of unexpected redirects)
  9. Page paths are set via hook in Page::path() instead of modifying the return of Page::render()
  10. Crosslink support via the RTE (CK Editor) Link plugin
  11. Page view links in admin with correctly modified urls

* under conditions: see next post!
Feedback welcome. Have a try: https://github.com/kixe/Multisite/tree/kixe

  • Like 6

Share this post


Link to post
Share on other sites

Not sure why you need to rewrite it. Current last version is the essence of 2-3 experience using it.

Just wanted to mention that for good reasons the module doesnt hook page path anymore cause it creates all sort of problem with core and other modules. Also id based root isnt tranportable thats why i have done it via config and page names.

Good luck.

Share this post


Link to post
Share on other sites

i'm trying to get the multisite module to work, but i guess there is something i am missing, i hope someone can help:

this is my page tree

-web
--www.domain1.net
---404 Domain1
--www.domain2.info
---page2
---Domain2 Not Foundffff
-Admin
-Trash

then i added this into config.php

$config->MultisiteDomains = array(
    "domain1.net" => array( 
            "root" => "www.domain1.net", 
            "http404" => 1023
        ),
    "domain2.info" => array(
            "root" => "www.domain2.info",
            "http404" => 27
        )
);

and

$config->httpHosts = array('www.domain1.net', 'domain1.net', 'www.domain2.info', 'domain2.info');

and both domains are pointing to the same directory

 

and now both www.domain1.net and www.domain2.info shows me the "-web" page

and anything else shows the Domain2 not foundffff PAge with ID 27 (www.domain2.info/web/page2, www.domain2.info/page2 and any other URL)

 

i have the module 

Multisite
MODULE VERSION SUMMARY
Multisite	0.1.0

showing up under modules page

 

I use PW under www.domain1.net/myadmin and the links-Button in the page-tree points to http://www.domain1.net/www.domain1.net and http://www.domain1.net/www.domain2.info

 

Now i tried to install the old module Multisite    0.0.1, now i have an additional settings field on the modules page which i did not have with the new module. The Domains and the subsites are working, but i cannot get to the backend anymore www.domain1.net/myadmin shows mie the 404 site... ahhhh, i'm confused :(

 

is there something missing? do i have to add anything else ?

 

Thanks for any help !!

Edited by NoremPload
adding info

Share this post


Link to post
Share on other sites

0.1.0 is the correct version I recommend. I'm not sure, looks correct except you have config "domain1.net" but you access the site with www.domain1.net? It should match I think.

Share this post


Link to post
Share on other sites

Thx Soma, this brought me one little step further, but not to the end ;)

i changed the config to

$config->MultisiteDomains = array(
    "www.domain1.net" => array( 
            "root" => "www.domain1.net", 
            "http404" => 1023
        ),
    "www.domain2.info" => array(
            "root" => "www.domain2.info",
            "http404" => 27
        )
);

and the page tree to

- web
	-- www.domain1.net
		--- 404 Domain 1
		--- page1
	-- www.domain2.info
		--- page1
		--- page2
		--- 404 domain 2
- Admin
- Trash

www.domain1.net shows me -- www.domain1.net and www.domain2.info shows -- www.domain2.info

but any subpages are showing the 404 page 

www.domain1.net/page1 => www.domain1.net/404domain1

and

www.domain2.info/page1 + www.domain2.info/page2 => www.domain2.info/404domain2

another strange thing: www.domain2.info => page1 was called calculator before and www.domain2.info/calculator/ worked, after renaming it to page1 www.domain2.info/page1/ doesn't work, going back to calculator, www.domain2.info/calculator/ works again

i really don't have any idea whats going on ;(

 

edit: i logged the modify part in the module

// we modify the GET it to tell PW what page to load
$_GET['it'] = (isset($_GET['it']))
	? "$langSegment{$domainPageName}/" . $this->it
	: "$langSegment{$domainPageName}/";

$this->log( '$_GET[it]: ' . serialize($_GET['it']));

and got this

$_GET[it]: s:28:"www.domain2.info/page1";

i guess thats what it should be, but the request does not work :( i always get the 404 page

 

Finally i solved it after a lot of try and error

the only thing i had to change was removing .info or change it to .inf 

  "www.domain2.info" => array(
            "root" => "www.domain2.inf",
            "http404" => 27
        )

in the config and in the paht, now it works.

 

other 4 letter domains are working, only info brings the error

 

Share this post


Link to post
Share on other sites

I just tried and changed my setup to a pw27.info and pw27b.info and its working fine. I don't see any reason why domain name would make a difference. I even uninstalled languages support to rule that out.

I also don't know which PW version we are talking about. Also 404 page of server or PW? 

The config is correct and works here. Also config root name doesn't have to be the domain it could be "foo" or "bar".

Only thing I can imagine is if you have a folder called "page1" in your install that would conflict with PW (nothing to do with multisite)

Share this post


Link to post
Share on other sites

Thx Soma for trying to find out what's going on.

I just tried to rename everything to

www.super.info => does not work

www.super.inf => does work

I really have no clue what's wrong, but it works with .inf, so i'll work with this ;)

 

@404, i get the correct 404 page not the server 404 page

 

Share this post


Link to post
Share on other sites

I have a couple of questions about the module,

I am using multisite 0.0.6 (unsure if this is the latest?) in conjunction with Admin Restrict Branch, in the admin area I am going to have a couple of admin listing pages that will, for example list all the pages with the template 'bob'. The admin restrict is setup so when 'user1' logs in they can only see the user1 branch, and same for 'user2' and so on. Each users domain is setup so it is 'user1.example.com'. What I am after is when a user logs in and goes to the listing page, it will find all of the template 'bob' but only in their brand. 

<?php
foreach($pages->find("template=bob") as $bob):
	echo $bob->title;
endforeach;
?>
Right now this code, displays all of the pages that have the 'bob' template not just the ones in the restricted branch.
Any ideas?
This works to find the 'user1' page if user1 is logged in. But I can't figure it out.

<?php
	// This is the variable for the root users page (i.e the users home page)
	$userroot = $pages->find("name=" . $user->name);
?>


Also, I would like the same in the frontend, so when a user goes to 'user1.example.com' and I run the same code as above it will do the same thing.
For now, I have done this, which works. I don't know if this is good practice or not?

<?php
$pages = $page->rootParent;
?>

-main
--user1
---Page1 (template=bob)
---Page2 (template=bob)
--user2
---Page3 (template=bob)
---page4 (template=bob)
-Admin
--Listing Page
-Trash

Share this post


Link to post
Share on other sites
On 6/18/2017 at 3:45 PM, xfroggy said:

I have a couple of questions about the module,

I am using multisite 0.0.6 (unsure if this is the latest?) in conjunction with Admin Restrict Branch, in the admin area I am going to have a couple of admin listing pages that will, for example list all the pages with the template 'bob'. The admin restrict is setup so when 'user1' logs in they can only see the user1 branch, and same for 'user2' and so on. Each users domain is setup so it is 'user1.example.com'. What I am after is when a user logs in and goes to the listing page, it will find all of the template 'bob' but only in their brand. 


<?php
foreach($pages->find("template=bob") as $bob):
	echo $bob->title;
endforeach;
?>

Right now this code, displays all of the pages that have the 'bob' template not just the ones in the restricted branch.
Any ideas?
This works to find the 'user1' page if user1 is logged in. But I can't figure it out.


<?php
	// This is the variable for the root users page (i.e the users home page)
	$userroot = $pages->find("name=" . $user->name);
?>

Also, I would like the same in the frontend, so when a user goes to 'user1.example.com' and I run the same code as above it will do the same thing.
For now, I have done this, which works. I don't know if this is good practice or not?


<?php
$pages = $page->rootParent;
?>

-main
--user1
---Page1 (template=bob)
---Page2 (template=bob)
--user2
---Page3 (template=bob)
---page4 (template=bob)
-Admin
--Listing Page
-Trash

I am a bit silly, 

$client = $pages->get("name=" . $user->name);

Replaced

$client = $pages->find("name=" . $user->name);

Which now means I can go

<?php
foreach($client->find("template=bob") as $bob):
	echo $bob->title;
endforeach;
?>

I feel a bit silly about that, it was a simple fix between find() and get().

Share this post


Link to post
Share on other sites

Hi, i'm back again with some questions about the module :)

How do i get the id of the current used sites root page in a template?

$config->MultisiteDomains = array(
    "www.someurl.net" => array( 
            "root" => "www.someurl.net", <====== page id of this page ???
            "http404" => 1023

 

and how do i pick this up in a template ?

 

// Multisite.module - Line 84

// set the current domain, so it can be picked up in templates or other modules
$this->domain = $httpHost;

Thanks for any help !!

Share this post


Link to post
Share on other sites
// @see: https://github.com/somatonic/Multisite/tree/dev#good-to-know-some-variables
echo $page->rootParent->id;

... should work :) 

Share this post


Link to post
Share on other sites

solved: host is with www. now 😉

It's me again 😉

Currently all my sites are running on http, but now it's time to change to https.

But if i call the site with https instead of http i just get a white page, anything i have to do in the config for using https?

The output is the root page (web), not the page that should be linked to the domain in the page tree (page2).

 

-web
-- page1
-- page2

 

Thanks!

Share this post


Link to post
Share on other sites

Hi!

Everything work as expected with my configuration of the Multisite module :

$config->MultisiteDomains = array(
    "foo.com" => array( // domain name can be used to map to root page
            "root" => "/ml", // page name for the root page
            "http404" => 27
        ),
    "law.foo.com" => array( // domain name can be used to map to root page
            "root" => "/law", // page name for the root page
            "http404" => 27
        )
);

…except when I try to loop over pages:

    $siteRoot = $page->rootParent;
    $parent = "/".$siteRoot->name."/projects";

    $projects = $pages->find("template=project, parent=$parent, sort=sort");
    foreach($projects as $project){
      $firstimg = $project->images->first->width(1000);
      echo "<a href='{$project->url}'><img src='{$firstimg->url}'></a>";
    }

The code below outputs a list of links that targets

foo.com/ml/projects/post-title
foo.com/law/projects/post-title

instead of

foo.com/projects/post-title
law.foo.com/projects/post-title

What am I doing wrong?

Share this post


Link to post
Share on other sites

No idea. What module and version are you using? And btw /xxx is not a page name. Also PW uses trailing slash (default).

  • 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 Anssi
      A simple module to enable easy navigation between the public and the admin side of the site. After installation a green bar will appear to the upper side of the screen, containing a few navigation elements and displaying the PW version number.
      Heavily inspired by @apeisa's great AdminBar (Thanks!). I needed a bit simpler tool for my projects and as a result, this was made. Available on GitHub .

    • By Sebi
      I've created a small module which lets you define a timestamp after which a page should be accessible. In addition you can define a timestamp when the release should end and the page should not be accessable any more.
      Github: https://github.com/Sebiworld/PageAccessReleasetime
      Usage
      PageAccessReleasetime can be installed like every other module in ProcessWire. Check the following guide for detailed information: How-To Install or Uninstall Modules
      After that, you will find checkboxes for activating the releasetime-fields at the settings-tab of each page. You don't need to add the fields to your templates manually.
      Check e.g. the checkbox "Activate Releasetime from?" and fill in a date in the future. The page will not be accessable for your users until the given date is reached.
      If you have $config->pagefileSecure = true, the module will protect files of unreleased pages as well.
      How it works
      This module hooks into Page::viewable to prevent users to access unreleased pages:
      public function hookPageViewable($event) { $page = $event->object; $viewable = $event->return; if($viewable){ // If the page would be viewable, additionally check Releasetime and User-Permission $viewable = $this->canUserSee($page); } $event->return = $viewable; } To prevent access to the files of unreleased pages, we hook into Page::isPublic and ProcessPageView::sendFile.
      public function hookPageIsPublic($e) { $page = $e->object; if($e->return && $this->isReleaseTimeSet($page)) { $e->return = false; } } The site/assets/files/ directory of pages, which isPublic() returns false, will get a '-' as prefix. This indicates ProcessWire (with activated $config->pagefileSecure) to check the file's permissions via PHP before delivering it to the client.
      The check wether a not-public file should be accessable happens in ProcessPageView::sendFile. We throw an 404 Exception if the current user must not see the file.
      public function hookProcessPageViewSendFile($e) { $page = $e->arguments[0]; if(!$this->canUserSee($page)) { throw new Wire404Exception('File not found'); } } Additionally we hook into ProcessPageEdit::buildForm to add the PageAccessReleasetime fields to each page and move them to the settings tab.
      Limitations
      In the current version, releasetime-protected pages will appear in wire('pages')->find() queries. If you want to display a list of pages, where pages could be releasetime-protected, you should double-check with $page->viewable() wether the page can be accessed. $page->viewable() returns false, if the page is not released yet.
      If you have an idea how unreleased pages can be filtered out of ProcessWire selector queries, feel free to write an issue, comment or make a pull request!
    • By David Karich
      Thanks to the great Pro module "RepeaterMatrix" I have the possibility to create complex repeater items. With it I have created a quite powerful page builder. Many different content modules, with many more possible design options. The RepeaterMatrix module supports the cloning of items, but only within the same page. Now I often have the case that very design-intensive pages and items are created. If you want to use this module on a different page (e.g. in the same design), you have to rebuild each item manually every time.
      With this proof of concept I have created a module which adds the feature to copy a repeater item to the clipboard so that you can paste this item to another page with the same repeater field. The module has been developed very rudimentarily so far. It is currently not possible to copy nested items. There is also no check of Min/Max. You can also only copy items that have the same field on different pages. And surely you can solve all this more elegantly with AJAX. But personally I lack the deeper understanding of the repeaters. Also missing on the Javascript side are event triggers for the repeaters, which would make it easier. Like e.g. RepeaterItemInitReady or similar.
      it would be great if @ryan would implement this functionality in the core of RepeaterMatrix. I think he has better ways to implement this. Or what do you think, Ryan?
      Everybody is welcome to work on this module and improve it, if it should not be integrated into the matrix core. Therefore I put it for testing and as download on GitHub: https://github.com/FlipZoomMedia/InputfieldRepeaterMatrixDublicate
      You can best see the functionality in the screencast: 
       
    • By anderson
      Hi,
      Please take a look at this:
      https://templatemag.com/demo/Good/
      The upper nav bar, including dropdowns like "pages" and "portfolios", what do you call this whole thing? At first I guess it's called "dropdown nav bar", but seems not.
      AND of course, what's the simplest way/module to achieve this in PW?
      Thanks in advance.
    • By Sebi2020
      Hey, I'm new and I created a simple module for tagging pages because I didn't found a module for it (sadly this is not a core feature). This module is licensed under the GPL3 and cames with absolutly no warranty at all. You should test the module before using it in production environments. Currently it's an alpha release. if you like the module or have ideas for improvements feel free to post a comment. Currently this fieldtype is only compatible with the Inputfield I've created to because I haven't found  an Inputfield yet, that returns arrays from a single html input.
      Greetings Sebi2020
      FieldtypeTags.zip.asc
      InputfieldTagify.zip
      InputfieldTagify.zip.asc
      FieldtypeTags.zip