Is this possible : Backend blueprint using page data for a dropdown of catogeries

Not the best title:

Wonder if any one has information to how to have a page blueprint, which has list data,
for example web, design, pubiflication, branding
then have this linked to the same page and used in a dropdown field on the form called catogery

so i can set an image and assign to one of the catogeries.

looked at data@ but cant see a solution (due to my lack of understanding)

or if there is a workaround … or a better practise :slight_smile:
thank you

Will give a full write up to this shortly. This is part of my learning curve and I am not a developer, just someone whom is learning fast and puts a problem and works out a solution.

Problem, is having an a dropdown in the backend blueprint of a page, which picks up data originally currently from the same page, to control the selection of input applied to a fieldset repetitively on the same blueprint.

This is still mark 1 of the solution so I am sure people can suggest ways to improve it.

I wanted to have a category section based on a main category and a sub category.
Created this with a list style blueprint

header.category:
      type: section
      title: Portfolio Category
      underline: true
      fields:
        .arraylist:
          name: Category
          type: list
          style: vertical
          collapsed: true
          label: Add Portfolio Category
          fields:
            .group:
              type: text
              label: Category 
            .item:
              type: text
              label: Sub Category

This would create the data in the frontmatter .md page

category:
    arraylist:
        -
            group: Portfolio
            item: Portfolio
        -
            group: Artwork
            item: Branding
        -
            group: Marketing
            item: Marketing
        -
            group: Development
            item: 'App Design'
        -
            group: Development
            item: 'Web Design'

I then wanted to be able to assign in each item of the list the friendly sub category text
item:
and then write the
group:
name to the page data of the group of items, and be able to select single or multiple groups to an item

portfolio:
    item:
        -
            categories:
                - portfolio
                - marketing
            title: null
            image: null

        -
            categories:
                - artwork
                - development
            title: null
            image: null
        -

So that is the outcome, here is how to complete it.

Step 1: Create the blueprint for the dropdown to appear

Step 2: Use the “select field” to create the dropdown, I have been advised that a ‘selectize’ field can be used, but I couldn’t get it to work.

Step 3: When the dropdown is selected, we need to create and call a function, to retrieve the page header info of page.header.category.arraylist and basically create a 'data-options: ’ in the blueprint to return and populate the field

header.portfolio.item:  
          name: Portfolio Items
          type: list
          style: vertical
          label: Add Portfolio Category
          fields:
            .categories:
              type: select
              label: Categories
              multiple: true
              array: true
              data-options@: '\Grav\Theme\YourThemeName::PortfolioCategoriesList'

              validation:
                type: commalist
                options:
            .title:
              type: text
              label: Title
            .image:
              type: filepicker
              folder: '@self'
              preview_images: true
              label: Background Image
              accept:
                - .png
                - .jpg
                - .svg

data-options@: '\Grav\Theme\YourThemeName::PortfolioCategoriesList'

This is the crucial line which is going to call a php function, which has been added to the to the YourThemeName.php which is the root of your theme.

Step 4 Writing the PHP function

public static function PortfolioCategoriesList()
{
  $pages = Grav::instance()['pages'];
  $pages->enablePages();
  $pagename ='/home/_portfolio';
  $arr = Grav::instance()['pages']->find('/home/_portfolio')->header()->category['arraylist'];

  $selectize_options = [];

  foreach($arr as $array) 
  {
    $group = strtolower($array['group']);
    $item = $array['item'];
    $selectize_options[$group] = $item;
  }

  return($selectize_options) ;
}

Overview of the code / function

 $pages = Grav::instance()['pages'];
 $pages->enablePages();

I need to access the page collection, in admin plugin this is turned off to help with speed so we need the above to enable access to the pages.collection and turn it on

$pagename ='/home/_portfolio';

The above lines sets a variable for the page where I know the category data lies, in this case it is a module ( _portfolio which is in the /home/ page)

I need to convert this to a function parameter at some stage, to make my code reuseable and pass the module / page name

$arr = Grav::instance()['pages']->find($pagename)->header()->category['arraylist'];

These next line is to get a (instance) chunk of page collection header data from the \home_portfolio page which is the arraylist which is under the category page.header root and return it to the $arr (array)

$selectize_options = [];

creates an array container which we be putting the results of the data and return to the blueprint select field

foreach($arr as $array) {
    $group = strtolower($array['group']);
    $item = $array['item'];
    $selectize_options[$group] = $item;
}

Now we are going to create a loop to go through the page.header.catogeries.arraylist array where the associated array element of group and item (nested array) and the value which are associated to this blueprint fields

foreach($arr as $array) {

Create a loop which takes the indvidual page.header.catogeries.arraylist array (group and item) from $arr and puts it into a variable called $array

 $group = strtolower($array['group']);

to create a standardised answer I am using strtolower, which will take the element and put it to lower case.

It uses a variable $group to store the data from in to the new storage array variable $array r

  -
       group: Portfolio
        item: Portfolio

in this example the first sub array ( where the - defines it in the frontmatter .md and the group and item are the associated array key names

In this first sub array , it is ‘group:’ and the reply with be Portfolio value

$item = $array['item'];

This line is to get the ‘item:’ key value ( in this case again on the first item within page.header.catogeries.arraylist will be also the word ‘Portfolio’

On the 2nd loop of the items in the array the following
$group will = artwork and $item will = Branding

$selectize_options[$group] = $item;

This prepare the data structure of [ $group = $item ] which will create the [ portfolio => Portfolio, artwork => Branding … and so on as the loop continues ]

This will provide a select box, with a list of the $item as friendly input name, but will save the $group name in lowercase to the front matter

On the admin blueprint of the page it creates

the html output on the blueprint when no value has been selected produces

Portfolio
Branding
Marketing
Web Design

Hope this basic tutorial / solution can point people in the right direction , happy to receive comments and criticism of a better way or possible mistakes in my documenting my learning (sorry dyslexic) than will do my best to update this post.

This took me about a week to perfect, mainly due to the lack of correct terminology (array, nested array and associated arrays and the issues with selectize and select field)

But this has been an learning curve (many thanks to Ricardo on discord) and a lot of trying and reading.

Tags: Nested Array, Associated Array, Loop, Selectize, Select, Dropdown, blueprint, dynamic, filled, Array, Key Name

V2 is to make it more of a modular function which can have data passed to for where I want to have this ability to call the option from any blueprint and on any page, move the categories builder blueprint to the themes blueprint rather than on the page.

Also just notice one of the categories sub items is being sent through development => ‘App Design’ is missing,

All this is to create a isotope portfolio cards with selectable filter , so a portfolio item may belong to different multiple buttons /filter