get item index in Foreach - macros

I have MyCustomMacro that returns me list of strings.
I need to show this list with custom separator beetwen list elements.
{%
foreach (ev in MyCustomMacro("events") )
{
ev + " | ";
};
#%}
but this code also addes " | " after last element.
How can i check that element is last in the list?

if you can get the values in a string array, you can do:
string.Join("|", events[])
Examples

I think a much efficient way is to use string StringBuilder class.
Something on these lines.
{%
var builder = new StringBuilder();
foreach (ev in MyCustomMacro("events") )
{
builder.append(ev + " | ");
};
result = String.Join("|", builder.Split('|'));
%}

You can do it easly by this:
{% result="";
foreach (ev in MyCustomMacro("events") )
{
result+= ev + " | ";
};
result.TrimEnd(" | ")
%}

You can use join method of string class:
{% string.join("|", MyCustomMacro("events")) %}

Related

Convert List to json object in Talend

I'm trying to convert list result from tJava Component to json object.
Result from tjava component is below.
[{run_id=5d0753d58d93b71a1d12cc22_, parent_run_id=null, pipe_invoker=scheduled, path_id=shared, count=33, plex_path=null, invoker=abc.com, nested_pipeline=true, duration=355, start_time=2020-11-20T11:17:32.298000+00:00, lable=MP_SQS, state=Completed, key=57694b41ee, root_ruuid=2_ba32ea346}, {run_id=5bd4c6ea346, parent_run_id=null, pipe_invoker=scheduled, path_id=shared, count=33, plex_path=null, invoker=wwr.com, nested_pipeline=true, duration=355, start_time=2020-11-20T11:17:32.298000+00:00, lable=Summary_MP_SQS, state=Completed, key=55dfff4f, root_ruuid=1246d2-8bdc-1846}]
i tried using tConvertType, or in tMapper converting into String then replace all function multiple time and then storing result into json file but noting is working as expected.
End Expected result is json file from above result.
I don't think there is an easy way with a Talend component to do that (but I may be wrong :-) ) :
Put quotes on the keys/value
Replace "=" by ":"
But it can be done with regular Java code, here an example :
String input =
"[{run_id=1111, parent_run_id=null1, pipe_invoker=scheduled1, path_id=shared, count=33, plex_path=null}," +
" {run_id=2222, parent_run_id=null2, pipe_invoker=scheduled2, path_id=shared, count=33, plex_path=null}]";
StringBuilder output = new StringBuilder();
input = input.substring(2,input.length() - 2); // remove "[{" .... "}]"
output.append("[{");
String step1 [] = input.split("\\}, \\{"); // each record, split on "}, {"
int j = 1;
for (String record : step1) {
String step2 [] = record.split(","); // each key/value, split on ","
int i = 1;
for (String keyValue : step2) {
// key=value --> "key":"value"
output.append("\"" + keyValue.split("=")[0].trim() + "\":\"" + keyValue.split("=")[1].trim() + "\"");
if (i++ < step2.length ) {
output.append(",");
}
}
if (j++ < step1.length ) {
output.append("} , {");
}
}
output.append("}]");
/*
output :
[{"run_id":"1111","parent_run_id":"null1","pipe_invoker":"scheduled1","path_id":"shared","count":"33","plex_path":"null"} , {"run_id":"2222","parent_run_id":"null2","pipe_invoker":"scheduled2","path_id":"shared","count":"33","plex_path":"null"}]
*/

string from list items after sortableJS has been applied

I am tring to get a string from a list after it has been sorted using jquery ui sortable
Using a simple list ( without sorting)
<ul id = "description">
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
and applying
$('#description').text().replace(/(\r\n|\n|\r)/gm," ");
I get: one two three
However if I make the list sortable and move items around, and using
function getOrder() {
alert($("#description").html());//gives a correct html ul
alert($("#description").text());// no spaces between words
var ans = $('#description').text().replace(/(\r\n|\n|\r)/gm," ");
alert("You got " + ans)
};
The output changes to three twoone or threetwoone - spacing messed up. $("description").html()
shows that the html is correct ( style="" gets added to the li tag for some reason) , but $('#description').text().replace(/(\r\n|\n|\r)/gm," "); does not give a properly spaced string.
Why does sorting change the behaviour and what can I do to resolve this? Appreciate any response please
To get the text, I would create a toString function:
function toString(element) {
var children = element.children;
var str = '';
for (var i = 0; i < children.length; i++) {
str += (!i ? '' : ' ') + children[i].textContent;
}
return str;
}
And then call that function with the HTMLElement (not jQuery object) of the list passed in as an argument.
This solution does not utilize jQuery, so you can use it with SortableJS or jQuery Sortable.
$.map( $('li'), function (element) { return $(element).text() }).join(' ');
works to get the list items into a properly spaced string

Scala/Twirl variables and scope/defining

I'm a front ender by trade but I've been asked to hop on to a Scala project which leverages the Play framework so includes Twirl. I'm trying to create a template which displays slightly different outputs depending on the string which is passed in.
Here is my code:
#(status: String)(implicit messages: Messages)
#{
if(status == "00") {
val pageTitle = "Page title"
val appStatus = "className"
val title = "message"
val subTitle = "message"
val step1Status = "className"
val step2Status = "className"
val step3Status = "className"
val image1 = "/customs/assets/images/image.png"
val image2 = "/customs/assets/images/image.png"
val image3 = "/customs/assets/images/image.png"
val optionalHeading = ""
val optionalParagraph = ""
val listContents = "<li>#Messages('message')</li><li>#Messages('message')</li>"
val optionalLink = "<br /><a class='button' href='#routes.DashboardController.display(custom)' role='button'>#Messages('message')</a>"
}
if(status == "01") {
//Other variables
}
if(status == "04") {
//Etc...
}
}
#layout(${pageTitle}) {
<div class="content__body">
<div class="hero">
<div class="${appStatus}">
<h1 class="bold-large">#Messages(${title})</h1>
<p>
${afterSubTitle}
</p>
<ol class="appstatus-steps">
<li><span class="${step1Status}"><img alt="Complete" title="Complete" src=" + ${image1} + ">#Messages("messages.Received")</span></li>
<li><span class="${step2Status}"><img alt="Complete" title="Complete" src=" + ${image2} + ">#Messages("messages.Processing")</span></li>
<li><span class="${step3Status}"><img alt="Complete" title="Complete" src=" + ${image3} + ">#Messages("messages.Decision")</span></li>
</ol>
</div>
</div>
${optionalHeading}
${optionalParagraph}
<h2>#Messages("messages.next")</h2>
<ul class="list list-bullet">
${listContents}
</ul>
${optionalLink}
</div>
}
So, as you can see, the idea is that this page is called with a code (status) and based on that string, a number of variables are defined which alter the way the page is formed; content/css classes/images etc.
This doesn't work (you may be surprised to learn!)
It's really unclear to me WHY it doesn't though. I thought that you accessed variables using a ${Variable} format, but it's possible that you're supposed to use the #Variable format instead.
Even when I try to change them to the #Variable way, I'm still getting problems and I loosely understand that this is to do with scope in Scala/Twirl and there's a "defining" keyword which can be used. I've read some documentation but I'm not getting it.
Could anyone shed some light on this?
EDIT
Okay, let's just consider the below code instead:
#(status: String)(implicit messages: Messages)
#{
if(status == "00") {
val myClass = "custom-class-1"
}
if (status == "01") {
val myClass = "custom-class-2"
}
#layout("page title") {
<div class="#myClass">This is a div</div>
}
So 'all I want to do' :) is be able to define a variety of variables based on the status and then use those variables in the template of the page.
Does that make sense? I'm so new to Scala so Tuples/Defining is lost on me at the moment, but I am learning!
You seem to be more used to javascript variables and scopes :)
In Scala and Twirl, if you only define a variable (in this case it's a value because it's immutable) inside an if statement, the value is only accessible inside the if block
One solution could be to have the if statement to return a tuple with all the variables, and use the power of assignment operation, like:
val (myA, myB, myC) = if(something) {
val a = "a"
val b = "b"
val c = "c"
(a,b,c) // this will return the 3 variables/values because if statements are an expression, and expressions return something
} else {
val a = "A"
val b = "B"
val c = "C"
(a,b,c)
}
// now you have a,b,c defined in this scope and you can do whatever you need with them
if you want to return different variables depending on the if statement, you will have more complications. a solution would be to make the not needed variables null or an Option
Let me know if you need anything else better explained :)
EDIT: solution for minified edited example
I don't have anything here to check if it compiles, but it should be something like:
#(status: String)(implicit messages: Messages)
#{
val myClass = if(status == "00") {
"custom-class-1"
} else if (status == "01") {
"custom-class-2"
} else {
""
}
#layout("page title") {
<div class="#myClass">This is a div</div>
}
Alternative using pattern matching:
replace the if/else statement with:
val myClass = status match {
case "00" => "custom-class-1"
case "01" => "custom-class-2"
case _ => ""
}
(the case _ is like "in every other case")
The answer by #pedrorijio is almost exactly correct, but the actual code which worked for me in the end was this:
#myClass = #{status match {
case "00" => "custom-class-1"
case "01" => "custom-class-2"
}}
Thank you for the assistance!

