Passing a variable to change layout

I have a collection page in folder Books1, together with some child pages representing books:

title: Books1
content:
    items: '@self.children'
layout: style1

The children are displayed using template display-one-book.html.twig.

I have a second folder Books2, which has a collection page for listing the books in folder Books1:

title: Books2
content:
    items:
        '@page': '/Books'
layout: style2

I want the book information to be rendered differently when approached via the menu item Books2.

As far as I can see the display template display-one-book.html.twig has to be used for both Books1 and Books2, but presumably it is possible to control the layout by passing a variable. I have therefore introduced the variable layout, as you can see, together with a test in the template:

{% if page.parent.header.layout == 'style1' %}
...

Unfortunately, I find that the variable layout is always set to ‘style1’, regardless of whether the approach is made via Books1 or Books2. I tried using {{ page.referrer.header.layout }} but that didn’t seem to have a value.

Can you tell me please how can I arrange for Books2 to use a different layout?

page.referrer does not exist afaik, the page.parent approach should work. Try dumping its value to the debug bar using {{dump(page.parent.header)}} and see why you cannot reference it. Is cache disabled?

@flaviocopes Thanks. {{ dump(page.parent.header) }} produces no output. I don’t know how to disable the cache (I’ve lots to learn) but I deleted the cache folder and tried again; still no output.

If does not produce output, it prints to the debug bar. Disable cache by setting it in the Admin system configuration, or in system.yaml

OK, thanks Flaviocopes. I’ve opened /Applications/MAMP/htdocs/user/config/system.yaml and set cache.enabled to false but a cache folder still appears.

The debug bar shows the same info whether I approach via Books1 or Books2:

#104
  +"title": "Books"
  +"content": array:1 [
    "items" => "@self.children"
  ]
  +"layout": "style1"

Also, I notice that even when I approach via the menu item Books2, after a click on a book title to get the details, the highlighted item in the menu bar shifts from Books2 to Books1.

Grav seems to change context completely as soon as the template display-one-book.html.twig is invoked.

Any further thoughts?

The cache folder will still be created for images, but pages content will not be cached if cache is disabled.

I read the first explanation too fast. I thought you had 2 folders structures. But instead you’re in both cases referencing the pages inside pages/Books1, and the parent will always be that. Not sure how to pass a value, if not by modifying the collection page template and pass that value to the child template.

I’d be pleased if I could find another way to do it, but at present it seems that I have to reference the pages inside pages/Books1 unless I’m going to have a second copy of the data, which is not at all DRY.

In general, what I’m looking for is to have one set of data and more than one view of that data: eg arranged alphabetically in one view, by date in another view, by locality in a third view. All suggestions gratefully received!

Anyway, many thanks for your help - at least I’ve learnt about caching and the debug bar.

You can create a book1.html.twig template and inside it, in the collection loop, pass a value like

{% for child in collection %}
    {% include 'partials/display-one-book.html.twig' with {'layout':'style1', 'page':child} %}
{% endfor %}

a book2.html.twig that passes a second style, and so on. And reference the layout variable in the partials/display-one-book.html.twig template.

Unfortunately I don’t think I can see how to make that work. The collection loop in the book1 template, and likewise the loop in the book2 template, displays a link using child.url:

{% for child in page.collection %}
	<li><a href="{{ child.url }}">{{ child.title }}</a> {{ child.header.author }}</li>

When the link is clicked, Grav goes to the URL of the book, which is in the Books1 folder, so that becomes the context.

It occurred to me that I can pass a parameter in the URL, like this:

{{ child.url }}?style=style1

That works fine for generating the URL query string. But I haven’t managed to retrieve the parameter in the template display-one-book.html.twig; I used

{{ dump (  app.request.query.get('style')  ) }}

but it seems to be null.

So now my question seems to have become, how can i retrieve a query string parameter in Twig?

rather than using query use a param, which is nicer looking:

{{ child.url }}/style:style1

Then you can retrieve that with:

{{ dump(uri.param('style')) }}

BTW, what you had before will work also, but you need this syntax:

{{ dump(uri.query('style')) }}

Yup, bingo yet again. Thank you @rhuckster and @flaviocopes for your time and help!