Is it possible to define complex variables in Twilio Studio Flow? - twilio-studio

I'm building a subflow to manage the menus, because I have multiple of them and it is turning very complex to read.
I need to send an array or a structured type of parameter to the subflow.
Is there any way to create a multilevel (like JSON) or array variable using the Set Variable Widget?
I need to send to the subflow the indexes and descriptions of each items of the menu, so I can build the menu using Liquid Template Language inside a Send & Wait Widget.

Yes, you can create a lot of complex conditions using only the Studio.
The Studio uses the liquid template for the texts, you can see all the possibilities on this documentation.
I'll give some examples of what you can do using the liquid template (These examples can be used on Message, Voice, and Set variables widgets:
//example 01
//iterating between an array of 25 items
{% for item in (1..15) offset:0 limit:15 %}
{%- if forloop.last -%}
{{forloop.index | plus: flow.variables.offset}} - Last Item {{forloop.index | plus: flow.variables.offset}}
{%- else -%}
{{forloop.index | plus: flow.variables.offset}} - Items {{forloop.index | plus: flow.variables.offset}}
{% endif %}
{% endfor %}
//in the above example I used an array with a specific size, but you can get the array from an API and iterate in the same way, and as you can see, you can set variables inside of the context of the widget using the assign
//example 02
//A If condition using Liquid
{%- if widgets.send_and_reply_1.inbound.Body == "1" -%}
item 1
{%- else -%}
item 2
{%- endif -%}
//example 03
//these variables are used how anchors on iteration, because the studio has a limit of 15 items by time, so this will control it, I iterate by ten items by time and last, I give the option to customer select more
{% assign iterationSize = flow.variables.offset | plus: 10 %}
{% assign arraySize = flow.variables.arraySize | plus: 0 %}
Encontrei {{widgets.getAvailableDays.parsed.data.qtd}} opções.
Selecione um dia.
//here I'm iterating from data that brings from an API, so I'm getting it from the parsed.
{% for day in widgets.getAvailableDays.parsed.data.resultado offset:flow.variables.offset limit:10 %}
{% if forloop.last %}
//here I'm using the iterating item to show to customer, in this case it's just a string, but if you've an object you can access it from the same way, i.e day.someDataInsideOfThisObject
{{- forloop.index | plus: flow.variables.offset -}} - Dia {{day}}
{% if iterationSize < arraySize %}
{{forloop.index | plus: 1 | plus: flow.variables.offset}} - Mais opções
{% endif %}
{% else %}
{{-forloop.index | plus: flow.variables.offset -}} - Dia {{day}}
{%- endif -%}
{% endfor %}
I hope that it can help you :D.

Related

Symfony/ Twig: Filter-filter a collection

Newbie here. Using Symfony 3.4.
I have a Collection of EntityType formtypes I created with the form builder. I'm trying to deposit them on the page selectively. I'd like to loop through them all several times on my template, spitting some of them out according to specific criteria (for instance, the value of a "HiddenType" subtype).
For instance, let's say I had a collection of Movies, some of which have a "Rating" HiddenType. My task is to spit them out selectively in several separate "Rating" sections (i.e. all the R-Rated movies in a single section).
Edit: But! Ratings are user-imputed; dynamically-generated elsewhere. So I can't just make a finite amount of "sections" ahead of time.
My first thought was
{% for rating in ratings %}
<h1>{{rating}}-Rated Movies</h1>
{% for movie in form.movies %}
{% if movie.rating = "R" %}
{{movie}} // put movie formtype/ collection member here somehow...?
{% endif %}
{% endfor %}
{% endfor %}
But I also read that twig has a "filter" filter:
{% for rating in ratings %}
<h1>{{rating}}-Rated Movies</h1>
{% for movie in movies|filter(m=> m.rating == rating) -%}
{{ m }} //put movie formtype/ collection member here somehow...?
{% endfor %}
{% endfor %}
Either way, though, I can't really reconcile the functions I'm familiar with for converting forms to actual html (e.g. form_row() ) with the either of these methods.
Any ideas?
You need to order the movies in your Form by rating. Then in your template do something like this:
{% set rating = null %}
{% for movieForm in form.movies %}
{% set movie = movieForm.vars.value %} <= check if this is the movie entity by dumping it
{% if movie.rating != rating %}
<h1>{{ movie.rating }}</strong>
{% set rating = movie.rating %}
{% endif %}
{{ form_row(movieForm) }}
{% endfor %}

