Timber Wordpress child menu - timber

I am looking for a way to display all child pages of the current page, similar to the wp_page_list function, but in Timber (Twig).
I know I can either add to the context via a query, or simply wrap the worpdress function in a timber function.
Either method I am struggling with and would appreciate some syntax guidance.
Many thanks.

Not sure how ideal this is, but it does the trick
{% for item in menu.get_items %}
{% if item.get_children and post.link == item.url %}
<ul class="jumbo-menu {{ post.slug | replace({'-data':''})}}">
{% for child in item.get_children %}
<li>{{child.title}}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}

Are you trying to display child pages without using a WordPress menu? So without the get_items method? The children of a given page are available via the post object, irrespective of any menu functions.
{% for child in post.children %}
<li>{{ child.title }}</li>
{% endfor %}
This assumes $context['post'] = new TimberPost(); in your controller.

Related

How do I get Child of a Child Page Timber/Twig WordPress

How do I get the Child of a Child Page to display on a .twig template?
Parent Page
— First Sibling
— — Second Sibling
— — — Third Sibling
I am getting the children of the First Sibling with
{% for child in post.children %}
<li class="pb-3">{{ child.title }}</li>
{% endfor %}
How do I go one further deeper? Timber/Twig WordPress.
You could do something like this a Child post is a post and because of that it has children if given
{% for child in post.children %}
<li class="pb-3">{{ child.title }}</li>
{% if child.children|length > 0 %}
{% for child in child.children %}
<li class="pb-3">{{ child.title }}</li>
{% endfor %}
{% endif %}
{% endfor %}
If you are using Timber/Twig, and you're using ACF, you can choose a Post Object of Page, select the title of the page that you are wanting to add as the Post Object, and to grab the child pages you can do something like this:
{% for child in Post(list.page).children %}
<li class="pb-3">{{ child.title }}</li>
{% endfor %}

Timber and ACF how to get sub field object of ACF field group

Using Timber for Wordpress, I'm trying to loop through an ACF field group and get for each sub_field the value and the label.
My ACF field group is named apartment_specs
I can get the values of each sub_field with:
{% for item in post.get_field('apartment_specs') %}
<li>{{ item }}</li>
{% endfor %}
I can get the labels of each sub_field with:
{% for item in post.field_object('apartment_specs').sub_fields %}
<li>{{ item.name }}</li>
{% endfor %}
I can't really get the two things in the same loop.
Is there in Timber anything like the ACF' get_sub_field_object? How'd it work?
You should use get_sub_field_object function.
Something like this might help you:
{% for key,item in fields.contracts %}
{% set object = function('get_sub_field_object', key) %}
{{ dump(object) }}
<li>{{ object.label }}</li>
{% endfor %}
This is a very simple example. For easier usage you can create Timber function or filter.
Thanks #maxim!
I was able to get what I needed by simply using:
{% for key, item in post.get_field('apartment_specs') %}
<li class="{{key}}">{{item}}</li>
{% endfor %}
I'm trying your solution in another more complex situation

What is the difference between include and block in Twig?

