Open mhsdesign opened 1 year ago
Also i went currently with anonymous functions, but anonymous classes might be even better (they do not support dependency injection directly, but i could extend a class with DI.
<?php
return new class('Neos.Demo:Content.Headline') extends NeosComponentFactory
{
public function fromNode(Node $node): string
{
return $node->getProperty("foo");
}
}
for dependency injection of any helpers, one could utilize inject*
or with DI
/** @var $container ContainerInterface */
return new class (
$container->get(SomeHelper::class)
) {
public function __construct(
private SomeHelper $someHelper
) {
}
};
return new class {
#[Flow\Inject]
public SomeHelper $someHelper; // note must be public, or could also be protected if we like to use reflection. (see php DI)
};
BDD -> Boilerplate driven design
return new class {
private SomeHelper $someHelper
public function injectSomeHelper(SomeHelper $someHelper): void
{
$this-> someHelper = $someHelper;
}
};
of back to (not autloaded classes)
<?php
namespace Any\Thing; // _should_ align at least to the package - but completely optional
// the class name can be any non conflicting name - must not be duplicated in the same namespace in codebase...
#[Component('Neos.Demo:Content.Headline')]
readonly class HeadlineFactory implements ComponentFactoryInterface
{
// via reflection like CompileTimeObjectManager, we can map the arguments
public function __construct(
private SomeHelper $someHelper
) {
}
}
or use real flow classes that would work with flows di. But this requires a proper psr4 setup and correct namespacing and file names ...
For out of band reload we need rendering entry points for each component, and how can we fix https://github.com/neos/neos-ui/pull/2892?
Also fusions rendering entry points are more specific, as one could have an element two times displayed on a page.
Question?
is a real factory to hard to setup and to bloaty (java style)
<?php declare(strict_types=1);
namespace Vendor\Site\Presentation\Image;
use Neos\Flow\Annotations as Flow;
/**
* @Flow\Scope("singleton")
*/
final class ImageFactory extends AbstractComponentPresentationObjectFactory
{
/**
* @param TraversableNodeInterface $node
* @return ImageInterface
*/
public function forImageNode(TraversableNodeInterface $node): ImageInterface
{
// Optional: Use assertions to ensure the incoming node type
assert($node->getNodeType()->isOfType('Vendor.Site:Content.Image'));
return new Image(
$node->getProperty('image__src')
? $this->uriService->getAssetUri($node->getProperty('image__src'))
: $this->uriService->getDummyImageUri()
$node->getProperty('image__alt') ?? '',
$node->getProperty('image__title')
);
}
}
How much are we really limited by php illegal keywords in class names?
do we want to allow mixing integration and presentation?
return #[Component('Neos.Demo:Content.Headline')] function(Node $node): string
{
return '<p>' . $node->getProperty('title') . '</p>';
};
or worse:
return #[Component('Neos.Demo:Content.Headline')] function(Node $node): string
{
ob_start();
?>
<p>hello</p>
<?php
return ob_get_contents();
};
keine Kindersicherung! alles ist erlaubt.
How critical are unplanned fusion overrides … for example for adjusting fe code of the fusion form builder
Hmm thinking about it
$content = editable(
renderingStuff: $renderingStuff,
property: 'title',
block: false
);
Feels a bit weird (maybe the name renderingStuff is too long and could be shortened to ctx
But how about extra methods or services on the renderingStuff
Like
$content = $renderingStuff->editable(
property: 'title',
block: false
);
$content = $renderingStuff->editable->for(
property: 'title',
block: false
);
Might be too bloaty but less god object:
Editable::for($renderingStuff)->get(
property: "title"
);
editable($renderingStuff)->for(property: 'title');
wilhelm said he likes $renderingStuff->editable()
but he would probably go for
$content = $renderingStuff->makeEditable(
property: 'title',
block: false
);
Also I remember the time where I was totally convinced by fluid because it appeared so simple, that why I build this https://neos-project.slack.com/archives/C04HF7TT9/p1624907972026500 (not really useful ^^, but whatever)
my point is to maybe reduce boilerplate code even more:
/** @var $node Node */
return new Headline(
$node->getProperty('title')
)
Which arguments should be available for the component factory
Node is the most obvious.
but it might make sense to add further ones like in the Component View
for contents:
for pages:
Currently im keeping the Controllercontext somewere global and dont pass it along everywhere. This is done similar to https://github.com/nezaniel/Nezaniel.ComponentView/blob/3cfb0f304a787dfb77cbab44e8f912ac79d0d604/Classes/Domain/UriService.php#L53 -> eventually we want to get rid of the controller context, but even then one might ask if i do want to pass the current actionRequest down to EVERY method. (Id like the tunnel through space a little better -> at least syntactically)
The global Controllercontext could be implemented and consumed with similar syntax for Reacts context.
caching
Also i was wondering how we would annotate caching and go cached by default (fusion) or uncached by default (ComponentView)
Maybe it would also be fun to have a useMemo similar to react
but it think this is most definitely a schnappsidee and not even helpful, as we want to cache whole node content components.
caching could be annotated via annotations
Helper functions vs static methods?
we will need a lot of helpers, basically what the fusion objects were doing and is neos specific. Native things like
join
will obviously replaceNeos.Fusion:Join
without further replacement.Following prototypes are critical
Neos.Neos:NodeUri
Neos.Neos:Editable
Neos.Neos:ConvertUris
Neos.Neos:ActionUri
Neos.Fusion:Resource
Neos.Neos:ContentCollection
Neos.Neos:ContentCase
(for delegating a node)...
in my super early draft, i decided for functions, as they are fun to look at - but they are not fun to implement.
files
in composer.jsonBootstrap::$staticObjectmanger
manually ...vs