Twig array access - arrays

I'm trying to print out value of the variable passed to the twig template. I'm using this code:
{{ naziv[0] }} Index is 0 because passed array has only one element. Mentioned code produces following error:
Key "0" for array with keys "title" does not exist in...
but when I use for loop like this:
{% for key,value in naziv %}
{{ value }}
{% endfor %}
I get what I want.
What's wrong with {{naziv[0]}} ?

Based on the var_dump of array(1) { ["title"]=> string(11) "SpaceVision" }
You should access your array in this way: {{ naziv['title'] }}.
The key of your array is associative and not a numerically indexed array. That is why you cannot use naziv[0].
You can also use: {{ naziv.title }} aswell.
See the documentation.

Your array is not number indexed, thus naziv[0] is not defined. Access it as naziv.title.

Related

Hugo - using index with complex key to get data

Assuming the following urls.toml file in data folder:
[Group]
link = "http://example.com"
[Group.A]
link = "http://example.com"
I know that I can access the link value in Group.A in my shortcode like this:
{{ index .Site.Data.urls.Group.A "link" }}
But, I would like to access the link in a way similar to the following:
{{ index .Site.Data.urls "Group.A.link" }}
The reason for this is to enable me to pass the "Group.A.link" as a parameter to my "url" shortcode within the content markdown like this:
{{< url "Group.A.link" >}}
Otherwise, I won't be able to use nesting for logical organisation in the urls.toml data file.
Thanks in advance.
You can use nested calls of index COLLECTION "key" to narrow your way down.
Meaning,
(index (index (index .Site.Data.urls "Group") "A") "link")
would work given your urls.toml structure.
The trick is making it somewhat dynamic, so you don't need to worry too much about depth.
The snippet below might serve as a potential starting point for a shortcode. However, it doesn't have any safe-guards. I'd recommend to add a few checks to get meaningful errors/warnings if things go wrong.
{{ $path := .Get 0 }}
{{/* split the string to have indices to follow the path */}}
{{/* if $path is "A.B.C", $pathSlice wil be ["A" "B" "C"] */}}
{{ $pathSlice := split $path "." }}
{{ $currentValue := .Site.Data.urls }}
{{ range $pathSlice }}
{{/* recommended homework: check that $currentValue is a dict otherwise handle with defaults and/or warnings */}}
{{ $currentValue = index $currentValue . }}
{{ end }}
<p>et voila: {{ $currentValue }}</p>
After having looked at Hugo's code (Index function) I found a very simple solution.
If we want to pass a complex comma-separated key, all we need to do is split it when calling index. Example:
Using the url shortcode in markdown:
{{< url "Group.A.link" >}}
Code of the url shortcode:
{{ index .Site.Data.urls (split (.Get 0) ".")}}

Comparing two arrays, checking for matching values

