I have an ACF field that allows a choice of post types, these are then going to be put in a carousel. There could be any number as every module on the page is controlled by the admin users.
In the carousel template, I want to be able to get the recent posts for the selected post type. I can to this with:
{% set items = fn('get_posts', {'post_type': 'team' }) %}
Is there a way to do this without calling it as a function? I was thinking along the lines of:
{% set items = Posts(params) %}
Is this possible or is the function call the only/best way?
Thanks
Currently, what you want to do is not possible. You could use Timber::get_posts through the array notation to get an array of Timber posts instead of regular WordPress posts:
{% set items = fn(['Timber\Timber', 'get_posts'], { 'post_type': 'team' }) %}
But in the future, the recommended way to get posts will be to use Timber\PostQuery. In the upcoming version 2 of Timber, we will add a PostQuery function to Twig. This means that you’ll be able to do something like this:
{% for items in PostQuery(params) %}
{# Display item #}
{% endfor }
This would work well for simpler use cases. I’d also recommend what Luckyfella said, it may be better to not have this in Twig at all, but prepare everything in PHP and then pass the items on to the Twig view.
Related
I am trying to create my first Drupal 8 theme. On the frontpage, I want to list all articles with the title, summary, date posted, etc.
I more or less achieved this using views. Basically {{ page.content }} in twig, but found it to be really inflexible and I didn't really get the results that I wanted. What I want to do is just to iterate through all the articles and print each section of that article "manually". For instance:
{% for page in pages %}
{{ page.content.title }}
{{ page.content.datePosted }}
{{ page.content.body }}
{% endfor %}
So that I can have more control of what is happening and not making a lot of configuration in the views module when deploying. What is the best soltuion to achieve this? Thanks!
I recommend to use Views. Configure you view (filter by content type, etc.), you have a lot of parameters to achieve what you need.
Set the view to show "Content" and give it a view mode (you can use the default teaser, full, or create your own view mode). Then you can create a custom template for this :
node--xxxx--teaser.html.twig
In order to know how to name your custom template file, enable Twig Debugging in sites/default/services.yml. Set the debug variable to true. And clear cache. Then, you will see in source code the template name suggestion like this :
<!-- FILE NAME SUGGESTIONS:
* node--1--full.html.twig
* node--1.html.twig
x node--oeuvre--full.html.twig
* node--oeuvre.html.twig
* node--full.html.twig
* node.html.twig
-->
In your twig, you can do that kind of templating :
{{ content.my_field_image[0] }}
<h2>{{ node.title.value }}</h2>
<p>{{ content.body }}</p>
Say I want to show 2 different collection lists(just the titles with links to their relative pages) on 2 different pages in Shopify; is there a way in Shopify that can be done? As far as I can see, either I show all "Collections" on a page or none at all. Is there no option to categorize them so that I can use liquid to only show certain collections?
The only other option to this I found is to hard code those collection menus on the page. But the issue with that is, any new collection I create, I will have to manually add it in to the code if I want to show it.
UPDATE
If you want to display all collections after a certain collection, once you find that handle, just have it parse the rest of them after it finds the handle.
Sorry my liquid is a little rusty so this is pseudo code.
{{ liquidtempvar = 0 }}
{% loop through collections %}
{% if thiscollection.handle == 'firstcollectioniwanttodisplay' %}
{{ liquidtempvar = 1 }}
{% endif %}
{% if liquidtempvar eq 1 %}
{{ loop through this collection and every collection after }}
{{ collection.product.handle }}
{{ endloop }}
{% endif %}
{{ endloop }}
Something like that...
END UPDATE
If you want to display a list of the items in a collection as links, then you would need to parse the collections object in the template of the page where you want to display them.
You would want to use the collection handle to qualify/filter which collections you wanted to display.
Using liquid loop over each collection, if the handle matches the collection you want, loop over the collection and display the links.
If you are looking to do this as a menu through the navigation, I think you can probably do it using query strings in the URL.
collection.next_product
and
collection.prev_product
will return the URL of the next and previous products in the collection.
Collection Navigation
Collection Object Reference
I am desperately trying to render a submenu in symfony-cmf.
Example
Structure:
page1
├─p1-subpage1
├─p1-subpage2
└─p1-subpage3
page2
├─p2-subpage1
└─p2-subpage2
Whenever the current page is somewhere within the page1 hierarchy it should use p1-subpage* to render the menu, when I am within the page2 hierarchy it should use p2-subpage* to render the menu. Technically that means it should set the current item to the parent of the 1st level (if it's not already on it) and render one level of nodes (e.g. knp_menu_render('main', { depth: 1 })).
The problem can be split in two parts:
Rendering a (sub-)menu from a given node
Retrieving the current node
Thoughts and Trials
TWIG: It has been suggested to support rendering submenus as a functionality of the KnpMenu itself, but it hasn't been done. As a workaround registering a twig extension has been provided by someone in the issue. However this extension is based on the getCurrentItem Method which has been removed with KNP-Menu 2.0. Although the cmf currently uses v1.1 of the knp-menubundle, this is going to change soon
TWIG: The CnertaBreadcrumbBundle would bring back this functionality, but depends on KNP-Menu 2.0 as well.
TWIG: Using a hack similar as suggested here. It checks the current URI, counts the number of slashes and decides based on that what to use. This could probably work. Problem here: I don't have cmfMainContent variable defined, nor can I find anything similar in my {{ dump() }} (nothing containig a menu either).
RouteVoter: The cmf itself has some MenuVoters itself, which are well documented what they are, but not how to use them. I don't think that there is any way to access that functionality whithin twig nor do I know how to intercept the menu building.
Thanks for any help.
have a look here for an example of using voters to make decision about what to highlight:
https://github.com/dbu/conference-tutorial-1.0/pull/20
aside from this we are making good progress on a KnpMenu 2.x compatible version of our MenuBundle but it might be until January until we make a stable release of it (but we might make one earlier .. we will see):
https://github.com/symfony-cmf/MenuBundle/pull/214
I have created a bundle yesterday for my own, similiar, use case.
However as all of my pages share the same route you might need to adapt it quite a bit.
I still think you might find some inspiration, especially for the second part of your problem.
My Bundle:
https://github.com/burki94/RecursiveMenuBundle/blob/master/README.md
AbstractRecursiveBuilder: https://github.com/burki94/RecursiveMenuBundle/blob/master/Menu/AbstractRecursiveBuilder.php:
This is not really a solution because it's not following my requirements of being compatible with KnpMenu 2.*. But this deprecated solution is easy:
{% set currentItem = knp_menu_get('main').currentItem %}
{% if currentItem is not null %}
{% if currentItem.getLevel() == 1 %}
{% set main = currentItem %}
{% else %}
{% set main = currentItem.getParent() %}
{% endif %}
{{ knp_menu_render(main, { 'template': 'ComBundle:Default:left_menu.html.twig', 'currentClass': 'uk-active' }) }}
{% endif %}
After hours of searching, I found a solution how to apply themes to individual fields for collection types here: symfony2: Applying theme to individual field for collection type (thanks #TroodoN-Mike).
So a custom theme for a collection type could be:
{% block _author_tags_entry_label %}
{# ... #}
{% endblock %}
The word "entry" replaces the row index, which works fine, but I need the Row index inside the custom block, something like {{ entry }}. Any hints?
Thanks
Chris
Ok, I found the solution. I wasn't aware of the fact, that you can pass custom variables to the form theme like this:
{{ form_row(form.field, {'customVariable': 'anyValue'}) }}
I am (still) trying to introduce http://xoxco.com/clickable/jquery-tags-input into a dedicated bundle. As far, I have a type as a child of text and a data transformer that converts comma-separated strings into arrays of Objects and vice versa.
Now I want to decorate the text field with the JQuery code linked above. As far as I understand, I have to define a block like
{% block manytomanycomboselector_widget %}
{% spaceless %}
{{ block('text_widget') }}
<script>
$(function(){
$("#{{ id }}").tagsInput();
});
</script>
{% endspaceless %}
{% endblock manytomanycomboselector_widget %}
in [MyTypeBundle]Resources/views/Form/fields.html.twig
Now, both the documentation and the answers for this question at StackOverflow state that I have to reference fields.html.twig somewhere either in the template that uses the form or in app/, but this doesn't seem to be necessarily for other field-type bundles, though I cannot see in their code why.
What do I have to configure inside the bundle besides this block in this file?
Also I didn't get where I have to put the css and js requirements for the header and how I deal with general requirements like jQuery itself.
I have the same issue & I resolve it by merging my field template in the twig.form.resources parameter.
So, in the DI extension of my bundle (MyBundle/DependencyInjection/MyBundleExtension.php), I add:
$container->setParameter('twig.form.resources', array_merge(
array('MyBundle:Form:field_widget.html.twig'),
$container->getParameter('twig.form.resources')
));
Be aware, your bundle must be registered after the TwigBundle in your AppKernel.
EDIT:
A form field is not linked to any JS or CSS. So, IMO, you have 2 solutions.
Firstly, you directly wrap your JS & CSS in your field template and your bundle stays stand-alone.
Secondly, you instruct final users that they need to include manually some JSS & CSS each time they use your field type.
The IoFormBundle & GenemuFormBundle uses the second solution like explain in their documentation.