I'm trying to make a bootstrap theme for PhileCMS which uses Twig. Right now I'm working on the menu. I've been searching to find out how to make a page active, and I've been seeing stuff about blocks. Right now my index.html looks something like this
{% include 'header.html' %}
<body>
{% include 'nav.html' %}
<div class="container"}
{{ content }}
{% include 'footer.html' %}
My nav.html looks something like this:
<div class="header clearfix">
<nav>
<ul class="nav nav-pills pull-right">
<li role="presentation"><a class="{% if app.request.attributes.get('_route') starts with 'home' %}active{% endif %}">Home</a></li>
<li role="presentation"><a class="{% if app.request.attributes.get('_route') starts with 'about' %}active{% endif %}">About</a></li>
<li role="presentation"><a class="{% if app.request.attributes.get('_route') starts with 'contact' %}active{% endif %}">Contact</a></li>
</ul>
</nav>
<h3 class="text-muted">{{ site_title }}</h3>
</div>
Is this proper coding practice, or should I be doing something with blocks? I don't really understand how blocks work.
You can include whole new template with new blocks. - That is what include do. You inject a template or piece of template defined in other file. So:
{% include 'nav.html' %}
will inject whatever you have put there and it will replace this whole phrase, this line of code with content of nav.html.
On the other hand when you use {% block body %} for example you override this body block which is inherited from parent template. For example:
If you have block named body in base.html.twig and you will inherit from it like this in another template(let's say blog.html.twig):
{% extends 'base.html.twig' %}
and then do this:
{% block body %}
Hello World
{% endblock %}
You will put this hello world inside of body block in base.html.twig.
I hope it's now clear to you.
P.S
If you want to use twig make sure you use twig extension!
If you are asking for best-practices, then as mentioned in the Symfony's Templating documentation:
When building your application, you may choose to follow this method or simply make each page template extend the base application template directly (e.g. {% extends 'base.html.twig' %}). The three-template model is a best-practice method used by vendor bundles so that the base template for a bundle can be easily overridden to properly extend your application's base layout.
The idea behind this is to have:
1- a base template (level 1)
2-A layout template (level 2)
3-An individual template (level 3)
Here is a sample code that illustrates this (originally from the Symfony2) documentation
{# layout.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>Blog Application</h1>
{% block content %}{% endblock %}
{% endblock %}
{# index.html.twig #}
{% extends 'layout.html.twig' %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
p.s: Even tough you wouldn't be dealing with Symfony2, but IMHO the principle should be the same, since we are using the Twig templating engine.

Overwriting a field of AdmingeneratorGeneratorBundle

I am trying to overwrite a field of the AdmingeneratorGeneratorBundle and want to append a link to a certain field. That works quite well following the documentation:
{% extends_admingenerated "MyMainBundle:PageEdit:index.html.twig" %}
{% block form_status %}
{{ parent() }}
Preview
{% endblock %}
What I would need to do now, is to get the real id of my page instead of the static 8, but i could not figure out, what the object is called inside the twig template. Any ideas?
Update:
In my case, as I only need the ID of my page, I can use app.request.attributes.get('pk') to get it in twig. Would be interesting how to get other values tough.
Just use
{% extends_admingenerated "MyMainBundle:PageEdit:index.html.twig" %}
{% block form_status %}
{{ parent() }}
Preview
{% endblock %}
Cedric
The Documentation has been updated.
Thats ho it works:
{% extends_admingenerated "NamespaceYourBundle:List:index.html.twig" %}
{% block list_td_column_title %}
<span style="font-weight:bold">{{ Movie.title }}</span>
{% endblock %}

How to customize a CollectionType() item?

This § of the Symfony2 documentation shows an awesome technique for customizing an individual field. I'm using it a lot but there is one particular Type for which I'm having a hard time doing the customization : the CollectionType() Customizing the collection itself is quite easy, you can do something like this:
{% block _mynamespace_mybundle_mytype_mycollectionfield_row %}
{% if prototype is defined %}
{% set attr = attr|merge({'data-prototype': form_widget(prototype) }) %}
{% endif %}
{% spaceless %}
<ul {{ block('widget_container_attributes') }}>
{% spaceless %}
{{ form_errors(form) }}
{% for child in form %}
<li>
{{form_widget(child)}}
</li>
{% endfor %}
{% endspaceless %}
{{ form_rest(form) }}
</ul>
{% endspaceless %}
{% endblock %}
But how can you customize each element of the collection ? And how can you customize the data-prototype using Twig (the data-prototype is a special attribute used to add new items with js)?
I tried doing something like this (for the data-prototype):
{% block _mynamespace_mybundle_mytype_mycollectionfield_$$name$$_row %}
customization ok!
{% endblock %}
But I get errors, because I don't know how to escape the $
Regarding the items, I tried many things:
{% block _mynamespace_mybundle_mytype_mycollectionfield_item_subfield_row %}
customization ok!
{% endblock %}
{% block _mynamespace_mybundle_mytype_mycollectionfield_element_subfield_row %}
customization ok!
{% endblock %}
None of them work.
I asked the question in symfony's bug tracker, and it seems there is no solution, but a good workaround is creating a custom type for each subfield you want to customize. See this issue

Resources