You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently i'd say that Expose is feature-wise at above 90% complete. There is little to no documentation currently aside from a little demo package i did to test + maintain it. One reason i didn't yet write documentation or shouted out to other people that they should use expose is my feeling, that we took a wrong direction. The introduction of TYPO3.Form and TYPO3.TypoScript added a flexibilty to the whole thing that you can't really find in other "admins". But it adds a huge amount of complexity. After using it extensively for 2 Customer projects this complexity feels plain wrong. It seems the direction expose went, got it to probably 70-80% on a DRY scale, yet we dropped well below 30% on a KISS scale. The performance was an issue as well, which is improved through the TypoScript caching, yet that's one more thing that you need to configure and take care of :/.
Because of this i've had a brewing idea in my head for a while:
remove TYPO3.TypoScript
remove TYPO3.Form
simple inheritance + fallback based controllers
viewHelpers to make forms concise and easy to maintain
processViewHelper to easily filter, sort, paginate, limit tables/lists without complex widgets
I did a little prototype the last few days, it's quite rough in some places of course, but basically i've got a complete simple crud workflow working already :)
https://github.com/mneuhaus/Famelo.Components
Currently, if you inherit from a controller that contains actions you need to copy over every template for that actions to your inheriting controller to use them. Imho the view of the controller should follow the same principles as the controller inheritance itself. E.g. use the template/layout/partials from the inherited controller, if it's not overridden in the extending controller.
Usecase
Given you have an CrudController with an action "index" and an template inside "Templates/Crud/Index.html".
When you create a "PostController" that extends from that controller.
Then it should use the template "Templates/Crud/Index.html" for the index action.
When you create a template "Templates/Post/Index.html"
Then it should use the template "Templates/Post/Index.html" for the index action.
Example
This way we can create a simple, easily extendable base CrudController that you can use like this:
One general hassle the TYPO3.Form package tries to solve is the easy creation of forms, which it does pretty good
for static forms. But for Expose this seems to be one more abstraction that adds complexity, performance overhead
and quite some code to actually make that work together. And if you want to create a new form control you have
to Add it to the Settings.yaml, create a template for it and configure that template to be used in the Schema.ts.
After using Expose in customer projects this gets a nasty forest of configuration files that doesn't make any fun.
Instead i would proprose a new ViewHelper called "<f:form.field/>".
This ViewHelper composes a lot of boilerplate code like this:
select a Partial to render the form control based on the propertyType
wrap that rendered form control with the Default or specified wrap
inside that wrap you get property specific validation errors included
Example:
If the property "someProperty" is of type "string" it will choose the Partial "Form/Field/Textfield.html" by default to render that control.
Since no specific wrap was specified for that field the control will then be rendered into a default wrap like for example for bootstrap.
Custom Control
If you specify an additional argument "control" for the fieldViewHelper like this:
Then it will use the default Partial to render that control and put that into a wrap called "Form/Wrap/Zurb.html".
Bottom line
As you can see, this approach would reduce the boilerplate code needed for forms without giving up much
flexibility.
The CrudController can for the simple default case simple loop over all the entity properties like this:
One thing that the TYPO3.TypoScript introduction brought with it was the concept of processors to wrap tables/lists with things like sort, filter, search, paginate, etc. I think we could bring a easy version of this directly into TYPO3.Fluid like this:
The ProcessViewHelper loops over every specified Processor and invokes a "process($query)" method.
The Process itself has access to the current "viewHelperVariableContainer" and can add content to a "Block" or add an callback for a "Wrapper".
Examples:
PaginationProcessor
The pagination processor updates the query to the current limit + page
renders a partial that contains the pagination itself
adds that rendered pagination to the block "bottom"
the "<c:block name="bottom" />" viewHelper takes that content and puts it into the specified place in the template
The sort processor updates the query to the current sortBy and order
adds a wrapper callback for the wrapper "field"
gets called by the "<c:wrap name="field" arguments="{field: field}">" to add the sort wrapper
publicfunctionprocess($query) {
$this->handleSorting($query;
$this->addWrapper('field', $this);
}
publicfunctionwrap($content, $arguments) {
... wrap the content with a some sort link and direction classes ...
return $content;
}
Bottom line
You're probably now thinking, wtf, we won't he shut up and use Widgets +/ TypoScript? Well, take a look at the code you need to write + maintain to have this working this way, vs Widgets +/ TypoScript. If you add PartialInheritance from "2_ControllerInheritanceFalbacks.md" into this mix you can easily override anything you want with very concise and clean code/templates. :)
I like it :-)