Fluid-Alias-View-Helper with result of another view helper - typo3

In one of my NEOS Templates I try to solve the simple task of generating a random number (within a specified range) and store it into a variable for later usage.
Since none of the default view helpers offers such a feature I developed my own view helper, which expects a min and max value. Internally the view helper uses php's rand($min, $max).
The following example is working in my template:
site:RandomNumber(0, 17)
As expected this outputs a random number. However now I need to store the result into a variable, since I have to use it more than one time.
I came across fluids alias-view-helper:
<f:alias map="{number: 33}">
The number is {number}
</f:alias>
This results in:
The number is 33
Now I want the number not to be 33, but the result of my RandomNumber-view-helper.
I tried things like:
<f:alias map="{number: {site:RandomNumber(0, 17)}}">
The number is {number}
</f:alias>
This however throws an Exception saying:
The argument "map" was registered with type "array", but is of type "string"
in view helper "TYPO3\Fluid\ViewHelpers\AliasViewHelper"
The docs of the f:aliasview-helper say accepted values are other view-helpers, but they never give any examples on that.
Am I completely wrong with this approach? Is it simply not possible to assign a simple variable within a fluid-template?
Further information:
I do have a slider on the website, which should start with a different slide on (almost) every page-load. So I need to grab this random slide-number, which I have to refer to in the slider markup several times.

I digged into it again and first tried to output:
{site:randomNumber(0,17)} <- was output as the string, not the expected result
<site:randomNumber min="0" max="17" /> <- this was the expected output
The first one, is the one I needed to get to work to use it in the alias-helper right?
So I first had to ensure, that this first one works!
I randomly guessed that it's necessary to specify the argument-names. So I tried this:
{site:randomNumber({min: 0, max: 17})}
Coming from PHP I thought, that giving an array with the arguments was the solution. However I was wrong.
Googling for "fluid inline notation" lead me to this resource: https://wiki.typo3.org/Fluid_Inline_Notation
There I saw, that I was very close. The arguments have to be given by their names, but not in array-notation, so THIS produced the expected output:
{site:randomNumber(min: 0, max: 17)}
So I got one step further to the solution. So I took this snippet and pasted it into the alias-helper like this:
<f:alias map="{number: {site:randomNumber(min: 0, max: 17)}}">
The number is {number}
</f:alias>
This however lead to the same exception as before. I felt I was close, so guessed in wrapping the expression into single-quotes, like:
<f:alias map="{number: '{site:randomNumber(min: 0, max: 17)}'}">
The number is {number}
</f:alias>
That's everything I wanted. Hard to believe that one needs 2 days to figure this out, since documentation is really bad.

It should be {site:randomNumber(min: 1, max:10)}. Notice the casing. This is assuming, you have registered the namespace site like this at the beginning of your template:
{namespace site=Vendor\ExtName\ViewHelpers}
EDIT: The arguments must match the parameter names of the ViewHelper render function.

Related

How to encode normalized(A,B) properly?