Random values in array with Timber (Twig) and Wordpress

I merged values of two arrays in a new array.
But I would like to take random values from this array and put them in a loop. That those values iterate in this loop.
{% set myArray = [] %}
{% set list1 = options.transitions_repeater %}
{% set list2 = options.transitions_wahou_repeater %}
{% set myArray = list1|merge(list2) %}
{% for key, val in myArray %}
{{ val|join(', ') }}
{% endfor %}
{% for item in options.projets %}
<li data-transisition="{{ myArray }}"></li>
{% endfor %}
I got the message : Array to string conversion in XX on line XX
Output :
animBottom
animTop
animLeft
directionRight
circles
cube
Your merged list is still a multidimensional array.You could solve your issue with the following code, however it's preferable to move the logic of creating the (single dimensional) array to your controller (then you could remove the filter first in the snippet)
{% for item in options.projets %}
<li data-transisition="{{ myArray[random(myArray| keys)] | first }}"></li>
{% endfor %}
demo

How to use capture cycle odd even and target specific collection item in Jekyll

Hi I'm working on a Jekyll site. I am using a capture cycle for odd and even displays of the collection. I would also like to specifically target which collections are shown on this page.
Here's the code so far:
{% assign sorted = (site.catalog | sort: 'date') | reverse %}
{% for project in sorted limit: 5 reversed %}
{% capture thecycle %}{% cycle 'odd', 'even' %}{% endcapture %}
{% if thecycle == 'odd' %}
{% if project.featured == "1" || project.featured == "3" || project.featured == "5" %}
<div>{{ project.title }} {{ project.subtitle }}</div>
{% endif %}
{% if thecycle == 'even' %}
<div>{{ project.title }} {{ project.subtitle }}</div>
{% endif %}
{% endfor %}
So I would like five items to be shown on this page in total. For the odd cycles, I would like those items to be (1,3,5) to display a certain format, and for the even cycles, I would like those items (2,4) to display a certain format.
The approach I started using would show this variable in the front matter of the collection item:
featured: "1"
Thanks in advance for any help

Looping through values in twig and replacing empty values