How to get the tags assigned to a pimcore object?

The pimcore documentation refers to the public static function getTagsForElement($cType, $cId). What values do $cType and $cId take?
I want to (a) assign tags to objects, (b) get the objects with a specific tag, e.g. myTag, and then (c) iterate through the list as in the news and blog examples in the demo system. My question relates to (b).
More specifically, myTag will be held in one object as myTags/myTag/myTarget and the aim to get a list of the other objects tagged with myTags/myTag.
Thank you.
Get all the tags of the object:
$tags = \Pimcore\Model\Element\Tag::getTagsForElement("object", 3);
foreach ($tags as $tag) {
echo $tag->getName() . " (ID=" . $tag->getId() . ")<br>";
}
$cType refers to an element type (object, document, asset) and $cId refers to an element ID (object id, document id, asset id).
To get a list of objects that have a certain tag use this:
$type = "object";
$tagId = 3;
$tag = Pimcore\Model\Element\Tag::getById($tagId);
$tagPath = $tag->getFullIdPath();
$considerChildren = true;
if ($considerChildren) {
$conditionForTags = "o_id IN (SELECT cId FROM tags_assignment INNER JOIN tags ON tags.id = tags_assignment.tagid WHERE ctype = '$type' AND (id = '$tagId' OR idPath LIKE '$tagPath%' ))";
} else {
$conditionForTags = "o_id IN (SELECT cId FROM tags_assignment WHERE ctype = '$type' AND tagid = '$tagId')";
}
$objectList = new \Pimcore\Model\Object\Test\Listing();
$objectList->setCondition($conditionForTags);
foreach ($objectList as $item) {
echo $item->getId() . "<br>";
}
In above example you have to use the ID of the tag and not the name!
If you want to use this approach on documents and assets, replace o_id with id.
[functional programming way] example (Object) Post tags separated by comma:
echo implode(', ',array_map(function($tag) {
return ''.$this->t($tag->getName()) . '';
}, \Pimcore\Model\Element\Tag::getTagsForElement('object', $this->post->getId())));

Inline variable in the Play framework 2.x Scala template

How to create an inline variable in the Play framework 2.x Scala template?
Path from the Play's guide is not clear to me:
#defining(user.firstName + " " + user.lastName) { fullName =>
<div>Hello #fullName</div>
}
First you don't create a variable but a value meaning it's read only.
In your example you have created a value fullName which is accessible inside the curly brackets.
#defining("Farmor") { fullName =>
<div>Hello #fullName</div>
}
Will print Hello Farmor
To define a value which is accessible globally in your template just embrace everything with your curly brackets.
E.g.
#defining("Value") { formId =>
#main("Title") {
#form(routes.Application.addPost, 'id -> formId) {
#inputText(name = "content", required = true)
<input type="submit" value="Create">
}
}
}
In the example you can use the value formId anywere.
If you don't want to use the #defining syntax you can define a reusable block which will be evaluated every time you use it:
#fullName = #{
user.firstName + " " + user.lastName
}
<div>Hello #fullName</div>
With this same syntax you can also pass arguments to the block:
https://github.com/playframework/Play20/blob/master/samples/scala/computer-database/app/views/list.scala.html
It's easy, span your block with code from the sample, then you will can use #fullName variable which has value:
user.firstName + " " + user.lastName