A range with steps bigger than one in freemarker? - range

Question
I want to know if you can specify a step size in a numeric range.
For example, exist something like 50..100 in 10 that resolve to [50, 60, 70, 80, 90, 100]?
or if not exist can I make something like 5..10 * 10 and the same result?
Explanation
Here an explanation about my problem (if you like to know more). I have a configuration file with two blocks, the second related with the first.
Something like:
This will configure the application to do first A with parameter 100 and then do B with parameter 200. A will be a easy algorithm than B but less powerfull, but B will also try what A do if it's parameter is lower.
Now I want to launch a test with multiple values to know what is the better combination so I made the next template with freemarker.
<#list [50, 100, 200] as A>
<#list [100, 200, 500] as B>
<doA param1="${A}" />
<doB param1="${B}" />
</#list>
</#list>
The problem will be the combination of A=200 and B=100, because I already know that B will test A=200 so it is a waste of time to test.
I can solve this with an if, so if A is bigger than B, don't do nothing.
Now the problem have became bigger, and I need to check more values so I want to switch to a range of values, something like:
<#list 50..300 as A>
<#list 100..10000 as B>
<#if A < B >
<doA param1="${A}" />
<doB param1="${B}" />
</#if>
</#list>
</#list>
But an step of 1 is too small.
Also I think that with this I can do:
<#list 50..300 as A>
<#list A..10000 as B>
<doA param1="${A}" />
<doB param1="${B}" />
</#list>
</#list>
But I haven't test it. First I need to know that if I can make a big step.
P.D. I have search in freemarker documentation but I don't found nothing about this.

No, you can't specify a step. You can't multiply a whole range at once either. But of course you can do something like ${A*10} that is similar to having step 10.

Related

Source a value from custom record field to a field in employee record

I need to source a value from a custom record field (type: decimal) to a field in employee record(type: decimal). when the custom record is created. Is there any way I can implement this in workflow or should I go for the script?
If I choose the script which script I need to write?
Actually, I am new to script.so can anyone show me some sample?
Sounds very much like business logic, and thus shouldn't be done in a template... but, maybe you have no choice, so you can write a function like this:
<#--
Returns if two sequences (Java List-s or Java arrays usually) are equal.
Items at the same index must have common comparable type, and no item
can be null, or else you may get an error!
-->
<#function sequencesEqual s1, s2>
<#if s1?size != s2?size>
<#return false>
</#if>
<#list s1 as i1>
<#if i1 != s2[i1?index]>
<#return false>
</#if>
</#list>
<#return true>
</#function>
Then you can do things like <#if sequencesEqual(foo, bar)>...</#if>.

TYPO3 Flux - getting content of grid returns nothing

I have a flux-grid that looks like this:
<flux:grid>
<flux:grid.row>
<flux:grid.column name="content" label="Content"/>
</flux:grid.row>
</flux:grid>
It's a wrapper for other content-elements (namely elements of a slider).
Now I need to wrap each of the elements in a <li>-Tag.
So I thought I get the content as an array and render it in an each-loop.
<flux:content.render area="content" as="slides" render="1" />
I thought I'd have the elements in a variable called slides now. But that doesn't seem to be the case. When I use <f:debug>{slides}</f:debug> I get just an empty variable...
Thus, this fails:
<f:for each="{slides}" as="slide">
<f:debug>{slide}</f:debug>
</f:for>
Just outputting the content like this works, though:
<flux:content.render area="content"/>
What am I doing wrong?
[Edit]
I'm one step further...
<v:variable.set name="contentElements" value="{flux:content.get(area:'content', render:'FALSE')}" />
Does indeed return an array with the elements.
But when I try to render the elements, they're empty:
<f:for each="{contentElements}" as="contentElement">
UID: {contentElement.uid}<br />
<v:content.render contentUids="{0:contentElement.uid}" />
</f:for>
the UID is correctly outputted - the v:content.render fails
Seems like I was just using an old Vhs-Version.
Saw in the Extensions that it had an update (to 4.3.3) and now it's working...

How to define array of numbers and output it?

