Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

Forms & Blueprints

Set Category and Tag (Taxonomies) as required

Solved by pamtbaau View solution

Started by Phillip 4 years ago · 16 replies · 1088 views
4 years ago

Hi!
I've been using Grav for a month now and I'm becoming a bigger fan from day to day.
Since a few days I started playing around with Blueprints to override the default behavior of some fields in the admin panel.
My current goal is to set both taxonomy fields ("Category" and "Tag") as required (indicated by a red star next to the text field) for pages of type "Item".

Currently, my blueprint file looks like this:

YAML
extends@: item

form:
  fields:
    tabs:
      fields:
        options:
          fields:
            taxonomies:
              fields:
                header.taxonomy:
                  validate:
                    required: true

But this validation becomes true when "Category" or "Tag" is filled in. I am looking for a way to set both fields as required.
Does anyone know of a way to do this?

Thanks a lot, Phillip

4 years ago
YAML
header.taxonomy.author:
              ordering@: header.title
              type: select
              label: Autor
              size: medium
              data-options@: ['\placeOfMyAuthorsList']
              options:
                '': ''
              validate:
                required: true

Thats how I manage to have Author as required.

ordering@: header.title moves Author select field to Content tab

hope this will help

👍 1
4 years ago

Hi,
thank you very much for your answer, but unfortunately it does not bring me any further.
I want to use the two fields "Category" and "Tag" and not create my own. Overwriting the two fields with custom headings is unfortunately not an option either, as I want to use the "Taxonomy List" plugin for example. This needs entries in the taxonomy map.
Or maybe I misunderstood your answer?

4 years ago
YAML
            header.taxonomy.category:
              type: select
              label: Category
              multiple: true
              array: true
              selectize:
                create: true
              options:
                  - Option1
                  - Option2
                  - Option3

            header.taxonomy.tag:
              type: select
              label: Tag
              multiple: true
              array: true
              selectize:
                create: true
              options:
                  - Option1
                  - Option2
                  - Option3

            taxonomies:
              replace@: true

Just adjust with your blueprint. Dont forget that in admin settings U need to have category and tag in taxonomies field

4 years ago
YAML
             validate:
                required: true

Forgot that U want to have them required - just add this on each and you will set both fields as required

4 years ago

Hello,
your answer goes in the right direction, but is still not quite what I want.
In your example, the user can select one of three static values ("Option 1", "Option 2", "Option 3"). However, I want the user to be able to select the "Category" and "Tag" tags previously created on other pages - that is, the default behavior of the Taxonomy tags.
When I create a new tag in one of the text fields you created, the tags don't appear in the dropdown menu when another page is created - only the three static values are displayed.
I think something like a "data source" is missing in these text boxes.

What works: The selected tags are recognized by the Taxonomy List plugin.

4 years ago

Youuup thats how its works ... You can always write Option4 in field to add different from predefined. Not sure if it possible to get exactly what you want without custom plugin to manage tags - something like I have for Author taxonomy from my 1st post... but I might be wrong as Im new here (using Grav from 1 month only)

👍 1
4 years ago

Hello,
first of all, thank you for your efforts.
You pointed me to your first post. Do I understand you correctly when I say:
I need to write a php script with a static function that returns the values of a taxonomy list (as an array) and define the script in the argument "data-options@"?
Is this correct?

Do you know a good documentation or example to read me into this?

4 years ago

Hello,
that was a good address to start with, thank you.

In my setup I created a theme that overrides Quark (I call it CustomQuark). In its php file I added a function "taxonomyTest", which I successfully included in the blueprint - I can see the placeholder in the dropdown menu of the text field.
But now I need a way to get every created tag of a taxonomy. I have tried the following:

PHP
<?php
namespace Grav\Theme;

use Grav\Common\Grav;
use Grav\Common\Theme;

class CustomQuark extends Quark
{

        public static function taxonomyTest()
        {
                $taxonomy = Grav::instance()['taxonomy']->taxonomy();
                Grav::instance()['log']->info("Taxonomy: " . implode(",", $taxonomy));

                $pages = Grav::instance()['pages']->all();
                Grav::instance()['log']->info("Pages: " . $pages);

                return array (
                        'PH' => 'Placeholder',
                );
        }
}
?>

Output in log:

TXT
[2022-11-11 21:54:52] grav.INFO: Taxonomy:  [] []
[2022-11-11 21:54:52] grav.INFO: Pages:  [] []

Why are both variables empty?

4 years ago

@pireba, Instead of trying to implement a "custom" Taxonomy field by yourself, you can add some validation using a plugin.

Try and adapt the following:

  • In case not all Taxonomy taxons are required, add to the yaml file of the plugin the following:
    TXT
    requiredTaxons: [category, tag]
    
  • Subscribe to event 'onAdminSave':

    PHP
    if ($this->isAdmin()) {
      $this->enable([
          'onAdminSave' => ['onAdminSave', 0],
      ]);
    
      return;
    }
    
  • Add the following function to handle the onAdminSave event:

    PHP
    public function onAdminSave(Event $event)
    {
    // Only run validation when a page is being saved.
    if (!$event['object'] instanceof PageObject) {
      return;
    }
    
    /** @var PageObject */
    $page = $event['object'];
    
    // Only run validation on specific page type, eg. blog item.
    if ($page->template() !== 'item') {
      return;
    }
    
    $taxonomy = $page->header['taxonomy'] ?? [];
    
    $taxons = $this->config->get('plugins.validate.requiredTaxons', []);
    
    foreach ($taxons as $taxon) {
      if (!isset($taxonomy[$taxon])) {
        $capitalised = ucfirst($taxon);
        throw new \Exception("Field '$capitalised' is required.");
      }
    }
    }
    

    The message of the Exception will be shown in a red banner in Admin at the top of the page.

