-
-
Notifications
You must be signed in to change notification settings - Fork 224
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
Discussion improve site entity and site node relation #4470
Comments
As discussed the real goal would be to remove our neos site entity at one point and save the domains in the I updated the pr description and we will evaluate how much effort this may take and if its realistic to fix with 9.0 |
Early thoughts about implementation: the scoped properties (maybe via #4779) could be used for the domains and stuff: 'Neos.Neos:Site':
# ..
properties:
domains:
scope: nodeAggregate
type: array<Neos\\Neos\\Domain\\Model\\Domain>
primaryDomain:
scope: nodeAggregate
type: Neos\\Neos\\Domain\\Model\\Domain
siteResourcesPackageKey:
scope: nodeAggregate
type: string
assetCollection:
scope: nodeAggregate
type: Neos\\Media\\Domain\\Model\\AssetCollection The site config (which might be reworked via #4582) would still depend on the node name (which must be unique by convention across multiple crs) |
How do you find the node with the right domain though if you don't know where to look during routing? |
While discussing this topic in Slack we realized that the Node can't be the central authority for sites because there is no central Content Repository. Instead I would suggest the following:
|
immutable site read modelAs discussed with @kitsunet the site state (offline / online) might be dropped as this is not an important feature. I played a bit around and the php code of the repository could look like this: interface SiteRepository
{
/**
* Find the site that was specified in the configuration `Neos.Neos.defaultSiteNodeName`
*
* If the configuration is not set it must fall back to the first available site or return null
*
* @throws \Neos\Neos\Domain\Exception if the configuration is invalid and the default site is not found
*/
public function findDefault(): ?Site;
public function findByDomain(Domain $domain): ?Site;
public function findByHost(UriInterface $uriWithHost): ?Site;
public function findAll(): iterable;
public function findOneByNodeName(SiteNodeName $siteNodeName): ?Site;
/**
* Finds a given site by site node.
*
* @throws \Neos\Neos\Domain\Exception in case the passed $siteNode is not a real site node or no site matches this site node
*/
public function findSiteBySiteNode(Node $siteNode): Site;
} The Site model will be stripped down and become and immutable vo. As the site will be build from the configuration it will already hold all information of final readonly class Site
{
public function __construct(
// from SiteConfiguration
public ContentRepositoryId $contentRepositoryId,
public RoutingConfiguration $routingConfiguration,
// original properties:
/** Name of the site */
public string $name, // todo name is actually bit confusing and doesnt declare that this might be a human readable label. So label or title would fit better.
/** The node name of this site */
public SiteNodeName $nodeName,
/** The key of a package containing the static resources for this site */
public string $siteResourcesPackageKey, // todo maybe just name it $packageKey?
public ?Domains $domains,
// todo how ???
// public AssetCollection $assetCollection,
) {
}
}
final readonly class Domains implements \IteratorAggregate
{
private function __construct(
public Domain $primaryDomain,
private array $rest,
) {
// deduplication logic
}
public static function create(Domain $primaryDomain, Domain ...$rest)
{
return new self($primaryDomain, $rest);
}
public function getIterator(): Traversable
{
yield $this->primaryDomain;
yield from $this->rest;
}
}
final readonly class Domain
{
public function __construct(
public string $hostname,
public ?string $scheme,
public ?int $port
) {
}
}
final readonly class RoutingConfiguration
{
public function __construct(
public string $contentDimensionResolverFactoryClassName,
public array $contentDimensionResolverOptions,
public DimensionSpacePoint $defaultDimensionSpacePoint,
public string $uriPathSuffix,
) {
}
} migrating things: all setters will be removed so no mutation via the repository nor the value objects is indented. This has to be manually implemented behind the scenes ;) // the state will be removed -> if someone needs it this he can implement by returning from the SiteRepository only the online ones. By that we reduce complexity a lot.
getState()
isOnline()
isOffline()
STATE_ONLINE = 1;
STATE_OFFLINE = 2;
// this internal signal will be removed
emitSiteChanged();
// simple properties will persist
getName() -> $site->name
getNodeName() -> $site->nodeName
getSiteResourcesPackageKey() -> $site->siteResourcesPackageKey
getAssetCollection() -> $site->assetCollection
// 9.0 specific configuration stuff
getConfiguration()->contentRepositoryId -> $site->contentRepositoryId
getConfiguration()->contentDimensionResolverFactoryClassName -> $site->routingConfiguration->contentDimensionResolverFactoryClassName
getConfiguration()->contentDimensionResolverOptions -> $site->routingConfiguration->contentDimensionResolverOptions
// contentDimensions.defaultDimensionSpacePoint must be actually required to be set otherwise there is trouble as [] is not always valid
getConfiguration()->defaultDimensionSpacePoint -> $site->routingConfiguration->defaultDimensionSpacePoint
getConfiguration()->uriPathSuffix -> $site->routingConfiguration->uriPathSuffix
// domain related
getDomains() -> $site->domains
hasActiveDomains() -> $site->domains !== null
getActiveDomains() -> iterator_to_array($site->domains)
getFirstActiveDomain() -> $site->domains->primaryDomain
getPrimaryDomain() -> $site->domains->primaryDomain |
The above read model would be backed primarily out of the box by a This requires us to adjust how sites are registered in Naturally this would mean having to duplicate all the "basic" options every time. But with the Site Config Presets this will not be necessary #4582 Currently in 9.0 the configuration might look like: Neos:
Neos:
sites:
'*':
uriPathSuffix: '.html'
contentRepository: default
contentDimensions:
resolver:
factoryClassName: Neos\Neos\FrontendRouting\DimensionResolution\Resolver\AutoUriPathResolverFactory But with the Site Config Presets and the SiteConfigurationSource we would write: Neos:
Neos:
sitePresets:
'default':
uriPathSuffix: '.html'
contentRepository: default
contentDimensions:
resolver:
factoryClassName: Neos\Neos\FrontendRouting\DimensionResolution\Resolver\AutoUriPathResolverFactory
sites:
'my-site-node-name':
preset: 'default'
name: "My Site Titel"
siteResourcesPackageKey: "Neos.Demo"
domains:
primaryDomain:
hostname: "localhost"
scheme: "http"
port: 8080
additionalDomains:
-
hostname: "www.lol.de"
assetCollection: null # todo how to actually reference an assetCollection??? via Persistence_Object_Identifier??? DiscussionsAlternative
|
Last Friday we discussed the above idea in the dev meeting:
Following points were made: Pro (Bastian & Marc Henry):
Con (Martin & Denny):
Jain - in between - (Christian)
Conclusion As this was discussed super controversially without a clear voting in favour we decided against this. |
@mficzel and me are currently discussing how to reduce the ambiguity in fusion as having the siteNODE available as The change to add Deprecating Additionally we discussed that when we want to allow creating sites on the fly as they are a entities its unhelpful that the contentRepository is only configurable by setting and not on the creation in the modal. Also the neos-development-collection/Neos.Neos/Tests/Behavior/Features/Bootstrap/RoutingTrait.php Line 117 in c34456b
A way out could be to leverage the new
Leaving us with the following structure new Site(
contentRepositoryId: ...,
nodeAggregateId: ...,
presetName: ...,
name: ..., // rather a label?
domains: ...,
primaryDomain: ...,
state: ...,
assetCollection: ...,
) Neos:
Neos:
sitePresets:
'my-preset':
resourcesPackageKey: 'Neos.Demo'
uriPathSuffix: '.html'
contentDimensions:
resolver:
factoryClassName: Neos\Neos\FrontendRouting\DimensionResolution\Resolver\UriPathResolverFactory
options:
segments:
-
dimensionIdentifier: language
dimensionValueMapping:
# Dimension Value -> URI Path Segment
de: deu
en: uk class SiteService
{
public function getPresetForSite(Site $site): SitePreset;
// ... further fetching and creation api
} cc @kitsunet |
Having the concept of a site entity (doctrine) and a site node (cr) is not ideal:
We discussed already several ways of improving their relationship:
neos-development-collection/Neos.Neos/Classes/Domain/Service/SiteService.php
Line 169 in a9d381e
site
in fusion is a site node, while in php we often mean by$site
the site entity (which is mostly unused in fusion) -> the same discussion came up with the introduction of !!! FEATURE: AddNeos.Neos:Site
(singular) NodeType for site nodes #4531 where we discussed to name itNeos.Neos:Site
orNeos.Neos:HomePage
. We decided for Site and declared the site entity rather legacy and some time to be replaced.Neos.Neos:Site
(singular) NodeType for site nodes #4531. The idea would use aggregate scoped properties for all the fields a site entity had and completely remove the site entity. In places where we need a site but have no specific information about the dimension we would pass the site node aggregate. The experiment can be found here: Experiment: ReplaceSiteEntity
withSiteNodeAggregate
#4780Neos.Neos.sites
. See Discussion improve site entity and site node relation #4470 (comment)The text was updated successfully, but these errors were encountered: