Contributors page with dropdown to show authored articles, instead of separate url

Hi there, I have seen a few helpful articles about how to create an author/contributor list, but they ended up being dead end, since we don’t want to have to enter the email or a password for each author (this would add a lot of unnecessary time for the admin of the site to have to input):

SO, what I want to do is slightly different, create a contributor page with a dropdown for each author, where you can view their bio + articles they authored, vey much like this:

Any tips on which cookbook or instruction page would lead me to this kind of contributor list?

As always, thank you!

Such a list is easy enough to create. Nevertheless the question is: where do your authors come from? Are authors Kirby users?

Basically, it’s a new website for a magazine so the authors are people who have contributed to the printed magazine over the years (so they are not authors on the website, but authors from the printed mag).

I suppose I am not sure the best way to input these authors/contributors, or how to structure this data.

There will be about 100 authors to input. Either I can input them all at once as users, then select them from the list as authors when I input the articles. OR I can input them in one by one via their respective article pages. IF I use the author/user method, I would want to make it so that I don’t have to input password or email, since we don’t need that info for them, just their name + 1-sentence bio.

All guidance appreciated, thanks!

Ok, then creating users is not the way to go. Maybe then create this users as simple pages with the users names as title and a field for their bio. Then query the users in articles (select/multiselect) field.

Ok, this is sounding good. Not sure what you mean though. Create a page template for each author, or a page where I’d add all the authors into one page?

I created a structure for the contributors page where the admin can add all the contributors. And then a query on the article pages so that the admin can select which author wrote the piece.

BUT now I need to figure out how to list all articles written by each person on my contributors collection page, I want each persons name to have their articles listed below their name.

this is what I have in my contributors template:

templates/contributors.php

<?php snippet('header') ?>


    <h1><?= $page->title() ?></h1>
        
    <?php if ($page->info()->isNotEmpty()): ?>    
            <p><?= $page->info() ?></p>
    <?php endif ?>
        
    <?php if ($page->contributors()->isNotEmpty()): ?>    
       
    <div>
                 
         <?php $items = $page->contributors()->toStructure(); foreach ($items as $item): ?>
            
            
         <div class="contributor-toggle">
            <div class="title"><span><?= $item->name()->html() ?></span></div>
            <div class="content">
                <p><span><?= $item->bio()->html() ?></span>
                <span><?= $item->location()->html() ?></span></p>
                <ul>
                    <?php foreach($articles->filterBy('contributors', $page->uid()) as $article): ?>
                    <li><a href="<?php echo $article->url() ?>"><?php echo $article->title() ?></a></li>
                    <?php endforeach ?>
                </ul>
             </div>
        </div>
<?php endforeach ?>
    </div>
<?php endif ?>

<?php snippet('footer') ?>

this is what I have in my contributors page blueprint

blueprints/contributors.yml

contributors:
        label: Contributors
        type: structure
        fields:
          name:
            label: Name
            type: text
            width: 1/3
          bio:
            label: Bio
            type: text
            width: 1/3
          location:
            label: Location
            type: text
            width: 1/3

this is what I have in my article template:

templates/article.php

<p>by <?= $page->author()->html() ?></p>

this is what I have in my article blueprint

blueprints/article.yml

fields:
      author:
        label: Author
        type: select
        options: query
        query: 
          fetch: site.find("contributors").contributors.toStructure
          text: "{{ structureItem.name }}"
          value: "{{ structureItem.name }}"

Hope that makes sense, or is enough info to go off.

Your field in the article pages is called author not contributor. And what you store in there is the name of the author, so you have to alse filter by $item->name() not $page->uid().

<?php foreach($articles->filterBy('author', $item->name()) as $article): ?>

Thanks Sonja, I think I’m so close! I tried pasting the above code into my contributors.php template page, but still not printing the url’s to the articles attributed to each author below their names. Is this what you meant?