The title is a bit ambiguous I know, but let me explain what I'm trying to achieve.
I am attempting to generate a CSV based on data pulled from a doctrine query in my Symfony2 CRM. The data retrieved is based on OpenCart Product and Attribute data, as well as some bespoke information which is irrelevant for this issue.
Each product can have up to 5 different attribute values, named A, B, D, L1 and L2. However, some products do not have all of them, only A, B and L1. The CSV requires each attribute value to be in a separate cell - so the headers are as follows:
ATTRIBUTE: A | ATTRIBUTE: B | ATTRIBUTE: D | ATTRIBUTE: L1 |
ATTRIBUTE: L2
And then I loop through in my Twig file as follows:
{% for attribute in row.product.attributes %}
{% if attribute.text is not null %}
{{ attribute.text }},
{% else %}na,{% endif %}
{% endfor %}
If the product has all 5 attributes, the structure of the CSV is fine. However, if the product only has 3 attributes, it means that all of the subsequent values are pulled back a cell, meaning that the other data is under the wrong headings. I tried checking for values first:
{% for attribute in row.product.attributes %}
{% if attribute.attributeName.name == "A" %}
{% if attribute.text is not null %}
{{ attribute.text }},
{% else %}na,{% endif %}
{% endif %}
{% endfor %}
And I did this for each possible attribute name, but unfortuantely this does not work since if the name does not exist, it just skips it anyway. I'm having trouble trying to think of a way to loop through these attributes and entering a n/a if it's non existent - I'm sure there is a way but I don't know what it is.
For reference, here is the controller code that's generating the data for the CSV:
public function adminCsvAction($filter) {
$repository = $this->getDoctrine()->getRepository('AppBundle:Project');
$stages_repository = $this->getDoctrine()->getRepository('AppBundle:Stage');
$users_repository = $this->getDoctrine()->getRepository('AppBundle:User');
$results = $repository->getSearchResults($filter);
$users = $users_repository->findAll();
$stages = $stages_repository->findBy(array('deleted' => 0), array('sortOrder' => 'ASC'));
$filename = "export_".date("Y_m_d_His").".csv";
$response = $this->render('AppBundle:pages:csv.html.twig', array('data' => $results,'users' => $users, 'stages' => $stages));
$response->headers->set('Content-Type', 'text/csv');
$response->headers->set('Content-Disposition', 'attachment; filename='.$filename);
return $response;
}
The Project Entity has various mappings, one of which links to the Product table in OpenCart which means all attributes and linked values are accessible via this.
Any help in this is much appreciated.
I also agree with Cerad from comment section - that is not the job for Twig. In case your really need to do it, I would try roughly something like this:
{% set allAttr = ["A","B","D","L1","L2"] %}
{% for attribute in allAttr %}
{% if row.product.attributes[attribute] is defined %}
{{ row.product.attributes[attribute].text }}
{% endif %}
{% if not loop.last %},{% endif %}
{% endfor %}
I guess the is defined is critical here...
OK I figured it out. Using what Jovan Perovic suggested, I came up with this:
{% set allAttr = ["A","B","D","L1","L2"] %}
{% set prodAtts = [] %}
{% for row in data %}
{% set existingAtts = [] %}
{% for att in allAttr %}
{% if att not in prodAtts %}
{% set prodAtts = prodAtts|merge([att]) %}
{% endif %}
{% endfor %}
{% for rowAtt in row.product.attributes %}
{% set existingAtts = existingAtts|merge({(rowAtt.attributeName.name|trim):(rowAtt.attributeName.name|trim~'_'~rowAtt.text|trim)}) %}
{% endfor %}
{% for prodAtt in prodAtts %}
{% if prodAtt not in existingAtts|keys %}
{% set existingAtts = existingAtts|merge({(prodAtt):(prodAtt~'_na')}) %}
{% endif %}
{% endfor %}
{% set orderedAtts = existingAtts|sort %}
....
Then the loop for each row thereafter. I used the attribute name with an underscore in order to be able to sort it correct (as it only sorts by value not key) then used preg_replace to remove it along with any instance of the name so I just ended up with the value.
Bit of a lengthy - and probably over thought - solution but it does work!

Shopify: Global variable data type

I'm having an unbelievable amount of difficulty finding out the data type of a global variable in Shopify. My problem could be a matter of scope, but it still shouldn't be difficult for them to tell me a data type. Their tech support says the theme writer should answer it and the theme writer says that Shopify should answer it. IMHO, either of them should be able to answer it. So I would greatly appreciate any wisdom you can provide.
My client is a wholesaler who does not do orders less that $50.00. It should be fairly easy to run a comparison in the variable for the total order (cart.total_price | money_with_currency), but my code is entirely unsuccessful. The code should also allow a retailer to change their order and run the comparison again. I have added every possible combination of parenthesis to the variable and pieces, in case I have a syntax error.
<div class="six columns cart-buttons">
{% if cart.total_price | money_with_currency < 50 %}
<div style="font-weight: bold; color: #900; margin-bottom: 15px;">Your order must be at least $50.00</div>
{% endif %}
{% if cart.total_price | money_with_currency > 50 %}
<input class="button nice" type="submit" value="{{settings.checkout_text}}" name="checkout" />
{% if additional_checkout_buttons %}
<em>or</em>
{{ content_for_additional_checkout_buttons }}
{% endif %}
{% endif %}
</div> <!-- end cart buttons div -->
See the Shopify docs on money filters. The money_with_currency filter may output something like "$1.45 CAD". Maybe try money_without_currency, which formats the price as a decimal.
EDIT:
Looks like money_without_currency doesn't work. The code below causes Liquid error: comparison of String with 50 failed:
{% assign total_price = cart.total_price | money_without_currency %}
{% if total_price < 50 %} ... {% endif %}
So, you have 2 options. First, you could convert the output of money_without_currency to a number like this:
{% assign total_price = cart.total_price | money_without_currency | times: 1 %}
Or, compare against cart.total_price without a filter (add 2 zeros because cart.total_price does not have a decimal place, so $50.00 is 5000 if not formatted with a money filter):
{% if cart.total_price < 5000 %} ... {% endif %}

Resources