last edited 11/12/22 by pamtbaau
4 years ago Solution

@pireba, To respond to your issue wrt the empty Taxonomy values in your static function...

Try the following function inside your theme (or plugin):

PHP
  public static function taxonomyValues(string $taxon, string $fieldType)
  {
    /** @var Grav */
    $grav = Grav::instance();

    /** @var Admin */
    $admin = $grav['admin'];
    $admin->enablePages();

    /** @var Taxonomy */
    $taxonomy = $grav['taxonomy'];

    $keys = $taxonomy->getTaxonomyItemKeys($taxon);
    $values = [];

    foreach ($keys as $key) {
      if ($fieldType === 'select') {
        $values[$key] = $key;
      } else {
        $values[] = [
          'text' => $key,
          'value' => $key,
        ];
      }
    }

    return $values;
  }

In combination with the following field definitions:

TXT
data-options@: ['\Grav\Theme\Quark::taxonomyValues', 'category', 'select']
data-options@: ['\Grav\Theme\Quark::taxonomyValues', 'tag', 'selectize']

Notes;

  • Replace Quark with the name of your theme.
  • The 2nd parameter select|selectize, might not be needed in your case. It's just to show that different returns types are required depending on the field type.
👍 1
4 years ago

Hi!
Nice, it works! Thanks a lot for that!

I think the reason it didn't work for me are these two lines:

PHP
  $admin = $grav['admin'];
  $admin->enablePages();

Can you tell me why I need to call "enablePages()"? I can't find any API documentation for the admin plugin class....

Your first solution is good to know, but I prefer the second one because any logic is in the blueprint file. Only the creation of the array is written in PHP code.

For those who want the same behavior as me, here is my working code:

Blueprint file (user/themes/custom_quark/blueprints/item.yaml):

YAML
extends@: item

form:
  fields:
    tabs:
      fields:
        options:
          fields:
            taxonomies:
              fields:

                header.taxonomy:
                  unset@: true

                header.taxonomy.category:
                  type: select
                  label: Category
                  selectize:
                      create: true
                  multiple: true
                  array: true
                  data-options@: [ '\Grav\Theme\CustomQuark::getTaxonomy', 'category' ]
                  default: [ 'blog' ]
                  validate:
                    required: true

                header.taxonomy.tag:
                  type: select
                  label: Tag
                  selectize:
                      create: true
                  multiple: true
                  array: true
                  data-options@: [ '\Grav\Theme\CustomQuark::getTaxonomy', 'tag' ]
                  validate:
                    required: true

PHP file (user/themes/custom_quark/custom_quark.php):

PHP
<?php
namespace Grav\Theme;

use Grav\Common\Grav;
use Grav\Common\Theme;

class CustomQuark extends Quark
{
    public static function getTaxonomy(string $tag) {
        $grav = Grav::instance();

        $admin = $grav['admin'];
        $admin->enablePages();

        $taxonomy = $grav['taxonomy'];

        $keys = $taxonomy->getTaxonomyItemKeys($tag);
        $values = [];

        foreach ($keys as $key) {
            $values[$key] = $key;
        }

        sort($values);
        return $values;
    }
}
?>
👍 2
4 years ago

@pireba,

Can you tell me why I need to call “enablePages()”?

For performance reasons, pages are not being initialized when using Admin. Hence the Taxonomy is not set. Using $admin->enablePages(); will force Admin to initialize the pages.

3 years ago

Hello,

I tried to implement this automatic option populating. It works fine with select, but it doesn't seem to work with selectize.
The php function in my theme is the same than yours, and my yaml look like:

YAML
header.test:
  type: selectize
  autocomplete: on
  style: vertical
  label: test
  data-options@: ['\Grav\Theme\NixTemplate::taxonomyValues', 'artiste','selectize']
  validate:
    type: commalist

If i dump the $values in the php, I can see an "array of array":

JS
array:2 [  0 => array:2 [    "text" => "artiste1"
    "value" => "artiste1"
  ]
  1 => array:2 [    "text" => "artiste2"
    "value" => "artiste2"
  ]
]

But if i click in the field in the admin, I can't see any suggestion of completion, do you know what I am doing wrong?

3 years ago

@nix, This topic has already been closed/solved. Please open a new topic with a proper title describing your specific problem and add a reference in the content of the topic to this topic for context.

Suggested topics

Topic Participants Replies Views Activity
Forms & Blueprints · by Ton Haarmans, 5 years ago
13 1135 4 months ago
Forms & Blueprints · by Hugo Oliveira, 5 months ago
0 60 5 months ago
Forms & Blueprints · by Flachy Joe, 6 months ago
9 132 6 months ago
Forms & Blueprints · by Augustus, 7 months ago
7 108 7 months ago
Forms & Blueprints · by Julien, 7 months ago
10 127 7 months ago