Problem with programmable-blueprints cookbook

:sunflower: :leaves:
hello everyone,
i just started with kirby and am glad to be joining this beautiful & vital community!

today i was playing around with the new panel cookbook for creating programmable blueprints. i love everything you have put together here @texnixe, it helps so much and my filtered page sections are populating nicely!

the only thing i noticed is, since i integrated the plugin, the first section in my site.yml is not showing up anymore (pls see screenshots). looks like the plugin’s function is still being called on the panel homepage, despite having the if clause right at the start inside your notes.php (in my setup it’s called meals.php though).

as soon as i disable the plugin, the section is rendering again.
any idea why this is happening?

thanks a lot!
:sparkles:


Could you please post the blueprint that’s causing the error?

yes, of course!
thank you for taking your time!

site.yml


title: Site

columns:
  left:
    width: 1/2
    sections:

        # primary pages
        primary:
            headline: Primary Pages
            type: pages
            empty: No pages found
            status: published
            templates:
                - home
                - shop
                - about
            image: icon

        # secondary pages
        secondary:
            headline: Secondary Pages
            type: pages
            empty: No pages found
            status: unlisted
            templates:
                - checkout
                - success
                - error
            image: icon

  right:
    width: 1/2
    sections:

        # databases
        databases:
            headline: Databases
            type: pages
            empty: No database found
            status: unlisted
            templates:
                - meals
                - categories
            image: icon

        # ecommerce
        ecommerce:
            headline: Ecommerce
            type: pages
            empty: No database found
            status: unlisted
            templates:
                - orders
                - shipping-methods
                - emails
            image: icon

as you can see, i am displaying my “meals page” (the one with the dynamic blueprint) inside the “databases section”. but removing the template here, doesn’t seem to solve the issue.

:deciduous_tree: :herb:

Thanks. But the error occurs for the first primary section, not the database section. Do the rest of the sections show up as intended?

And I assume site.yml is a the standard blueprint in the /site/blueprints folder, not in the plugin? And the only dynamic blueprint you are using is the meals blueprint?

@texnixe yes, that’s correct.

Could you post index.php and meals.php from your plugin, please?

yup, here you go!

index.php


<?php

use Kirby\Cms\App as Kirby;

Kirby::plugin('cookbook/dynamic-blueprints', [
    'blueprints' => [
        'pages/meals' => function ($kirby) {
            return include __DIR__ . '/blueprints/pages/meals.php';
        },
    ]
]);

meals.php


<?php

$sections = [];

if ($page = page('meals')) {

    // create dynaimic sections
    foreach ($page->site()->find('categories')->children() as $category) {

        $sections[explode('/', $category)[1]] = [
            'headline' => $category->title()->value(),
            'type' => 'pagesdisplay',
            'status' => 'published',
            'layout' => 'cardlets',
            'empty' => 'No products yet',
            'query' => "page.children.filterBy('type', '==', '" . $category . "')",
            'templates' => 'meal',
            'image' => false,
            'info' => '{{ page.descr }}'
        ];
    }

    // add drafts
    $sections['drafts'] = [
        'headline' => 'Drafts',
        'type' => 'pages',
        'status' => 'draft',
        'empty' => 'No products yet',
        'templates' => 'meal',
        'image' => false,
        'info' => '{{ page.descr }}'
    ];
}

// create the array for the page blueprint with two columns
$yaml = [
    'title' => 'Meals',

    'image' => [
        'back' => 'white',
        'icon' => 'food',
        'color' => 'black'
    ],

    'options' => [
        'changeSlug' => false,
        'changeStatus' => false,
        'changeTemplate' => false,
        'changeTitle' => false,
        'delete' => false,
        'preview' => false,
        'update' => false,
        'duplicate' => false
    ],

    'sections' => $sections
];

return $yaml;

:sparkles:

Ok, the error points to line 8 of meals.php, which is this line with the call to children:

foreach ($page->site()->find('categories')->children() as $category) {

I can reproduce the error and it helps if you wrap the first section in an if statement:

    if ($p = $page->site()->find('categories')) {

        foreach ($p->children() as $category) {

            $sections[explode('/', $category)[1]] = [
                'headline' => $category->title()->value(),
                'type' => 'pagesdisplay',
                'status' => 'published',
                'layout' => 'cardlets',
                'empty' => 'No products yet',
                'query' => "page.children.filterBy('type', '==', '" . $category . "')",
                'templates' => 'meal',
                'image' => false,
                'info' => '{{ page.descr }}'
            ];
        }
    }

thank you so much for your wonderful support @texnixe, that did the trick! :pray:t2: :sparkles:

do you mind explaining why i needed to add this? because i thought the plugin only loads on my meals template, not on every page in the panel. is that not correct?

Those page blueprints need to be loaded as well, e.g. for the sections to decide if a page should be listed at all, for preview images etc.

1 Like

@texnixe one more question… how do i now get the content of my dynamically created fields when building a template?

i cant do $page->xyz() because xyz is dynamic… so is there something like $page->content('xyz')?

thank youuu!
:partly_sunny: :sparkles:

I guess you are referring to the dynamic fields example? In the example, the field names are set to the page slug in the loop. So to fetch these fields, you would apply the same loop as in the dynamic blueprint.

@texnixe in my dynamic blueprint loop (the same from above), i added other fields, like a headline and a writer. and because each field needs an individual name to store the content, i use the category name as a prefix.

of course i will need to use the same loop inside my template. i can also get the same category name (my prefix) there. but then, how do i get to the content itself? because i guess i can’t do $page->$name . 'label'() here, right?

do you know what i mean?
its a bit hard to explain…
:deciduous_tree:

$sections[$name . 'intro'] = [
    'type' => 'fields',
    'fields' => [
        $name . 'label' => [
            'label' => $category->title()->value(),
            'type' => 'headline',
        ],
        $name . 'headline' => [
            'label' => 'Headline',
            'type' => 'writer',
            'nodes' => false,
            'marks' => '-italic -link'
        ],
    ],
];

You can, but you have to wrap the the concatenated string in curly braces:

$page->{$name . 'label'}()
1 Like

perfect, thats exactly what i was looking for. again, thank you so much! what a beautiful & fast support here, wow! :sunflower: