Nested Treemenu

I’m using the treemenu snippet and it works almost exactly as I would like.

So it shows my home page, my about page and the 2 authors under the about page.

I have an unlisted page of posts(books) as the posts are visible on my home page.

If I make the page books visible I see the posts in the menu but also the page which is not really what I want.

I would love if I could show the posts under the author names.

Any ideas?

Hm, you could do that either manually (using if statements), or you use a page model for the author pages where you redefine the children() method for authors (setting the posts that belong to each author as children).

In /site/models/author.php (assuming the blueprint for the author pages is called author.

class AuthorPage extends Page {
 
    public function children() {
       return page('books')->children()->listed()->filterBy('author', $this->id()); // the right method to use depends on what you store in the author field
    }
}

If my page was team-member.php would the code then be this?

class AuthorPage extends Page {

public function children() {
   return page('books')->children()->listed()->filterBy('team-member', $this->id()); // the right method to use depends on what you store in the author field
}

}

No, the class name must be the same as template name Team_MemberPage or TeamMemberPage or something like that, forgot what was the right way to deal mit the dash in the template name.

Hmmm. I must have organized my templates weird but its not working.

Gonna attempt with if statements.

Thanks though.

Looks as if you just have to leave out the dash:

class TeammemberPage extends Page. {
  // methods
}

So I got it to work using a model but two things are happening 1. The posts are getting the li class depth-2 applied same as their parent above and both parents are getting the same posts displayed and I can’t seem to figure out how to narrow the code so it only shows the appropriate posts under each author.

What exactly is stored in the team-member field. What sort of field are you using? A pages field?

This is my team-member page

title: Team
    preset: page
    icon: user
    pages: false
    files: false

status:
  draft: true
  listed: true

fields:
  text:
    label: Text
    type: textarea
    size: medium
sidebar:
  image:
    extends: sections/image
    headline: Profile Picture

This is my about page
title: About Us
extends: layouts/about

icon: 😱

options:
  status:
    draft:
      label: Draft
      text: The book is still in draft mode. It can only be seen by editors with panel access.
    unlisted:
      label: In Review
      text: The book is online and can be visited with the direct URL. The team must still give the final go to publish it.
    listed:
      label: Published
      text: The book is online and listed in the blog
  delete: false

and this is my about layout
tabs:

  users:
    label: Users
    preset: pages
    drafts:
      headline: New User
      info: "{{ page.position }}"
      template: team-member
    listed:
      headline: User
      width: 1/4
      info: "{{ page.position }}"
      template: team-member
      image:
        ratio: 1/1
        cover: true

  content:
    label: Content
    preset: pages
    pages: false
    width: 2/3
    fields:
        headline:
          label: Title
          type: text
        description:
          label: About
          type: textarea
          buttons: false
          size: small

I must admit that I don’t understand the underlying structure yet. Could you maybe send me the project as a zip file?

I see what your problem is:

  • you have an about page with author subpages and also user accounts with the same authors
  • in your book.yml you have an author users field where you store a relation to a user, not a relation to the authors in the about page.

This setup creates duplicate content for no obvious reason. Also, the filtering doesn’t work for several reason, one of them being that there is no relation between a team member page and the user of the same name. It would make more sense if you would either have only users or only authors.

I think you should first decide if you want author pages or if you want to use Kirby’s user system for your authors.

If you want to use the team member pages, do not use a users field in your book.yml blueprint but a pages field that queries the team members.

I tried to implement this but am running into a problem with the model causing a bad gateway error now.

Ah.

I’ll look into that. Thanks!

If you change your book.yml blueprint to using a pages field, you can then do this in your model:

<?php
class TeammemberPage extends Page {
   
   public function children() {
      return page('books')->children()->listed()->filter(function($child) {
         return $child->author()->yaml()[0] == $this->id();
      }); 
   }

}

(Couldn’t find a better way then using yaml() for the moment.

Book.yml:

        author:
          label: Name
          type: pages
          query: kirby.page('about').children.listed
          multiple: false

The problem with the depth happens because the depth of these books pages is 2 (they are not real children of the authors). You can do either of this:

  • ignore
  • add +1 to the depth using an if statement
  • create a page model for the book page

Awesome!

Thanks so much.

I ended up switching to using Kirby’s user system.

It seemed to tidy things up. So I’m just editing the about page right now.

On a side note, I just discovered this:

<h4>Designed by <?= $page->author()->toUser()->name() ?></h4>

Never call a method directly without first checking if the object exists (this does not apply to this example but in general).

<h4>Designed by <?= $user = $page->author()->toUser() ? $user->name(): '' ?></h4>

Or in this case better with an if statement, because you don’t want to print Designed by if it is not designed by anyone:

<?php if ($user = $page->author()->toUser()): ?>
<h4>Designed by <?= $user->name(): '' ?></h4>
<?php endif ?>

Oh, and one more thing: You are still on 3.0.0, make sure to update to the latest version.

Will do.

If I want to use the kirby user system can I still accomplish my goal of having the user listed and then the posts under them.

I’m thinking that it makes more sense to have them as a drop down menu and write it manually than trying to use the treemenu.

Thoughts?

Yes, you could create a page model for the about page, where you return the users as children (similar to what we’ve done above. The for each user, you can display the books that belong to them.

Awesome.

Thank again!

Will try that.

So I’ve gotten the book titles to show up. Using this.

<?php

class AboutPage extends Page {
 
   public function children() {
      return page('books')->children()->listed()->filterBy('users', $this->name()); // the right method to use depends on what you store in the author field
   }
}

And I know that

$users = $kirby->users();

Will get me the users on the site. But for the life of me can’t combine the 2 concepts.