Jekyll Liquid Array ID Not Working - jekyll

I have a CSV file in my _data folder and I am trying to specify the row of the CSV to access in my Front Matter and then return specific columns from the CSV based on the row specificed in the Front Matter.
Here's the CSV file:
name,description
Dallas,Big City in Texas
And here's the contents of my index.html file:
---
city: "Dallas"
---
{{ site.data.data[page.city].description }}
Per the Jekyll Docs page on using data files, I should be able to use this syntax to access data files in this way, but the compiled html file does not include any data.
I have tested other ways of accessing the contents of the CSV file and those work, so it doesn't appear to be a problem with the data file or the site itself but rather with using the [ ] array id Liquid syntax.

Looks like you have misunderstood the [] notation for a hash structure.
I will first orient you on how the [] is supposed to work..
Expanding your data.csv a bit:
name,description
Dallas,Big City in Texas
Houston,Another City in Texas
and "inspecting" your the data object obtained from the above CSV file,
{{ site.data.data | inspect }}
on building the site, you'll see that the resultant object is simply an Array of Hashes :
<p>
[
{"name"=>"Dallas", "description"=>"Big City in Texas"},
{"name"=>"Houston", "description"=>"Another City in Texas"}
]
</p>
which means you can only access individual hash entry by referencing its index number.
i.e. {{ site.data.data[0] }} will give you the first hash and {{ site.data.data[1] }} will give you the next hash.
and therefore {{ site.data.data[0].description }} will give you the result you expect to get:
<p>
Big City in Texas
</p>
Now that you know how [] works for data hashes, lets simply get to the solution.
To access elements in an Array, one can simply iterate through the Array objects and reference necessary entries:
{% for entry in site.data.data %}
<div>
<span>{{ entry.name }}</span> : <span>{{ entry.description }}</span>
</div>
{% endfor %}
will give you:
<div>
<span>Dallas</span>
<span>Big City in Texas</span>
</div>
<div>
<span>Houston</span>
<span>Another City in Texas</span>
</div>

Related

Jekyll Collection Filter

I'm trying to grab a specific item from a collection called 'content' based on an id using where_exp, but for the life of me I can't get it to work. Here's the code:
filter:
{% assign var = site.content | where_exp:"content", "content.id == 'testId'" | first %}
frontmatter for post in collection:
---
layout: content
title: "This is the title"
image: "assets/photos/image.jpg"
id: "testId"
---
html:
<img class="full-width-poto" src="{{ var.image }}">
I can't figure out what I'm doing wrong.
Note, I've been referring to this post: Getting a specific item from a collection in Jekyll and https://riptutorial.com/jekyll/example/28446/accessing-a-specific-collection-item
Ok, I figured out my problem, just in case someone comes across this. For some reason I can't use the key 'id' for this...it must be hardcoded for something else.
I swapped in 'myid' and it works fine now...

How to render HTML with golang data in golang gin web frame?

I am trying to place a golang array (also slice, struct, etc.) to HTML so I can use array element in HTML Element content when returning HTML from golang gin web framework. Another problem is how to render these data with loop? Such as Flask jinja
works in this way.
{% block body %}
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
Usually you have a folder with template files so first you need to tell the gin where these templates are located:
router := gin.Default()
router.LoadHTMLGlob("templates/*")
Then in handler function you simply pass template name the data to HTML function like this:
func (s *Server) renderIndex(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", []string{"a", "b", "c"})
}
In index.tmpl you can the loop the data like this:
{{range .}}
{{.}}
{{end}}
The . is always the current context so in first line . is the input data and inside the range loop . is the current element.
Template example: https://play.golang.org/p/4_IPwD3Y84D
Documentation about templating: https://golang.org/pkg/text/template/
Great examples: https://astaxie.gitbooks.io/build-web-application-with-golang/en/07.4.html

Laravel: Routes with parameters

I have following case:
Route::get('/kids_report_card/{id?}/{param?}', 'KidsReportCardController#index');
And in view file I have:
{{ url('kids_report_card/4') }}
In some other view file I have:
{{ url('kids_report_card/name') }} (where name is string here-some parameter)
Now the situation is:
For {{ url('kids_report_card/4') }} ,Route::get('/kids_report_card/{id?}/{param?}', 'KidsReportCardController#index'); works fine.
For {{ url('kids_report_card/name') }},Route::get('/kids_report_card/{id?}/{param?}', 'KidsReportCardController#index'); doesn't work fine as in url we have name parameter while in Route we have first parameter as id(integer value). so is there any dynamic solution that srting parameter must go to second parameter in Route??
You can pass an array of parameters in the url like this:
{{ url('kids_report_card', ['name' => 'name_value']) }}
Reference: URL's

Mailjet: Array value provided through vars makes email being blocked on sending