How can I define an array of numbers and output each number in a for loop?
I tried it like this:
<f:alias map="{numbers: [1,2,3,4,5,6]}">
<f:for each="{numbers}" as="number">
<p>{number}</p>
</f:for>
</f:alias>
Result:
The argument "map" was registered with type "array", but is of type "string" in view helper "TYPO3\CMS\Fluid\ViewHelpers\AliasViewHelper"
And like this:
<f:alias map="{v:iterator.explode(content: '1,2,3,4,5,6')}">
<f:for each="{content}" as="zahl">
<p>{zahl}</p>
</f:for>
</f:alias>
Result: No output.
<f:for each="{0:1, 1:2, 2:3, 3:4, 4:5, 5:6, 6:7}" as="foo">{foo}</f:for>
The ideal solution IF and only IF:
You use VHS.
You want numbers starting from 0 or 1 going to a max; or numbers calculated using those two starting indices (TYPO3 8.0+ supports math expressions in Fluid natively, earlier versions require VHS for this).
You want to loop the numbers, not consume them as an array.
Which seems to be exactly your use case...
Then, and only then, is the following the ideal solution in terms of both performance and minimising complexity:
<v:iterator.loop count="6" iteration="iteration">
{iteration.index} starts at zero, {iteration.cycle} starts at one.
</v:iterator.loop>
Don't forget the following either:
{f:render(section: 'OtherSection', arguments: {iteration: iteration})
-> v:iterator.loop(count: 6, iteration: 'iteration')}
Which is the most efficient way of rendering a section X number of times
with only the iteration variable being different. Sections or partials are the most efficient way to represent this exact type of code and the
inline syntax is the most efficient when parsing.
try this:
<f:alias map="{numbers: {1,2,3,4,5,6}}">
<f:for each="{numbers}" as="number">
<p>{number}</p>
</f:for>
</f:alias>
I was able to solve it with this code:
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
v:schemaLocation="https://fluidtypo3.org/schemas/vhs-master.xsd">
<f:for each="{v:iterator.explode(content: '1,2,3,4,5,6')}" as="number">
<p>{number}</p>
</f:for>
Output:
1
2
3
4
5
6
Make sure that you have installed the extension VHS: Fluid ViewHelpers (extension key = vhs).
Make sure to include the extension in the partial.
Write this at the top:
<html xmlns="http://www.w3.org/1999/xhtml" lang="en"
xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"
v:schemaLocation="https://fluidtypo3.org/schemas/vhs-master.xsd">
I am using Typo3 v6.2.25

one pattern multiple responses in aiml

I want to make a chatbot,so my doubt is how can i respond in multiple ways for a single pattern in aiml ?
for example if the user asks whats next the chat bot should respond step1
if again he asks whats next it should respond step2.
You can use "that" tags in the template, which remember the last bot statement and answer accordingly, although this gives you just one level of control. If you want more levels, a better way is to set topics using the "think" tags, and then defining topic specific templates which will be used first.
To have multiple responses for a single <pattern>, you can use the <random> and <li> tags:
<category>
<pattern>WHATS NEXT</pattern>
<template><random>
<li>Step 1</li>
<li>Step 2</li>
</random></template>
</category>
However, the responses will be generated randomly and not in a certain order.
For instance, if the user inputs "What's next?" for the first time, the response might be "Step 1" and the next time the user inputs the same keyword, the response might still be "Step 1".
First you need a category that knows the steps, and returns the answer in a defined format. In my example the format is
MAKE TOAST STEP * *
where the first star is the step number and the second star represents the remainder of the returned text. Here is the category:
<category>
<pattern>MAKING TOAST STEP *</pattern>
<template>
<set var="step"><star/></set>
<condition var="step">
<li value="1">Make toast step 1, get some bread</li>
<li value="2">Make toast step 2, put the bread in the toaster</li>
<li value="3">Make toast step 3, wait until it pops up</li>
<li>Make toast step 4, eat the toast</li>
</condition>
</template>
</category>
Then you need a category that calls the next step but only if the previous answer was a toast-making question. This category uses the that tag to ensure it is activated only during the toast making conversation. It uses thatstar to get the previous step number, then adds one to the step number:
<category>
<pattern>WHAT IS NEXT</pattern>
<that>MAKE TOAST STEP * *</that>
<template>
<set var="step"><calculate><thatstar/>+1</calculate></set>
<srai>MAKING TOAST STEP <get var="step"/></srai>
</template>
</category>
Then you need a category to kick off the whole sequence:
<category>
<pattern>HOW DO I MAKE TOAST</pattern>
<template>
<srai>MAKING TOAST STEP 1</srai>
</template>
</category>
The caveats with this approach are (1) it uses the calculate tag which is not standard AIML but should be coded quite easily. (2) It uses AIML v2 elements such as variables used with get and set. (3) I have not tested it, but I am confident the process should work.
<category>
<pattern>TEST SPLIT</pattern>
<template>
I don't want to talk about that now.
<split/>
I would rather talk about you.
</template>
</category>
Do <split/>
Output
Reference

Extbase add calculated field in query/repository

I have a normal extbase extension.
In the controller I get all my records:
$stuff = $this->jobRepository->findAll();
$this->view->assign('stuff', $stuff);
and in the template I display them:
<f:for each="{stuffs}" as="stuff">
{stuff.title} <br />
{stuff.category}
</f:for>
Now I need a new field stuff.isnew with the value 1 if the record is the newest by category.
An SQL-Statement for that would look like:
SELECT j2.isnew, j.* FROM `tx_stuff_domain_model_stuff` as j
left join
(SELECT max(crdate) as crdate, category, 1 as isnew FROM `tx_stuff_domain_model_stuff` group by category) as j2
on j.crdate=j2.crdate and j.category=j2.category
(If I have to write my own Query I will have to check deleted, hidden, starttime, endtime to check if the record is active right now)
My question now is, what is the cleanest/best way to add that to my extension?
My solution would be to implement the method findAll in the job repository. It would first use the method findAll from the parent class to get all jobs. The usual constraints will already be applied. Then it would walk the resulting jobs and mark the newest one.
It should also be possible to create a custom query to reach you goal, but that would probably be a bite more work.
Actually you don't need to use additional query at all... while it's always first record which is new, you can just use an iterator of for ViewHelper:
<f:for each="{stuffs}" as="stuff" iteration="iterator">
<f:if condition="{iterator.isFirst}">THIS ONE IS BRAND NEW STUFF! </f:if>
{stuff.title} <br />
{stuff.category}
</f:for>