Page blueprint with conditional tab

Hello,

I try to set a condition to display a tab. But the tab under the condition is not displayed.
it’s properly displayed without the “conditional”.

title: Gallery
'@extends':
   type: default
   context: blueprints://pages

form:
 fields:
   tabs:
     type: tabs
     active: 1
     fields:
       gallery:
         type: tab
         title: PAGE_MAP.GALLERY.LABEL
         underline: true
         import@1:
           type: partials/gallery
           context: theme://blueprints  
       conditionfeat:
         type: conditional
         condition: "'true'"            
         fields:
           features:
             type: tab
             title: PAGE_MAP.FEATURES.LABEL    
             underline: true
             import@2:
               type: partials/features
               context: theme://blueprints 

I have tried the funny following code, which displays the fields of the second tab under the fields of the first tab :

title: Gallery
'@extends':
   type: default
   context: blueprints://pages

form:
 fields:
   tabs:
     type: tabs
     active: 1
     fields:
       gallery:
         type: tab
         title: PAGE_MAP.GALLERY.LABEL
         underline: true
         import@1:
           type: partials/gallery
           context: theme://blueprints  
   conditionfeat:
     type: conditional
     condition: "'true'"            
     fields:
       tabs2:
         type: tabs
         active: 1                  
         fields:
           features:
             type: tab
             title: PAGE_MAP.FEATURES.LABEL    
             underline: true
             import@2:
               type: partials/features
               context: theme://blueprints 

How can i handle this ?

Thanks for your help.

Did you try the usual condition: true (without quotes)? Or even condition: "true" or condition: 'true' (as docs say, it can be strings)? Why the double quotes? This should literally parse to 'true' (string with quotes in it and not just as string true)

Hi,

‘true’ or true don’t work.

“‘true’” works for a field.

                            type: conditional
                            condition: "'true'"            
                            fields:            
                                header.test:
                                    type: toggle
                                    label: TEST 

At the end, i will not use “‘true’” but a real condition like
condition: "config.plugins.myne.xxx ? 'true' : 'false'"

@unmick,

Is it possible?
From the docs:

The conditional field type is used to conditionally display some other fields base on a condition.

The term “fields” is quite ambiguous, but my first interpretation is “input fields” which excludes “tabs”.

The final verdict might be given by the Grav-team

Alternative ‘conditional’ approach:
You didn’t share the intention of using a ‘conditional tab’, so maybe the following alternative might not work in your use-case.

You could display a tab conditionally by conditionally publishing the overriding blueprint.

Usually a plugin publishes its blueprints in the event onPageGetBlueprints. E.g.:

public function onGetPageBlueprints(Event $event) {
   $types = $event->types;
   $types->scanBlueprints('plugin://' . $this->name . '/blueprints');
}

To publish the blueprint conditionally you could:

  • Subscribe to event onPageGetBlueprints only when condition is met.
    if ($condition) {
        $this->enable([
           'onGetPageBlueprints' => ['onGetPageBlueprints', 0],
        ]);
    }
    
  • Or you could wrap the code inside onPageGetBlueprints with an if-statement:
    public function onGetPageBlueprints(Event $event) {
       if ($condition) {
          $types = $event->types;
          $types->scanBlueprints('plugin://' . $this->name . '/blueprints');
       }
    }
    

IMHO, this approach is much cleaner and less error-prone than messing around in YAML form definitions.

Thanks! I will dig this solution.

@unmick, I just read your question on Github in which you explained you use-case:

In fact, i use the same yaml for standard pages or blog ones and i would like to display the tab dedicated to the blog only if the parent is a blog

I’m wondering why the typical use of file names: blog.md (defining the blog) and item.md (each blog item) does not work in your use-case. Would you mind sharing why the use of blog.md/item.md doesn’t work in your use-case and the conditional tab is a necessity?

Hi
Thanks to take care of me :slight_smile:
In my blueprints folder, i have a gallery.yaml which imports the fields related to the gallery:
import@1: type: partials/gallery context: theme://blueprints
Not important in this explanation, in my blueprints\modular folder i have a gallery.yaml which import the fields related to the gallery

For my blog, i have also the item.yaml which imports the blog-fields.
Instead of using item.yaml, i can use also the first gallery.yaml where i would like to insert the blog-fields only when the parent is a blog.
I don’t want to see the blog-field outside a blog and i don’t want to create a itemgallery.yaml for maintenance reason.

At each time i need a new parameter for the gallery, i add it in only one yaml.
At each time i need a new parameter for the blogitem, i add it in only one yaml.

Mick

@unmick, I’ve been playing around a bit trying to minimize duplication…

In a fresh Grav 1.7.7 installation, I created the following pages:

user/pages
├── ...
├── 03.blog
│   ├── blog-item
│   │   └── item.md            <-- standard blog-item
│   ├── blog.md                <-- standard blog page
│   └── gallery-item
│       └── gallery-item.md
└── 04.gallery
    └── gallery.md

And in Quark I defined the following blueprints:

user/themes/quark/blueprints
├── ...
├── gallery-item.yaml         <-- extends item    + adds gallery tab + imports gallery-bits
├── gallery.yaml              <-- extends default + adds gallery tab + imports gallery-bits
├── item.yaml                 <-- extends default + adds blog tab + imports blog-bits (already exists in Quark)
└── partials
    ├── blog-bits.yaml        <-- fields for item (already exists in Quark)
    └── gallery-bits.yaml     <-- fields for gallery
// gallery.yaml

extends@: default

form:
  fields:
    tabs:

      fields:
        gallery:
          type: tab
          title: Gallery
          import@:
            type: partials/gallery-bits
// gallery-item.yaml

extends@: item

form:
  fields:
    tabs:

      fields:
        gallery:
          type: tab
          title: Gallery
          import@:
            type: partials/gallery-bits
// partials/gallery-bits.yaml

form:
  fields:
    gallery_options:
      type: section
      title: Gallery Options
      underline: true

    header.gallery:
      type: text
      label: Gallery field

Notes:

  • The only duplicate code is the definition of a tab in gallery.yaml and gallery-item.yaml. I guess however, that that piece of code will hardly change over time. The changes will be in the partials/gallery-bits.
  • Mark the different extends@ blueprints gallery.yaml and gallery-item.yaml use.
  • Any changes in item.yaml and partials/blog-bits will automatically be available in the blog tab of gallery-item.yaml.
  • Any changes in the partials/gallery-bits.yaml will automatically be available in the gallery tab of gallery.yaml and gallery-item.yaml.

You wanted:

At each time i need a new parameter for the gallery, i add it in only one yaml.
At each time i need a new parameter for the blogitem, i add it in only one yaml.

I like to think I have achieved above requirements…

Sorry for the delay.
It’s effectively the best solution. I cannot avoid to duplicate gallery.yaml in gallery-item.yaml and may be in a second time to create a gallery-eshop.yaml
i have too many kind of pages :slight_smile:

Thanks for you help!

The question, whether conditional tabs are supported, has been answered on Github:

This is currently not possible as tabs field only allows children to be fields of type tab .

A workaround can be found in post#8