Using HubL (as I'm building a module in HubSpot), I have two arrays:
topics : Which is a list of topics.
all_tags: Which is an array of all the blog tags in the system.
If I dump out these arrays, this is what it will return:
{{ topics }} prints the following: [Data, Accounting, Insight]
{{ all_tags }} prints the following: [Accounting, Press, Data]
So essentially, {{ topics }} has a tag ("Insight") that doesn't exist in the system yet.
What I'm trying to do is to create a third array, which will contain matching results from the two above arrays. For example, topics_final, once returned, should print [Data, Accounting].
But, when printing {{ topics_final }}, the array is empty.
What I've tried:
<!-- this gets all tags -->
{% set all_tags = blog_topics( blog_id , 250) %}
<!-- create arrays -->
{% set topics = [] %}
{% set topics_final = [] %}
<!-- append topic data to the array -->
{% for item in module.add_topics.topics %}
{% set topic_option = item|striptags %}
{% do topics.append( topic_option ) %}
{% endfor %}
<!-- check if topic tags exists in HubSpot -->
{% for topics in all_tags %}
{% if topics in all_tags %}
{{ topics }}
<!-- results with above
Data, Accounting, Insight
-->
{% else %}
else
{% endif %}
{% endfor %}
With the above, it just prints out the {{ topics }}, even though Insight isn't in the all_tags array.
Note: Tagging Jinja2 as the syntax is similar
A combination of the filter reject and the built in test in could help you achieve this.
Sadly, it seems the reject filter does not accept negating a test, still, you can reject all the elements of topics that are not in all_tags then reject the said elements from the topics list.
So that ends with:
{{ topics | reject('in', topics | reject('in', all_tags) | list) | list }}
Switch yields:
[
"Data",
"Accounting"
]

Liquid from AzureLogicApps parsing an object dynamically

I'm looking to parse a JSON object dynamically in a Liquid.
So far my efforts have been in vain as you can't loop over an object with a regular for loop.
The amount of properties in the ticket_attributes objects is dynamic and can vary in keynames.
Input object:
{
"action": "insert",
"state": "New",
"ticket_attributes": {
"category": "Event",
"user_name": "Customer ",
"prop3":"data1",
"prop4":"data1",
},
"ticket_number": "INC9190433"
}
Liquid snippets used that don't work:
{% for prop in content.ticket_attributes %}
{{prop[0]}}:{{prop[1]}}
{% endfor %}
{% for item in content.ticket_attributes %}
{{ forloop.index }}: {{ item.name }}
{% endfor %}
Any pointers on how to solve this inside the template?
According to some test, it seems liquid in azure logic app doesn't support loop hash. I think we can implement this requirement outside azure logic app with liquid as the template you provide in your question, but in azure logic app we can't.
For this requirement, I think we can just parse the json data, get the property ticket_attributes as string, remove the head "ticket_attributes": { and the tail }, and then insert it back to the resource json data.

Django - Access list values on template

I've to get access to all values availables in a list(array) in a Django template. All examples I find online, use dictionaries instead. So, the list is passed correctly to the template, but the following code doesn't work:
{% for item in array %}
field_names = field_names + "{{ item }},";
{% if forloop.last %}
field_names = field_names + "{{ item }}";
{% endif %}
{% endfor %}
I could access the values using {{ field.[0] }} , {{ field.[1] }} , etc. But, I have to make it work independently of the list's size.
Can anybody give me a hint?
P.S. - I cannot use a dictionary to pass the values to the template, since that code wasn't donne by me, and I'm not supposed to touch it.
In your view:
my_joined_list = ",".join(somelist)
In your template:
field_names = {{ my_joined_list }}
Resolved it!! I just passed the variable to the template exactly as i needed it and used {{ array|safe }} to resolve it to a Javascript variable. Done!

TWIG - variable == objectattribute

I am new to Twig and Symfony2 (and PHP as well). I currently have an array of objects where I can access an attribute by doing {{result.attribute1}} after a {for result in results} statement.
I would like to use a variable {{var| removePath}} (where removePath is an extension I made in Twig), and use it to iterate over the results array. What I would like to do is return the row if {{var| removePath}} == result.attribute1.
Is this possible to do in Twig? If so, how should I approach this? I have already tried something similar to the code found below, but the "else" statement is executed (saying there's no match). I also tried var == result.attribute, but this didn't work either.
{% for result in results %}
{% if var|removePath in result.attribute1 %}
{{ var | removePath }} exists.
{% else %}
{{ var | removePath }} doesn't exist in array.
{% endif %}{% endfor %}
Thus I think I have 2 questions;
1) Is it possible in TWIG (if so, how)
2) Is there an easier/better way to get the whole row (object array also contains attributes 2, 3 & 4, and I would like to return those that are in common with attribute 1 (if it matches var))
See schema of my array recently added
Thank you in advance for your help! I hope my question is understandable :S
Just surround the expression with brackets.
use (var|removePath) which groups an expression.
example:
{% if ( 1+1 ) == 2 %}
And you can use the attribute() function to access properties and methods of an object/array.
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
attribute chapter in the twig docs.
Further shorten template code using the ternary operator like this:
{% set strippedVar = var|removePath %}
{{ strippedVar }}{{ (strippedVar in result.attribute1) ? 'exists' : 'does not exist' }}.
Setting the filtered variable to another prevents executing the filter multiple times.

Resources