I am using clingo to solve a homework problem and stumbled upon something I can't explain:
normalized(0,0).
normalized(A,1) :-
A != 0.
normalized(10).
In my opinion, normalized should be 0 when the first parameter is 0 or 1 in every other case.
Running clingo on that, however, produces the following:
test.pl:2:1-3:12: error: unsafe variables in:
normalized(A,1):-[#inc_base];A!=0.
test.pl:2:12-13: note: 'A' is unsafe
Why is A unsafe here?
According to Programming with CLINGO
Some error messages say that the program
has “unsafe variables.” Such a message usually indicates that the head of one of
the rules includes a variable that does not occur in its body; stable models of such
programs may be infinite.
But in this example A is present in the body.
Will clingo produce an infinite set consisting of answers for all numbers here?
I tried adding number(_) around the first parameter and pattern matching on it to avoid this situation but with the same result:
normalized(number(0),0).
normalized(A,1) :-
A=number(B),
B != 0.
normalized(number(10)).
How would I write normalized properly?
With "variables occuring in the body" actually means in a positive literal in the body. I can recommend the official guide: https://github.com/potassco/guide/releases/
The second thing, ASP is not prolog. Your rules get grounded, i.e. each first order variable is replaced with its domain. In your case A has no domain.
What would be the expected outcome of your program ?
normalized(12351,1).
normalized(my_mom,1).
would all be valid replacements for A so you create an infinite program. This is why 'A' has to be bounded by a domain. For example:
dom(a). dom(b). dom(c). dom(100).
normalized(0,0).
normalized(A,1) :- dom(A).
would produce
normalize(0,0).
normalize(a,1).
normalize(b,1).
normalize(c,1).
normalize(100,1).
Also note that there is no such thing as number/1. ASP is a typefree language.
Also,
normalized(10).
is a different predicate with only one parameter, I do not know how this will fit in your program.
Maybe your are looking for something like this:
dom(1..100).
normalize(0,0).
normalize(X,1) :- dom(X).
foo(43).
bar(Y) :- normalize(X,Y), foo(X).

What is causing the error between these two .bindPopup?

The below popup works properly displaying "Neigh_Name" (a name such as "Main") and "2020 Total Population" (a string comprised of numbers '234273' etc).
layer.bindPopup(feature.properties.Neigh_Name+"<br>"+feature.properties["2020 Total Population"])
However, when using the below..
layer.bindPopup(feature.properties["2020 Total Population"])
I get the error: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
Can someone explain what is happening in the backend and why these two lines of code differ and the latter ultimately fails? I'm trying to learn why certain things occur to avoid future issues.
Thanks!
Very probably the bindPopup method behaves unexpectedly when passing a number as content (your 2nd line), whereas it happily accepts a string argument (as in your 1st line).
Simply make sure to convert your argument into string, e.g. with "" + feature.properties["2020 Total Population"] or
`${feature.properties["2020 Total Population"]}`

set threshold as a function of autoThreshold

I have written a macro for ImageJ/FIJI to deconvolve my confocal microscopy images and run the "3D Object Counter" plugin. The macro successfully runs all required commands and saves all required data in the specified places.
However, I have found that the 3D-OC autothreshold (as shown in the plugin dialog box) is to stringent resulting in objects being lost or divided.
To remedy this I would like to reduce the autothreshold by a predetermined function something similar to what was done here (from:How to get threshold value used by auto threshold Plugin) which resulted in this code:
setAutoThreshold();
getThreshold(lower,upper);
v=setThreshold(lower,upper*0.5);
run("3D Objects Counter", "threshold="v" slice=10 min.=400 max.=20971520 objects statistics summary");
The idea was to call the AutoThreshold values, modify them and set them to a variable. However when these lines are run the following error is returned:
Number or numeric function expected in line 3.
v=<setThreshold>(lower,upper*0.5);
And if the variable is inserted directly into the threshold key for run(3D-OC) the following msg is encountered:
Numeric value expected in run() function
Key:"threshold"
Value or variable name:"setThreshold(lower,upper*0.5"
Any suggestions or help on how to designate the 3D-OC threshold value as a variable as described would be greatly appreciated (as would any work arounds of course :) ).
Cheers
Edit: After testing Jan's response below (which works perfectly), it appears I need to call the threshold set by the 3D-OC plugin. Anyone know how to do this?
The getThreshold(lower, upper) function returns the lower and upper threshold levels in the provided variables. There is no need to assign any value to a new variable, and as you observed, setThreshold does not have any return value.
Instead, you can use the value(s) returned from getThreshold and use them as parameters in the run method (in the correct way, by string concatenation, see here):
setAutoThreshold();
getThreshold(lower, v);
run("3D Objects Counter", "threshold=" + v + " slice=10 min.=400 max.=20971520 objects statistics summary");
Alternatively, you can use &v in the second parameter to avoid string concatenation in the last line (see the documentation for the run() macro function):
run("3D Objects Counter", "threshold=&v slice=10 min.=400 max.=20971520 objects statistics summary");
You might have to use the lower instead of the upper threshold value, depending on whether you count bright or dark objects.

JQuery UI Autocomplete returning all values

I have the following code:
$("#auto").autocomplete({
source: "js/search.php",
minLength: "3" });
This code is assign to an input text box where i type a name and after 3 letters it should return the ones that have similar letters. For my case it is returning all values, even those not related to the 3 letters already typed. My question is:
How to send my search.php file the value inside the input so it should know what to search for. For the moment it searches for everything. I checked the value that was going to php and it was empty. Since the query to mysql uses LIKE '%VARIABLE%' and the variable is empty it searches for '%%' which is all cases.
How can i send the correct informacion from JS to PHP with the simplest form.
Here is the explanation :
http://www.simonbattersby.com/blog/jquery-ui-autocomplete-with-a-remote-database-and-php/
Regards

Asp.Net MVC 2: How exactly does a view model bind back to the model upon post back?

Sorry for the length, but a picture is worth 1000 words:
In ASP.NET MVC 2, the input form field "name" attribute must contain exactly the syntax below that you would use to reference the object in C# in order to bind it back to the object upon post back. That said, if you have an object like the following where it contains multiple Orders having multiple OrderLines, the names would look and work well like this (case sensitive):
This works:
Order[0].id
Order[0].orderDate
Order[0].Customer.name
Order[0].Customer.Address
Order[0].OrderLine[0].itemID // first order line
Order[0].OrderLine[0].description
Order[0].OrderLine[0].qty
Order[0].OrderLine[0].price
Order[0].OrderLine[1].itemID // second order line, same names
Order[0].OrderLine[1].description
Order[0].OrderLine[1].qty
Order[0].OrderLine[1].price
However we want to add order lines and remove order lines at the client browser. Apparently, the indexes must start at zero and contain every consecutive index number to N.
The black belt ninja Phil Haack's blog entry here explains how to remove the [0] index, have duplicate names, and let MVC auto-enumerate duplicate names with the [0] notation. However, I have failed to get this to bind back using a nested object:
This fails:
Order.id // Duplicate names should enumerate at 0 .. N
Order.orderDate
Order.Customer.name
Order.Customer.Address
Order.OrderLine.itemID // And likewise for nested properties?
Order.OrderLine.description
Order.OrderLine.qty
Order.OrderLine.price
Order.OrderLine.itemID
Order.OrderLine.description
Order.OrderLine.qty
Order.OrderLine.price
I haven't found any advice out there yet that describes how this works for binding back nested ViewModels on post. Any links to existing code examples or strict examples on the exact names necessary to do nested binding with ILists?
Steve Sanderson has code that does this sort of thing here, but we cannot seem to get this to bind back to nested objects. Anything not having the [0]..[n] AND being consecutive in numbering simply drops off of the return object.
Any ideas?
We found a work around, by using the following:
Html.EditorFor(m => m, "ViewNameToUse", "FieldPrefix")
Where FieldPrefix is the "object[0]". This is hardly ideal, but it certainly works pretty well. It's simple and elegant.