“Contributors” is the label I use for the collection page of all authors.
"Author’ is the label I use for the attribution on individual article pages.
(reminder, this is a website for an online magazine)

    <?php if ($page->contributors()->isNotEmpty()): ?>    
       
    <div>
                 
         <?php $items = $page->contributors()->toStructure(); foreach ($items as $item): ?>
        
         <div class="contributor-toggle">
            <div class="title"><span><?= $item->name()->html() ?></span></div>
            <div class="content">
                <p><span><?= $item->bio()->html() ?></span>
                <span><?= $item->location()->html() ?></span></p>
                <ul>
                    <?php foreach($articles->filterBy('contributors', $item->name()) as $article): ?>
                        <li><a href="<?php echo $article->url() ?>"><?php echo $article->title() ?></a></li>
                    <?php endforeach ?>
                </ul>
             </div>
        </div>
<?php endforeach ?>
    </div>
<?php endif ?>

You are still filtering by the contributors field, whereas in your article.yml the field is called author.

So again:

<?php foreach($articles->filterBy('author', $item->name()) as $article): ?>

Hi thanks, I did try that, and a few other things, but it’s still not printing anything out on the contributors page front end. I assigned each of the authors i’ve input on the contributors list to at least one article, and still nothing shows up. hmmm.

Hm, that’s weird. Maybe send me the zipped project and I’ll take a look.

Awesome awesome. Here it is!

where i’m trying to print the linked articles associated to each author like this magazine site for example:
templates/contributors.php

where i have the author attribution in the individual articles:
blueprints/archiveEntry

Thanks!

ACTUALLY, SORRY. I should use the multiselect for my author selection on the individual archiveEntry page! (I realized the list would get to be 100 contributors which is unwieldy for a dropdown list) I can resend the package if you haven’t already opened it?

author:
        label: Author
        type: multiselect
        min: 1
        max: 3
        options: query
        query: site.contributors.toStructure
          fetch: site.find("contributors").contributors.toStructure
          text: "{{ structureItem.name }}"
          value: "{{ structureItem.name }}"

No, go ahead!

Voila

The problem is that $articles is not defined.

<?php if ($page->contributors()->isNotEmpty()) : ?>
  <div>
    <?php
    $items = $page->contributors()->toStructure()->sortBy('name', 'asc');
    foreach ($items as $item) : ?>

      <div class="contributor-toggle">
        <div class="title"><span><?= $item->name()->html() ?></span></div>
        <div class="content">
          <p><span><?= $item->bio()->html() ?></span>,
            <span><?= $item->location()->html() ?></span>
          </p>
          <?php if ($archive = page('archive')) : ?>
            <?php $articles = $archive->children()->listed()->filterBy('author', $item->name()->value(), ',');
            ?>
            <ul>
              <?php foreach ($articles as $article) : ?>
                <li><a href="<?php echo $article->url() ?>"><?php echo $article->title() ?></a></li>
              <?php endforeach ?>
            </ul>
          <?php endif; ?>
        </div>
      </div>
    <?php endforeach ?>
  </div>
<?php endif ?>

Since you now have a multiselect field, the filter must be slightly changed as well, see above.

And you don’t get an error message because debugging is not enabled in your config.php.

Make sure that all config options are within a single return array, currently you have multiple return statements in your config, and everything after the first return statement will be ignored. PHP: return - Manual

return [
  'debug' => true,
  'thumbs' => [
    'presets' => [
      'default' => ['width' => 1024, 'quality' => 80],
      'blurred' => ['blur' => true]
    ]
  ],
  'blocks' => [
    'fieldsets' => [
      'text' => [
        'label' => 'Text',
        'type' => 'group',
        'fieldsets' => [
          'text',
          'heading'
        ]
      ],
      'media' => [
        'label' => 'Media',
        'type' => 'group',
        'fieldsets' => [
          'image',
          'video'
        ]
      ]
    ]
  ]
];

Yes!!! It works. phew! Thank you. thank you.

Darn, only thing is, I also have other sections with magazine content, for example, there’s a section called the lexicon where people contribute entries, so what you wrote here only pulls from the archive section, I take it and if i want to include sources from elsewhere on the site (from another section as well), would that be an entirely different story?

Figured it out. got it thanks. added that page to the formula.

You can also get children from multiple parent pages

$articles = $site->find('archive', 'press', 'lexicon')->children()->listed()->filterBy('author', $item->name()->value(), ',');