Get parent of term - timber

I might have missed it in the Timber Docs but is there a possibility to get the parent terms of a given taxonomy?

two methods depending on Twig vs. PHP and what exactly you're looking to do.
Consider a post which as been assigned a category of "Politics" (which is a child category of "News")
Example 1: Get a parent term in a Twig file
<p>Find more posts in {{ post.category.name }} and {{ post.category.parent.name }}</p>
<!--- outputs as ... --->
<p>Find more posts in Politics and News</p>
Example 2: Get the top-level terms from a taxonomy
$context['parent_categories'] = Timber::get_terms(array('taxonomy' => 'category', 'parent' => 0));
Use in Twig like...
Top-level categories for my site are...
{% for term in parent_categories %}
<li>{{ term.name }}</li>
{% endfor %}
<!-- Outputs as... -->
<li>News</li>
<li>Sports</li>
<li>Opinion</li>

Let's say you are trying to use the parent of a category in a twig view. That was the case I tried to solve when stumbling upon this post.
In category.php you can get the parent category by getting the parent category ID of the currently viewed category:
$category = new TimberTerm();
$context['category'] = $category;
if ($category->parent) {
$context['parent_category'] = new TimberTerm($category->parent);
}
$category->parent corresponds to the ID of the parent category. It is null if the category doesn't have a parent. You can then use the resulting category in your template.
<a class="category_{{parent_category.slug|lower}}" href="{{parent_category.link}}">
{{parent_category.title}}
</a>

Related

Render as multiple bagdes with an AssociationField in EasyAdmin

I got an issue with that question.
I've make this to render a "string" for a ManyToMany relation :
->formatValue(function ($value, $entity) {
return implode(",",$entity->getCategories()->toArray());
})
and it works pretty good ! But I've a question !
How can I render many badges in Index ? Because this method render one unique badge with "Value 1, Value 2"... And I want to see 2 badges, one with "Value 1" and one other with "Value 2" in the same line.
Someone know how to do that ?
I hope my question is clear.
NoƩ
You need to create a custom template that does it.
Use easy admin ->setTemplatePath() method to override your field template.
Example:
->setTemplatePath('fields/yourEntity/categories.html.twig')
And your twig template loop through each values to render it with multiple badges:
{% for value in field.value %}
<span class="badge badge-info">
{{ value }}
</span>
{% else %}
<span class="badge badge-secondary">
None
</span>
{% endfor %}
You should get a badge for each categories, you could also customize how to render those badge (with different colors ?) by using {{ value }} and any of its method to render it differently.

Get custom post type label instead of name - WordPress + Timber

I created 3 custom post types in WordPress : dissertation, subject-imposed, subject-free
In each custom post type the user is allowed to create only ONE post.
I created a menu composed with those three custom post types which allow to switch from post to another from the same user.
But I got a problem. The menu item display the name of the post type and not the label.
I got : DISSERTATION / SUBJECT-IMPOSED / SUBJECT FREE
And I would like the label (labels are in french) : MEMOIRE / SUJET IMPOSE / SUJET LIBRE
How can I get the label instead ? Thank you in advance.
In single.php :
$post_queried = get_queried_object();
$context['post_type_current'] = get_post_type_object(get_post_type($post_queried));
$get_post_current_user = get_posts( array(
'author' => $current_user->ID,
'post_type' => array('dissertation', 'subject-imposed', 'subject-free'),
));
$context['list_posts_current_user'] = $get_post_current_user;
In single.twig :
<ul class="menu-secondary__list">
{% for item in list_posts_current_user %}
{% set active = (post_type_current.name == item.post_type) ? 'active' : '' %}
<li class="menu-secondary__item">{{ item.post_type }}</li>
{% endfor %}
</ul>
Two steps to fix this one, first ...
Convert into an array of Timber\Posts
$get_post_current_user is an array of WP_Posts we need to convert these to Timber\Posts in order to interact with Timber's methods. Many ways to do this, but the easiest ...
{% for item in Post(list_posts_current_user) %}
Access the type method:
Now you can use the Post::type() method in your Twig template and access the labels:
{{ item.type.labels.name }}
The {{ item.type }} property will give you everything from here:
https://developer.wordpress.org/reference/functions/get_post_type_object/

Grouped view for datasets in sonata admin list view

