assign custom function call to variable - typo3

I am quite new to Typo3 and Fluid, but I guess what I am after is quite basic.
As an Analogy: Twig can extended, so it is possible to create a custom function which can be used like that:
{% set id = uid() %}
<input id="{{ id }}" … /><label for="{{ id }}">…</label>
Is such a thing possible with Fluid? Do I need to install other extensions, or can that be done with basic fluid extension?

In Fluid you have two ways to achieve this:
Prepare the desired data in the controller and assign it to the view as variable.
Create a custom viewhelper which contains the logic to build the desired data.
You can also combine these two and store the result of a viewhelper call in a variable using the f:variable viewhelper (more usage examples):
<f:variable name="myvariable">{acme:custom.viewhelper()}</f:variable>
In this specific case you can also install the VHS extension, the swiss army knife of Fluid, and use its UniqIdViewHelper Notice that you normally don't need this for forms since you bind them to (domain) objects you want to create/edit and let Extbase/Fluid handle the rest.

Related

AEM6.5 Passing paramater to the resource from HTL/Sightly template

I have a component that uses two different resources in its HTL/Sightly template.
Is there a way to pass a parameter, to the say in my example the eventResource template, so that I can depending on this passed paramter change a css class on it?
<ul data-sly-list.teasers="${model.resourceList}" class="teaser-list-alternating c-list--reset">
<sly data-sly-test="${teasers.eventTeaser}"
data-sly-resource="${teasers.resource # resourceType='xxx/components/content/eventTeaser'}"></sly>
<li data-sly-test="${teasers.contentTeaser}" class="l-stack l-stack--horse"
data-component-hook-content-hub="teaser"
data-sly-resource="${teasers.resource # resourceType='xxx/components/content/contentHubTeaser'}"></li>
</ul>
I tried using data-sly-resource="${teasers.resource # resourceType='xxx/components/content/eventTeaser', requestAttributes=model.config, selectors='blabla'} to no availability.
#RequestAttribute(name = "contentHub")
private String contentHub;
The requestAttribute contentHub in the eventTeaser model is alway null and I am not sure how to get the selectors value in the eventTeaser template.
I can do it using TypeScript on the front end part but it is not very clean.
I was able to solve it using the selectors indeed and reading the selector value directly from the other sightly template. Here is the documentation I refered to:
data-sly-resource="${teasers.resource # resourceType='xxx/components/content/eventTeaser', requestAttributes=model.config, selectors='inContentHub'}
 In the eventTeaser template I then used the following:
data-sly-set.inContentHub="${'inContentHub' == request.requestPathInfo.selectorString}
and depending on the value of the inContentHub variable I was able to change the css class which was my ultimate goal.

TYPO3 DCE to TYPO3FLUX

Hello guys im totally new to TYPO3 and I received a task to rewrite the DCE syntax to flux. Can anybody explain it to me how it works? do I need flux for each?
<f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference">
<vhs:resource.image identifier="{fileReference.uid}" treatIdAsReference="1" as="image1">
<vhs:variable.set name="imageSrc1" value="{image1.0.source}" />
</vhs:resource.image>
</f:for>
Actually DCE is an extension which allows you to create custom elements and you can create elements from Backend of TYPO3. Flux is a different method to create custom elements which creates elements using the viewhelpers in the template.
Here you can find the documentation of the flux https://fluidtypo3.org/documentation/templating-manual/introduction/
Both methods are different so you will need to re-create each and every element and also needs to do data entries if site is already filled with the data.

Add additional source to Image for further actions

