Use apply with a method in Hugo - hugo

I don't know if the terminology is correct, but essentially it comes down to using something like site.GetPage or path.Base as opposed to something like humanize with apply in Hugo:
I have a part of a layout in Hugo that looks like the following:
{{ range .Params.related_plays }}
{{ with site.GetPage . }}<li>{{.Title}}</li>{{ end }}
{{ end }}
where related_plays is a list of strings containing the path to pieces of content (e.g. ["english/play-1.md", "english/play-2.md"]. This currently works.
Instead of the above, I'd like to assign the list of page objects into a variable. I've tried something like the following:
{{ $related_plays := apply .Params.related_plays "site.GetPage" "." }}
but I get the following error:
error calling apply: can't find function site.GetPath
Is there any way to call apply for something like this?
I'm guessing my alternative is to build up a Scratch slice via the range and with functions, but if it can be done with apply, I would prefer that.

Related

Wrapping HTML tags using Yield with Ruby

Ruby beginner here.
I am trying to understand yield and how to wrap HTML tags around it and I have been having issues with this code.
def tag (tag_name, attributes = nil)
"<#{tag_name}#{attributes}>#{yield}</#{tag_name}>"
end
style_tag = tag("div", ["class=", "red"]) do
tag("h1") do
"Google it"
end
end
my output is :
"<div[\"class=\", \"red\"]><h1>Google it</h1></div>"
Thank you
The issue is not with yield wich seems to be working fine, but with the attributes parameter. Or rather inserting the parameter into the string.
At the moment you are doing an implicit Array.to_s which is where the brackets come from. If you are sure the attributes string is correct, you can do a simple ...#{attributes.join} ... to join all elements to a proper string (provided the HTML syntax is correct and so on).

Go template to print an array's length

I have no Go experience. I use a tool, Podman, which is written in Go, it documents its --format option as,
-f, --format string Format the output to a Go template or json (default "json")
I can see what I want with,
podman inspect localhost/myimage --format "{{.RootFS.Layers.length}}"
But, if I want to get the count of how many elements there are what do I do? I've tried different fields with .count and .length and .len, but I always get,
can't evaluate field FieldName in type []digest.Digest
I've also tried invoking this as {{len(RootFS.Layers)}}. I'm just kind of brute forcing it. When I do the above, I get,
ERRO[0000] Error printing inspect output: template: all inspect:1: unexpected "(" in operand
What is the right Go Template to get an array's element count?
The go templating language and syntax is different from the go language itself - so len(RootFS.Layers) as you have seen does not work.
From the template docs, you are using the correct function len but the template syntax does not require parenthesis. So use:
{{ len .RootFS.Layers }}
FYI: a quick intro to Go templates.

parse array in laravel blade

my view page consist {{$data->attachment}} which render
[{"filename":"hello.jpg", "location":"/home/my_folder"}].
Here i tried to display file name in view page using
#foreach($data->attachment as $attachment)
$attachment->filename
#endforeach
which gives me
Invalid argument supplied for foreach()
i trying
{{$data->attachment->filename}}
which gives me
Trying to get property of non-object
what i'm doing wrong? how can i display filename? thanks.
As you mentioned in the comments, the value of $data->attachment is actually a string. In order to iterate over it in a loop you will need to convert it back to an array.
So if you change your loop to:
#foreach(json_decode($data->attachment) as $attachment)
{{ $attachment->filename }}
#endforeach
you should get what you want.
I would add that the correct place for this conversion should really be in your controller, not your view.
Your question was not entirely clear so this is all assuming you knew what you were doing when you used a foreach loop, meaning you actually have multiple entries in the $data->attachment array. If it is just the one attachment and you are really just trying to get the filename, then you don't need a loop, all you need is to say:
{{ json_decode($data->attachment)->filename }}
and again I would add that really that all belongs in your controller so that in your view you would end up with something like {{ $filename }}

Iteration of array in Liquid

I'm using an analog of Shopify and I'm stuck with syntax of Liquid.
I need to output in the template the field with an id product[product_field_values_attributes][][value]
So I need to write a loop to get the i value of this array.
I'm confused with this empty element in the brackets.
I've looked through the examples of loop syntax in Liquid but all of those arrays are simple and they are not my case.
For example, the Title field has id product[title] and in Liquid template i call this variable product.title and it works fine.
But all my tries to write a loop for this array failed.
Please, help to write a loop to get the values of the array stated above.
Try outputting the array directly onto the page using {{ product }} or {{ product[product_field_values_attributes] }} somewhere in the HTML. That will do a JSON-like string representation of the array. From there you can figure out what the keys for the array are.
I'm not sure what you're saying about the i value. You don't reference i anywhere else in your question. If you can clarify that then we can see if something can be done about it.

Twig iterating though a non nested array ( mysql_fetch_array )

When I use the following code:
$members = array();
$members[] = array([id]=>"1", [name]=>"name") ; // mysql_fetch_array($row)
I can iterate with twig like this:
{% for member in members %}
<tr><td>{member.id}</td><td>{member.name}</td></tr>
{% endfor}
But I have more rows, and I don't want to allocate the entire array in the memory, it seems like a waste of resources to me.
So how do I loop through:
$members = array([id]=>"1", [name]=>"name");
Currently it seems to iterate each array key, in stead of the entire array:
{% for member in members %}
<tr><td>{member.id}</td><td>{member.name}</td></tr>
{% endfor}
outputs :
<tr><td>1</td></tr>
<tr><td>test</td></tr>
And I don't want to use: (unless there is no alternative)
return array( mysql_fetch_array($data) );
Your problem, as I understand it
You wish to iterate through a mysql resultset in twig, without loading the whole thing into php arrays.
What you have tried
Loading the first row into a nested array. This worked, but of course you only got the first record echoed in twig.
You're looking for a way to fetch the next row from twig, using only the array. This is not possible, because the array that you have has no connection to the mysql result pointer (besides having the data of the first record).
Possible solutions
Note that I have not tested any of the code examples.
Load the whole thing into php
If the resultset is reasonably small, like say below a 100 rows, you can just bite the bullet and load it completely into a nested array and pass that to twig. You'll have no problems iterating over it with a simple {% for %} loop like in your question.
Create a generator[docs]
This would require that you upgrade to at least php 5.5, which introduced this feature. Your code would look something like this:
return array( //I'm assuming this returns data to be passed to twig
"data" => function () use ($result) {
//$result is the returned value of mysql_query
yield mysql_fetch_row($result);
},
);
You can then do {% for row in data %} in your template.
Create an Iterator
On older versions, such as your 5.3.3, generators are not available. But that's only a shortcut to writing classes implementing the \Iterator[docs] interface. This involves some code, but you can create a generic class that you can construct using only a result pointer, and you can either foreach (in php) or for (in twig) over it, just like arrays or generators.
Switch to PDO
Depending on your project size this may be the best option (this is the one I recommend). It is very easy to start using PDO, and when you do a query it returns a \PDOStatement object, which implements \Traversable, meaning you can foreach or {% for %} over it - without writing any wrapper code. This was one of the main reasons why I switched to PDO from mysql_* (the other being prepared statements).
Create a twig extension
Just to mention this one. Probably the most involving (both time and code) solution is to create a while tag in twig, and the possibility to call mysql_fetch_* on a result pointer.

Resources