I’m working on an email template for Mailjet written in MJML that uses an array value provided through Vars to generate a list of items the sender wants to receive from the mail recipient. All values in the array are plain text values.
The data passed to the API request looks like this:
{
"FromEmail":"sender#email.com",
"FromName":"Chris Crumble",
"Subject":"Data Request",
"MJ-TemplateID":"200000",
"MJ-TemplateLanguage":true,
"Recipients":[
{
"Email":"recipient#email.com",
"Name":"Hans Henson"
}
],
"Vars":{
"mailTitle":"Data Request",
"userName":"Chris Crumble",
"imageUrl":"http://my.host.com/image.jpg",
"userBirthDate":"1.3.1982",
"recipientName":"Hans Henson",
"uploadUrl":"https://my.upload.com/",
"authVideoUrl":"https://my.authvideo.com",
"records":["Document A","Document B"],
"authPhone":"113777840097"
}
}
The template uses var:records like this:
...
</mj-text>
<mj-raw> {% if var:records:false %} </mj-raw>
<mj-text>
<p>
I, <strong>{{var:userName}}, born on {{var:userBirthDate}}</strong> am asking you to provide the following documents:
</p>
</mj-text>
<mj-raw> {% for item in var:records %} </mj-raw>
<mj-text>
{{item}}
</mj-text>
<mj-raw> {% endfor %} </mj-raw>
<mj-raw> {% else %} </mj-raw>
<mj-text>
<p>
I, <strong>{{var:userName}}, born on {{var:userBirthDate}}</strong>, am asking you to provide all my existing documents.
</p>
</mj-text>
<mj-raw> {% endif %} </mj-raw>
<mj-text>
...
As long as var:records isn’t set in the data sent with the request, the mail is sent as expected. As soon as an (not empty) array value is provided with the request, the mail is blocked by Mailjet on sending without giving any further information on the reason.
No idea how to get this working.
UPDATE:
Thanks to Zhivko’s hint to the error reporting mechanism provided by Mailjet I was able to gain a little more insight into the problem.
The template produces the following error:
expression parsing error ## Unknown identifier: var:records:false ## near ## var:records:false ##
This still doesn’t make any sense to me as the line mentioned is an if condition with a default value of false defined for the case that no value for var:records is provided with the api request.
Also the template only produces this error when the value is explicitely set in Vars and is not empty.
My tests so far make me guess that it may have to do with the provided value being an array value as the line doesn’t cause any problems if the value is plain string.
I had the same problem and after asking the MJML team on their Slack I add an answer. Just use the defined() method :
Example :
{% if defined(var:employees) %}
My employees :
<ul>
{% for employee in var:employees %}
<li>{{employee.firstname}} {{employee.lastname}}</li>
{% endfor %}
</ul>
{% endif %}
This method is correct and a core maintainer of MJML just says :
It's not publicly documented yet
PS : Their Slack is a good place to ask this kind of question and I had a response in minutes. (mjml.slack.com)
The message is probably blocked due to an error in the template language. To receive details about the error, enable the error reporting mechanism. If you have troubles debugging the error message, open a support ticket with Mailjet for in depth investigation for the specific template.
As far as I know, Mailjet doesn't allow arrays as a personalized var.
DataType: the type of data that is being stored (this can be either a
str, int, float or bool)
https://dev.mailjet.com/guides/#manage-contacts
Solution:
<% if(typeof bar !== 'undefined') { %>
variable 'bar' is defined in payload:
<b><%= bar %></b>
<% } else {%>
variable 'bar' is not defined in payload
<% }%>

Create hyperlink in django template of object that has a space

I am trying to create a dynamic hyperlink that depends on a value passed from a function:
{% for item in field_list %}
<a href={% url index_view %}{{ item }}/> {{ item }} </a> <br>
{% endfor %}
The problem is that one of the items in field_list is "Hockey Player". The link for some reason is dropping everything after the space, so it creates the hyperlink on the entire "Hockey Player", but the address is
http://126.0.0.1:8000/Hockey
How can I get it to go to
http://126.0.0.1:8000/Hockey Player/
instead?
Use the urlencode filter.
{{ item|urlencode }}
But why are you taking the name? You should be passing the appropriate view and PK or slug to url which will create a suitable URL on its own.
Since spaces are illegal in URLs,
http://126.0.0.1:8000/Hockey Player/
is unacceptable. The urlencode filter will simply replace the space with %20, which is ugly/inelegant, even if it does kind of get the job done. A much better solution is to use a "slug" field on your model that represents a cleaned-up version of the title field (I'll assume it's called the title field). You want to end up with a clean URL like:
http://126.0.0.1:8000/hockey_player/
To make that happen, use something like this in your model:
class Player(models.Model):
title = models.CharField(max_length=60)
slug = models.SlugField()
...
If you want the slug field to be pre-populated in the admin, use something like this in your admin.py:
class PlayerAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
....
admin.site.register(Player,PlayerAdmin)
Now when you enter a new Player in the admin, if you type "Hockey Player" for the Title, the Slug field will become "hockey_player" automatically.
In the template you would then use:
{% for item in field_list %}
<a href={% url index_view %}{{ item.slug }}/> {{ item }} </a> <br>
{% endfor %}
There is this builtin filter .
http://docs.djangoproject.com/en/dev/ref/templates/builtins/#urlencode
Although you should be using one of these
http://docs.djangoproject.com/en/dev/ref/models/fields/#slugfield