im trying to add an additional source to the dce-image for further actions e.g. an alternate source to perform some JavaScript actions.
The wanted output should look like this:
<img src="path/to/foo.png" data-altsrc="path/to/bar.png">
The problem is the dce i'm using - its iterating through the "images" like this:
<f:for each="{dce:fal(field:'image', contentObject:contentObject)}" as="fileReference">
<f:image src="{fileReference.uid}" treatIdAsReference="1" />
</f:for>
So if I would insert multiple images to this I have no real relation between the images where i know which one is the normal-source and which one is the alternate source.
So there was the possibility to create a section and add two fields for images which we can restrict to one image per field. But there again is the for-loop which doesn't allow me to access the source of the second image for the first image.
It should be a visible relation between these images for the user which is working with the dce.
Im trying to achieve something like this:
<f:for each="{field.images}" as="images">
<!-- want to achieve something like this -->
<f:image image="{images.foo.src}" data-altsrc="{images.bar.src}">
<!-- thats the normal way iterating through images -->
<f:for each="{images.foo}" as="image">
<f:image image="{image}" />
</f:for>
</f:for>
Another idea would be to iterate first through the alternate images and store them into an array and on the main-images to access them but I have no idea if this is even possible also this will restrict the usability of the dce for the user.
Is there any way to achieve this with dce-fluid ?
Thanks in advance
Well, i guess you could extend the sys_file_reference table to add a relation from there. So you would have nested relations (never done that, so you would have to try).
You would also have to add the field to the tca type in the place you need it, that could be a little tricky. Have a look at Tca types overrides.
You could extend the sys_file_reference table with a field "alternative_reference" and add the neccessary TCA setup. Then you would have to retrieve the FileReferences via the FileRepository and use sys_file_reference as foreign table (and of course the sys_file_reference uid as identifier).
FileRepository::findByRelation(
'sys_file_reference',
'alternative_reference',
$uidOfActualSysFileReferenceRecord
);
The other possibility would be a completely new record with 2 different sys_file_reference relations. That record (eg: tx_ext_domain_model_imageset) would have an image_default and image_alternate field, both would be configured as file_relations. That would work for sure.
$defaultImages = FileRepository::findByRelation(
'tx_ext_domain_model_imageset',
'image_default',
$uidOfRecord
);
$alternativeImages = FileRepository::findByRelation(
'tx_ext_domain_model_imageset',
'image_alternative',
$uidOfRecord
);
I assume you do have knowledge about creating records, models, tca and so on.
I personally would prefer the second way, it is more clean and does not change the core-table structures.
Also there is a second image generation viewhelper, that might suite your needs better
<img src="{f:uri.image()}" data-altsrc="{f:uri.image()}" />
But the best way to go might be to write your own ViewHelper for that purpose. You could pass your Object (ImageSet) as parameter and handle all logic there. So your template would be simpler and easier to read/work on.
You have to use data attribute of fluid viewhelper and then get the uri of the image with inline call. Here is how to achieve :
<f:image src="{fileReference.uid}" data="{altsrc: '{f:uri.image(src: \'{fileReference.uid}\', treatIdAsReference: 1}" treatIdAsReference="1"/>
This should do the work.

How can I include content of a component in Fabricator Assemble *without* a corresponding attribute, or at block level?

In Fabricator Assemble, I could have a component button.html:
<a class="button">{{text}}</a>
I can use this with the syntax {{>button text='Home'}}. Notably, I have to specify a name for the "text" attribute.
I'm looking to see how I can handle not needing to do that in Assemble. The Literals section of the docs for Handlebars (whiich Fabricator Assemble is built on) highlights an alternative syntax with which I could include a button:
{{>button 'Home'}}
In this example, "Home" is a value without any name for it at all. Handlebars also indicates the following is possible as a basic block:
{{#button}}
<b>Some button content</b>
{{/button}}
Likewise, that content has no name.
I'd like to be able to do this same thing in Fabricator Assemble, but it doesn't seem to have a way for me to include this nameless content. In templates there's {% body %} but that doesn't work here.
In Handlebars, which Fabricator Assemble is based on, all examples for how to recreate this involve JavaScript, which doesn't translate well to Assemble.
What can I do to use {{>button 'Some text'}} or {{#button}}...{{/button}} syntax in Fabricator Assemble? Is this behaviour even available?
In the current version, the easiest way to achieve this is with a custom helper.
Add the following to the helpers option in your gulpfile.js:
default: (value, defaultValue) => {
return value || defaultValue;
},
Then inside a handlebars template:
<div>
{{default varName 'default value'}}
</div>

TYPO3: category tree of tx-news, render sub-tree only if main is selected

I override Templates/Styles/TWB/Templates/Category/List.html to have the category menu behave exactly as the sidebar menu in the introduction package (submenus show only if main is selected).
If I add the static template "News Styles Twitter Bootstrap (news)" I'm almost there, it is not difficult to open the sub-categories only if the main category is selected (I need a massive amount of categories/sub-categories), but it should also be open when a sub is selected:
...
<f:if condition="{0:category.item.uid,1:category.item.uid} == {0:overwriteDemand.categories,1:category.children.{overwriteDemand.categories}.parent}">
<f:if condition="{category.children}">
<f:render section="categoryTree" arguments="{categories: category.children,overwriteDemand:overwriteDemand,class:''}" />
</f:if>
</f:if>
...
I do not know how to use {overwriteDemand.categories} as key to match the value ... can anybody point to the proper syntax
update: I tried to apply a custom ViewHelper as this post suggests, but using TYPO3 V7.6.16 got stuck with the error should be compatible with TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper:‌​:render(), so could not try working with the variable overwriteDemand.categories in another way ...
Dynamic access to variables in fluid is just possible since TYPO3 8. Check out the Whats New Slides here: https://typo3.org/download/release-notes/whats-new/ and search for "Dynamic variable name parts" in the PDF.
In TYPO3 7, the "vhs"-Extension provides a ViewHelper to do the same job but nesting a ViewHelper within an complex f:if-condition is even more difficult. If possible, try out TYPO3 8. If it's not possible you may write your own ViewHelper to solve this logical problem.