Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH Add domain support for the main site. #473

Closed

Conversation

GuySartorelli
Copy link
Member

Fixes #472

This ensures the AbsoluteLink for pages will always be correct for main site pages (if a domain is set up for the main site) - even when calling it from the context of a subsite. This allows easily linking to main site pages from subsites, as well as any other situation where the absolute URL for the main site needs to be fetched correctly.

@GuySartorelli
Copy link
Member Author

Note: In managed models, the title was set explicitly for the subsites tab to avoid the main site domains tab becoming the first tab.

Copy link
Contributor

@michalkleiner michalkleiner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @GuySartorelli, the approach looks sensible. I've added a few minor inline comments if you could look at those, thanks!

src/Admin/SubsiteAdmin.php Show resolved Hide resolved
src/Model/Subsite.php Outdated Show resolved Hide resolved
src/Model/Subsite.php Outdated Show resolved Hide resolved
src/Admin/SubsiteAdmin.php Outdated Show resolved Hide resolved
@michalkleiner
Copy link
Contributor

Though I always thought the main site has mechanisms to get its primary domain anyway, with or without using the subsites module. Is the issue rather in the bespoke code/additions or modules where it doesn't correctly pick the subsite e.g. from CLI or similar, and configs like alternate_base_url should be used instead?

@GuySartorelli
Copy link
Member Author

Thanks @GuySartorelli, the approach looks sensible. I've added a few minor inline comments if you could look at those, thanks!

Sweet! I'll make those changes shortly.

Though I always thought the main site has mechanisms to get its primary domain anyway, with or without using the subsites module. Is the issue rather in the bespoke code/additions or modules where it doesn't correctly pick the subsite e.g. from CLI or similar, and configs like alternate_base_url should be used instead?

So... in some situations the main site has mechanisms to get its primary domain. And sometimes they work. Sometimes they don't. For the times it doesn't work I have added a PR to allow that to be configured dynamically (see silverstripe/silverstripe-framework#10168) but that's a bit out of scope.

alternate_base_url is fine for most situations, but I'm often in a situation where the client hasn't made a final decision on the production domain until after we've already deployed code to the production environment, so I always end up adding in a field to the SiteConfig to store the main site domain anyway. This PR gives a more consistent place to set that domain and means I don't have to add it myself every time I add subsites to a codebase.

This ensures the AbsoluteLink for pages will always be correct for main site pages (if a domain is set up for the main site) - even when calling it from the context of a subsite. This allows easily linking to main site pages from subsites, as well as any other situation where the absolute URL for the main site needs to be fetched correctly.
@GuySartorelli
Copy link
Member Author

@michalkleiner I've made the requested changes.

@@ -885,6 +885,16 @@ public function domain()
*/
public function getPrimarySubsiteDomain()
{
// Main site
if (!$this->isInDB()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now seeing the method this is in and the not-in-db check... is there a better/different place this could go to? Alternatively, can we get more explanation why it's here and why we need to check it's not in the db?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative would be if (!$this->ID) {.
This is for situations like SiteTreeSubsites::alternateAbsoluteLink (inline below for convenience) where we call domain (which calls getPrimarySubsiteDomain) on the relationship directly from the has_one relation object.
If the page has no SubiteID (i.e. it belongs to the main site), the relation object will still be an instantiated Subsite object which has no ID and which returns false from isInDB - so we end up getting the main site domain.

I can't think of somewhere else to put the call, since the intention is to distinguish between a main site or subsite Subsite object (where a main site Subsite object is any Subsite object without an ID, effectively) when fetching the domain.

This allows project-specific code or code from other modules to remain the same (if they don't have the "if there is a subsite ID" check in place - in that case there's still only a very minor change required) and now get the added benefit of automagically fetching the correct main site domain as well.

public function alternateAbsoluteLink($action = null)
{
// Generate the existing absolute URL and replace the domain with the subsite domain.
// This helps deal with Link() returning an absolute URL.
$url = Director::absoluteURL($this->owner->Link($action));
$url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
return $url;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just realised I didn't explicitly say why we need to check for the main site vs an actual subsite there - the main site domains aren't stored on the Domains relation of any subsite object, so we can't just use $this->Domains() for the main site.

Copy link
Member

@emteknetnz emteknetnz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried this PR has a high chance of causing regressions when people run composer update

What will the experience be like for all existing sites that do not have SubsiteDomain's defined once this code is released?

Is this 100% backwards compatible with "Incomplete data"? Or is there an expectation that everyone will fill create a new SubsiteDomain record (they won't)

I'd need unit tests testing things like AbsoluteLink() on this PR both with and without a SubsiteDomain record on the main site to feel comfortable here

if ($this->owner->SubsiteID) {
$url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
}
$url = preg_replace('/\/\/[^\/]+\//', '//' . $this->owner->Subsite()->domain() . '/', $url);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we removing this check? If $this->owner->SubsiteID == 0 then this will cause an exception i.e. (null)->domain()

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm about 60% sure $this->owner->Subsite() would give a new Subsite object with no ID - but that would need to be checked if someone picks this PR up again. If that's not the case, then another mechanism will need to be added here to get the main site Domain where no subsite is set.

Copy link
Contributor

@NightJar NightJar Feb 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GuySartorelli
Copy link
Member Author

GuySartorelli commented Feb 1, 2022

Honestly it's been far too long since I've touched this PR. It needs work and I don't have the time to do it and we've found ways around this in the project I was working on at the time. Closing, but someone else can pick it up if they need something like this in their projects and haven't found their own workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Main site should have a domain
4 participants