Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

All other Modules /

Discuss all other Modules here.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Subsites Module access content from pages in Main.

Go to End

5 Posts   2315 Views


Community Member, 165 Posts

1 September 2009 at 7:48am

I have some pages in the Main site that I need to access the Content of from all the subsites. At this point It seems that the $disable_subsite_filter = false; in Subsite.php blocks access to DataObject::get('SiteTree',..... for any page not in the current subsite even SubsiteID = 0 pages.

How can I access pages in SubsiteID = 0 from other subsites?


Forum Moderator, 4102 Posts

1 September 2009 at 8:20am

Hi, Micah,

I did this on a recent project. Took a little bit of hacking, but my approach was to set up a relationship of SiteTree -> MM -> Subsites and each page has a "Publication" tab where you click off which subsites can access the content on this page. "Global" is also an option.

I then had to hack the augmentSQL() function in SiteTreeSubsites to make it aware of the new filtering rules (or lack thereof).

Here are the major changes to SiteTreeSubsites.php:

	function extraStatics() {
		if(!method_exists('DataObjectDecorator', 'load_extra_statics')) {
			if($this->owner->class != 'SiteTree') return null;
		return array(
		  'db' => array(
		    'GlobalContent' => 'Boolean'
			'has_one' => array(
				'Subsite' => 'Subsite', // The subsite that this page belongs to
				'MasterPage' => 'SiteTree', // Optional; the page that is the content master
			'many_many' => array(
			   'Subsites' => 'Subsite'

	function augmentSQL(SQLQuery &$query) {
		if(Subsite::$disable_subsite_filter) return;
		// If you're querying by ID, ignore the sub-site - this is a bit ugly...
		if(!$query->where || (strpos($query->where[0], ".\"ID\" = ") === false && strpos($query->where[0], ".`ID` = ") === false && strpos($query->where[0], ".ID = ") === false && strpos($query->where[0], "ID = ") !== 0)) {

			if($context = DataObject::context_obj()) $subsiteID = (int) $context->SubsiteID;
			else $subsiteID = (int) Subsite::currentSubsiteID();

			// The foreach is an ugly way of getting the first key :-)
			foreach($query->from as $tableName => $info) {
    		$query->from['SiteTree_Subsites'] = "LEFT JOIN SiteTree_Subsites ON SiteTree_Subsites.SiteTreeID = `$tableName`.ID";
    		$query->from['Subsites'] = "LEFT JOIN Subsite ON Subsite.ID = SiteTree_Subsites.SubsiteID";

				$where = "(`$tableName`.SubsiteID IN ($subsiteID)) OR (`$tableName`.GlobalContent = 1) OR `Subsite`.ID = $subsiteID";
				if(defined('Database::USE_ANSI_SQL')) {
					$where = "\"$tableName\".\"SubsiteID\" IN ($subsiteID)";
				// The tableName should be SiteTree or SiteTree_Live...
				if(strpos($tableName,'SiteTree') === false) break;
				$query->where[] = $where;

	function updateCMSFields(&$fields) {
		if($this->owner->MasterPageID) {
			$fields->insertFirst(new HeaderField('This page\'s content is copied from a master page: ' . $this->owner->MasterPage()->Title, 2));
		// replace readonly link prefix
		$subsite = $this->owner->Subsite();
		if($subsite && $subsite->ID) {
			$baseUrl = 'http://' . $subsite->domain() . '/';
				new LabelField('BaseUrlLabel',$baseUrl),
		if($this->isMainSite()) {
		  $fields->addFieldToTab("Root.Content.Publication", new CheckboxField('GlobalContent','This page can be viewed by all subsites'));
      $map = ($subs = DataObject::get("Subsite")) ? $subs->toDropdownMap() : array();
		  $fields->addFieldToTab("Root.Content.Publication", new CheckboxSetField('Subsites','This page is only visible on the following subsites',$map));

And to Subsite.php;

	static $belongs_many_many = array(
	   'SiteTree' => 'SiteTree'

That should be it. I also hacked the Subsite module to support multiple domains, not just subdomains, if you're interested in that, too.


Community Member, 165 Posts

1 September 2009 at 8:31am

Wow, that is a lot of code. I will have to take some time to look into it. Thanks for sharing your hard work.


Community Member, 5 Posts

2 September 2009 at 3:49am

UncleCheese: I would be definitely be interested in the domain hack, if you wouldn't mind sharing.


Forum Moderator, 4102 Posts

2 September 2009 at 4:22am

I've attached my Subsites.php and my SiteTreeSubsites.php. These should give you the content syndication plus the ability to use domains instead of subdomains.

A note about the domain hack. It's not perfect. The Subsites module will yell at you if you leave the subdomain blank on create, but if you put in a junk value and then go back and remove it on edit, you can get it to retain the null value.

I believe these are the only files I modified. If they don't work for you, let me know and I'll look around.