When I’m trying to pass the information contained in {{posts}}
I cannot retrieve all of it, at least not the post.link
information
{% for post in posts %} <script> var t = JSON.parse('{{post|json_encode(constant('JSON_HEX_APOS'))|e('js')}}') t.link = '{{post.link}}' console.log(t) </script> {% endfor %}
Without manually adding the link
, it doesn’t show up
Why is this happening and how could I workaround this?
EDIT: related https://github.com/timber/timber/issues/1434
Advertisement
Answer
You shouldn’t encode your whole post object. You should encode all the values you need separately.
The link
for your post doesn’t show up, because link
is not a property, but a method of the TimberPost
object. This might be a little bit confusing, because in Twig we use {{ post.link }}
. It looks like it’s a property or maybe an array item. But we could also use {{ post.link() }}
, which is the same as {{ post.link }}
. You can read more about this in the Variables section in Twig for Template Designers.
So what I would do is build a new array with the data you need and encode it to JSON in PHP with wp_json_encode()
.
PHP
$posts_json = []; foreach ( $posts as $post ) { $posts_json[] = wp_json_encode( [ 'title' => $post->title(), 'link' => $post->link(), ] ); } $context['posts_json'] = $posts_json;
By only adding the data you need, you keep the output in the frontend small. Otherwise, you would end up with a lot of data that you will never and that only increases the page size unnecessarily.
And then in Twig, you could do it like this:
{% for post in posts_json %} <script> var t = {{ post }} console.log(t) </script> {% endfor %}