LESS: variable that refers to another one's value with concatenate name - less

The following (vey simplified) LESS code runs correctly, printing value of width property, previosly assigned to #screen-md variable.
#screen-md:700px;
#size:md;
#temp:"screen-#{size}";
#width:##temp;
.foo
{
width:#width;
}
Imagine that #size value could be a parameter passed to a mixin. In general, to obtain desired result, I need to pass through #temp variable, first assigning her a variable name based upon #size value, and then using Variable name to finally assign it to #width variable.
My question is: is it possible to avoid need of #temp variable, collapsing
#temp:"screen-#{size}";
#width:##temp;
into something like #width:##"screen-#{size}" ?

Yes, it is possible to collapse it into one single line like shown below:
#screen-md:700px;
#size:md;
.mixin(#size){
width: ~"#{screen-#{size}}"; /* can either be assigned to another variable or property */
}
.output{
.mixin(md);
}
Explanation:
screen-#{size} - would evaluate to screen-md as the input parameter to the mixin is md.
#{screen-#{size} - would therefore mean #{screen-md}. This would be evaluated as 700px.
~"" - escaping is used to avoid the quotes being in printed in the output.

Related

Why a garbage value is stored after declaring a variable? Why not store a specific number by default like 0 (zero)?

If I declare a variable a random(garbage) value is stored inside the variable.
Many times it can be pretty annoying. Why not just fix a value like 0 or like 1.
What is the problem in giving a specific value to a variable before initialization?

How to loop through all params in Less mixin

I'm writing a Less mixin.
I want to be able to pass the mixin several parameters. The first will be a string. The rest, an infinite number of parameters, will be value pairs.
In my mixin how can I loop through the infinite number of parameters?
For example one time I will call...
.my-mixin(#name, #foo: bar, #hello: world);
and another time...
.my-mixin(#name, #iam: cool, #youare: lame, #someoneis: awesome);
Here's what it would look like if Less supported JS/PHP...
.my-mixin() {
#name: #arguments[0]; //First param
for (#arguments as #label => #value) {
#label: #value;
}
}
Is this possible?
In fact you ask two questions. First how to create a mixin that can accept an endless number of parameters, and secondly who to iterate over the list / array of parameters.
Less has the special ... syntax to create mixins with an endless number of parameters. The official documentation can be found here: Advanced arguments and the #rest variable. An example / use case can be found at Can I define a LESS mixin to generate a transition-property with a variable number of parameters?.
The special ... syntax can be used to assign the parameter list to a variable by adding the variable name before the ...:
.mixin(#parameter1, #endlesslistofparameters...) {}
The #endlesslistofparameters variable now contains a list of parameters, you can use the Less list functions to extract a value from this list (or find its length):
length() returns the length of a list and extract(#list,position) return the value of a certain position in the list. Notice that the first value is on position 1 and not 0.
Finally you can use a loop to iterate over this list of arguments.
In Less a mixin can call itself. Such recursive mixins, when combined
with Guard Expressions and Pattern Matching, can be used to create
various iterative/loop structures.
See also: Loop over an array of name value pairs in LESS
All together i think you can write something like that shown below:
.my-mixin(#name,#properties...) {
.setproperties(#iterator:1) when (#iterator <= length(#properties)) {
#propertyname: extract(extract(#properties,#iterator),1);
#{propertyname}: extract(extract(#properties,#iterator),2);
.setproperties((#iterator + 1));
}
.#{name} {
.setproperties();
}
}
.my-mixin(jared; iam cool, youare lame, someoneis awesome);
The preceding Less code will compile into the following CSS code:
.jared {
iam: cool;
youare: lame;
someoneis: awesome;
}
And than also notice that Less allows you to Passing Rulesets to Mixins since version 1.7, which enables you to write:
.my-mixin2(#name,#properties) {
.#{name} {
#properties();
}
}
.my-mixin2(jared; {iam: cool; youare: lame; someoneis: awesome;});

Use single value of parameter List in queryString

I am using JasperStudio 5.6.0.final and the report is not generated dynamically from java code.
I have a problem with getting single value from parameter.
In the report I have a parameter A of a type List.
It is not a problem to use it in a clause as IN statement:
AND $X{IN, USER.ID_USER, A}
But I have a problem to get a single value from that list.
I know that my List has always 10 values.
So I want to use it in query, but I don't know how to write the statement:
AND USER.ID_USER = *first_value_of_list_A*
e.g.
AND USER.ID_USER = $P!{Atrybuty}.get(1)
doesn't work
I tried also to assign parameter value to a variable, but as I know it isn't possible to use variables in queryString.
So my question: How to get single value from parameter List in queryString.
What you need to do for this is use
AND $X{IN, USER.ID_USER, A}
Set A type as Collection and that will allow you to even have a single selection or multi selection or just a single value.
Hope that this helps.

in Golang, can we declare some string value to variable name?

I have slices with some variable names
like
strList := ['abcd', 'efgh', 'ijkl']
and I want to make it to variables names(to make some object iterably)
What I curious is that how can I make strings value to variable name. (in code)
like strList[0] seems not allowed....
Thanks for your help!
Since your strings will be read at runtime and your variable names will be checked at compile time, it's probably not possible to actually create a variable with a name based on a string.
However, you can make a map that stores values with string keys. For example, if you wanted to hold integer values inside something you can look up using the values "abcd", "efgh", etc., you would declare:
myMap := map[string]int {
"abcd": 1,
"efgh": 2,
"ijkl": 3,
}
and you could then read those values with e.g. myMap["abcd"] // 1.
I think you want something like http://play.golang.org/p/M_wHwemWL6 ?
Note that the syntax for a slice literal uses {}'s not []'s.

Velocity Template engine - key-value-map

I have some problems wo use a key-value-map into Velocity.
Someone has an example of this functionality?
$myMap ={}
$myMap.put("mykey1", "myvalue")
$myMap.delete("mykey1")
$myMap.getValue("mykey1")
As Nathan said, you should use:
#set ($myMap = {})
to create a new map and assign it to a variable.
Now, why is the put call printed.
Anything that is not inside a directive, like #set(not printed) or #if(not printed) or #foreach(again not printed), is printed, including free text, variables, and method calls.
Velocity can't distinguish between the different semantics of $myMap.get('mykey') and $myMap.put('key', 'value') (reader vs. writer), so the result of the put call is printed, just like any other method.
Whenever something can't be properly evaluated, because a variable is not defined or somewhere along the line a method returns null, the code that failed to be evaluated is dumped literally into the output.
As the documentation of the put method states, the function returns the previous value stored for that key, or null if no value was set at all.
Summing it all up, it's normal to get that line printed.
To try this theory out, you can do this:
#set ($myMap = {})
$myMap.put('key', 'first value')
$myMap.put('key', 'second value')
$myMap.get('key')
This will be printed:
$myMap.put('key', 'first value')
first value
second value
There are two things you can do so that the line isn't printed:
Store the outcome of the function in a temporary variable: #set ($discard = $myMap.put('key', 'value')
Use the silent method call: $!myMap.put('key', 'value')
I'd recommend the first one, since the second one will still print something when you're replacing an existing value.
Did you try doing:
#set( $myMap = {} )
Also, make sure you are using a modern version of Velocity. Ancient ones did not have map syntax in VTL.
Just add ! to not print put:
$!myMap.put('key', 'second value')