Blueprint with select dropdown generated from tags?

Is it possible to create a Blueprint select dropdown menu that has a list of all tags used in children pages?

  tag:
    label: Tag name
    type: select
    options: query
    query: 
        value: '{{tags}}'
        text: '{{tags}}'

This just gives me a list of all of the tags fields but they are not sorted individual tags.

I think there is not such an option atm.
Also it would open up some questions: What if your tags field isn’t actually called ‘tags’? What if you use a different separator than ‘,’?

You could create a custom select field that gets all tags from the child pages, maybe similar to a categories field I made for one of my projects:

<?php

class CategoryField extends SelectField {

  public function __construct() {
    $this->type    = 'text';
    $this->icon    = 'chevron-down';
    $this->label   = 'Categories';
    $this->options = array();

    foreach(kirby()->site()->categories()->split() as $category) {
      
        $this->options[$category] = $category;
      
    }
  }
}

Where would you set this up? /site/plugins/methods.php? or…

That needs to go into /site/fields, in this case into a folder “category”, because that is the name of the field. If you change the name of the field, you also need to change its folder name.

This is kind of a duplicate of this topic. It might become an official feature in the future.

@lukasbestle: You are right, there are, in fact, a few related topics, e.g. querying a structure field. That’s why an official feature would be great. But unfortunately, we cannot always sit and wait for a feature if we have to get a project out into the world :wink:

That’s definitely true. :slightly_smiling:
I was just pointing out that this feature request is known. Your temporary solution looks good.

1 Like

Has been added to the develop branch - will be included in the next release: https://github.com/getkirby/panel/pull/746

Hi,
I’ve tried to use your example to fetch all the tags of all the site pages, but I’m struggling to traverse all the pages of the site:
foreach(kirby()->site()->tags()->split() as $allmytags)
return only the tags from the ‘site.txt’ file

foreach(kirby()->site()->pages()->tags()->split() as $allmytags)
return a null error

foreach(kirby()->site()->page()->tags()->split() as $allmytags)
return only the ‘home.txt’ content (which is a starterkit content for now)

How can I traverse all the pages of the site within a custom select field in order to fetch all the fields tags ?

Thanks for your help

maybe with $page->index()
https://getkirby.com/docs/cheatsheet/page/index

That would be $site->index()

why not use a route to generate a dynamic source json?

Sorry, it’s been a while, but I am still looking for a way with select / multiselect (using @distantnative’s plugin) fields to choose from all tags there are. Any suggestions as of 11/17?

Thanks very much and sorry for reviving this old post, but posting a duplicate would be worse :wink:

Check out this plugin: https://github.com/rasteiner/controlledlist
But does not work with multiselect

For multiselect, you would have to use the JSON API.

So, that would be generating a JSON array and populating it with all tags on the page ( something like this: foreach ($page->index()->tags()->split as $globalTags), right? So, basically for tags that would ‘only’ be their title, or am I mistaken?

// Edit: While I’m on it: Is it possible to (automatically) create a subpage for each tag, with a URL like example.com/tags/individual-tag … I don’t especially like the tag:individual-tag structure from the docs

To fetch all tags use the pluck() method.

I wouldn’t create pages per tag but rather use a route that returns the results per tag.

1 Like

Like so?

c::set('routes', array(
  array(
    'pattern' => '(:any):(:any)',
    'action'  => function($tag, $uid) {

      // search for the article
      $page = page($tag . '/' . $uid);

      // redirect to the article or the error page
      go($page ? $page->url() : 'error');

    }
  )
));

? Sorry I am so bad at routing …

No, you can’t use parameters in the route, that will be ignored, this should work the other way round, i.e. the route pattern should be the URL that you want to have, like tags/some_tag and then the action returns whatever you want to return from that route, i.e. a filtered collection.

So, it’d be more like this:

c::set('routes', array(
  array(
    'pattern' => 'tags/(:any)',
    'action'  => function($tag) {

      // search for the article
      $page = page('tag:' . $tag);

      // redirect to the article or the error page
      go($page ? $page->url() : 'error');

    }
  )
));

??