I am wondering if there is a easy way to implement a group view for datasets grouped by its "root" element.
Lets say i have a "person" entity. Many persons can have a "root" person they belong to. So i would add a reference to the person entity itself.
Now i don't want to show every person in the flat list view. Instead i want to display only every root-person and with clicking this dataset a accordion opens with the subordinated person entities ... how is that possible?
It would also be fine without a accordion, it can be enough if the subordinated entities are indented a bit ...
Can somebody give me a clue which approach i should follow? I would be the if i can reuse the most of the sonata admin functionality, especially the templates ...
Thanks
Was solving something similar in past. Got that working in few steps:
Override first field in your Datagrid
With this code you say that you want use my_custom_template.html.twig to render this field (in your admin class).
protected function configureListFields(ListMapper $list)
{
$list->add('yourFirstField', null, ['template' => 'my_custom_template.html.twig'])
}
Enable filtering for yourFirstField
Prepare filtering for your parent field (in your admin class)
protected function configureDatagridFilters(DatagridMapper $filter)
{
$filter->add('parent');
}
Write custom template for first field
Then in your custom template you use to set up filter value on click on link.
{% extends 'SonataAdminBundle:CRUD:base_list_field.html.twig' %}
{% block field %}
{% if object.isRoot %}
{{ object.name }}
{% else %}
{{ object.name }}
{% endif %}
{% endblock %}
Later on you can override break breadcrumbs builder service (https://sonata-project.org/bundles/admin/master/doc/reference/breadcrumbs.html) and create nice path in breadcrumbs, so user can go navigate.

Display dynamically informations in a Symfony layout

I have a layout included in another one that display my menu. The labels of my menu items need to be dynamic (like the unread messages number of a mailbox). Then I did this :
My orders
(
{{ render(controller('MyController', {'etat':2})) }}
<span style="color:red">with {{ render(controller('MyController', {'etat':2})) }} in late</span>
)
I would like to display labels according to the number that return my controller. I don't know how to get it in a variable.
When rendering your template in your controller
return $this->render('twig_template_name.html.twig', array('variable_name' => $variable);
you pass a variable to the twig template in the array of options as I showed. Your code
{{ path('mypath',{'etat': '2' }) }}
prints a path defined in the routing.yml under the 'mypath' section and ends up adding a GET request variable to the link ('?etat=2'), if 'mypath' showed an absolute route 'www.website.com/yourpath',
{{ path('mypath',{'etat': '2' }) }} would produce 'www.website.com/yourpath?etat=2', which would send your controller for a route /yourpath/{etat} a variable etat with a value of 2 so all you need to do now is change 2 with an actual dynamic value which you receive from another controller.
I am not sure what etat is but lets say it's an article and it has it's id, you have a blog page with lots of articles and the controller that prints them all out sends an array of articles to the twig template, on your twig template you do something like:
{% foreach article in articles %}
{{ article.title }}
{{ article.story }}
read more
{% endforeach %}
And you end up something like:
Catchy Title
Awesome story about code without bugs and where deadlines depend on how creative and well designed and implemented the solutions are
[read more]
and you ofcourse click on "read more" and end up on the url ~/article/2 because the article had an id of 2, your controller for that url receives a variable id in the request, you do a $id = $_GET['id']; and grab the article from the repository and send it to the template.
Hopefully this answered your question, I am very tiered so forgive me if i was confusing which I surely was.

How can I print Google Books api description?

Hie I am trying to get the synopsis and other items like author and published date printed. But I am Able to achieve this only with certain search terms, an error occurs with other words or terms
Key "description" for array with keys "title, subtitle, authors, publishedDate, industryIdentifiers, readingModes, pageCount, printType, categories, maturityRating, allowAnonLogging, contentVersion, imageLinks, language, previewLink, infoLink, canonicalVolumeLink" does not exist.
I am using symfony and twig. this is what the twig file looks like :
{% for item in items %}
<article>
<img src="{{ item.volumeInfo.imageLinks.thumbnail}}"/>
<h4>{{ item.volumeInfo.title}}</h4>
{{ item.volumeInfo.description }}
<strong> {{ item.volumeInfo.publishedDate }}</strong><br/>
<b>{{ item.volumeInfo.authors | join }}</b>
</article>
What am I doing wrong? why does this work only sometimes ? how can I make it work correctly all the time?
class GoogleBooksController extends Controller
{
public function getVolumeAction($title)
{
$client =new client();
$response = $client- >get("https://www.googleapis.com/books/v1/volumes?q=$title");
$data=$response->json();
$items=$data['items'];
return $this->render('BookReviewBundle:GoogleBooks:volume.html.twig', array('items'=>$items
// ...
)); }
Thanks
I belive the description field is not mandatory, so you can do follow
{% if item.volumeInfo.description is defined %}
{{ item.volumeInfo.description }}
{% endif %}

Resources