Output a specific page's datas from a "page builder" structure field

Hi,

I’m using “kirby page builder” ( https://github.com/TimOetting/kirby-builder ) to make a manual showcase builder. If i’m not mistaking, thee “kirby page builder” is an extension of the native “structure field” and rely on it. The builder is accessible from the “home” panel blueprint as it will be displayed on the homepage (it’s basically the whole, and only content on the homepage). In this builder one can add “entries” in which they can select a page with a “page field” (https://getkirby.com/docs/cheatsheet/field-methods/pages). The pages allowed to be selected are all childrens of the “projects” page. The goal is to then display on the homepage the selected project’s name, URL (to make a link) and some additional infos from these projects templates (city, year, category(ies)).

I have no idea on how to access these infos from the page builder. When i select a page and try to access the name, it only display the path of the project (projects/project-a) for example.

Here is the code:

https://pastebin.com/ufk3xr1n

NOTE: In the code above, you’ll see that i use in these showcase entries a picture directly uploaded from the home page, its just for test purpose as i would like the picture to be selectable from an image select field that has listened to what project has been selected previously. But thats another issue that i may develop later if i still can’t find any solution despite the help i already benefited from this forum.

Thanks

Could you post your blueprint please, I need to know what you store in your file.

Here is the “home” blueprint:

https://pastebin.com/wM7rvYa9

And the “project” blueprint:

https://pastebin.com/8M72SVxF

Here I would store the project uri:

fields:
          project:
            label: Projet
            type: page
            required: true
            options: query
            query:
              page: projects
              fetch: children
              value: "{{ uri }}"
              flip: true

Then you can call the toPage() method on the value to fetch the project page:

<?php $p = $data->project()->toPage(); ?>
<?php if ($image = data->picture()->toFile()): ?>
    <figure class="image">
        <a href="<?= $p? $p->url():'' ?>">
            <img src="<?= $image->url() ?>" alt=""></a>
                <figcaption class="has-text-left">
                    <a href="http://wwww.google.com">
                        <h2 class=""><?= $p? $p->title()->html() :'' ?></h2>
                    </a>
                        <p> <?= $data->project()->city() ?> </p>
                </figcaption>
            </figure>
  <?php endif ?>

Hope it works, it’s a bit late…

Cheers,
Sonja

Hi, thanks for your answer, i was away from my computer for a few days. I tried your solution and it doesn’t work. Considering the circumstance i think it would be way more clear if i link you the code. Here is the full site .zip:
http://www.studioperrier.fr/kirby_start.zip

Files involved are:

Template:
-home.php
-home.yml

Snippet:

  • sections/entry.php

So, when you go on the homepage you’ll see a picture showcase, these pictures can be added from “home” panel. I tried my best but i can’t achieve all i would like. In the panel form you can select a project to showcase, as you can see i only achieved to output the selected project URL in the template, you can compare what i tried to output in the sections/entry.php snippet and compare to what you can actually see in the frontend when you hover one of the showcase picture…

There is also a picture field, the picture field only allow to choose from a “home” upload file for test purpose. I’d like to allow the user to select amongst pictures from the previously selected project.

I see the problem and there is no straightforward solution to selecting the correct image from the selected project, I’ll get back to you later tonight.

Hi, that is indeed the 2nd part of the problem, i suppose its possible to output the selected project title, place and year rather easily tho?

Well, if we leave the image bit away, I still think the snippet should look like the above, at least this works in your project’s entry.php snippet:

<div class="column <?= $data->width() ?>">
  
  
  <?php $p =  $data->project()->toPage(); ?>
  <?php   if($p): ?>
  <figure class="image">
    
    
    
    <a href="<?= $p->url() ?>">
      <img src="<?= $page->image($data->picture())->url() ?>" alt="">
    </a>
      <figcaption class="has-text-left">
        <a href="<?= $p->url() ?>">
          <h2 class=""><?= $p->title()->html() ?></h2>
        </a>
        <p><?= $p->place() ?>, year, category(ies)</p>
      </figcaption>
    </figure>
    
  <?php endif ?>
  
</div>

As regards getting an image from the project, this is more complicated. I see several options:

  • Instead of having the user actually select an image, either choose the first or a random image
  • create a select field that lists all images of all projects (using the controlled list plugin to fetch the options), but the displayed value contains the project name as well as the file name, e.g… Project A - image-one.jpg etc. (the user will then have to think a bit to select the correct image)
  • create a custom field that listens to the project select field and inject the image options on the fly.

Thanks ! Its working indeed with the first version of the code, you edited it afterward and i tried but the current version doesn’t work. (unexpected endif).

I’ll try your solution for the picture. How may call the first picture of the project btw?

Sorry, I forgot a colon after if($p)

if($image = $p->images()->first()) {
  echo $image->url();
}

Thanks, but it’s still throwing an error :slight_smile:“Call to a member function url() on null” :

For the page url? Which line in which code snippet? Please post your code and a screenshot of the Whoops error message that includes the line where the error is thrown.

here it is:

also how do i call project’s category name from a category map in this context?I have : <?php $categoryMap = c::get('categoryMap'); ?> but then i don’t knowhow to call the mapped names instead of raw categories (currently like this): <?= $p->category() ?>

Didn’t you want to get the first picture of a project page. now?

And in. general: never call an object method like url() etc. without checking if the object exists, see my if statement in one of my last posts.

$categoryMap = c::get('categoryMap'); 
$category = $categoryMap[$p->category()];

Full code to fetch the first image:

<div class="column <?= $data->width() ?>">


  <?php $p =  $data->project()->toPage(); ?>
  <?php   if($p): ?>
  <figure class="image">



    <a href="<?= $p->url() ?>">
      <?php if($image = $p->images()->first()): ?>
        <img src="<?= $image->url() ?>" alt="">
      <?php endif ?>
    </a>
      <figcaption class="has-text-left">
        <a href="<?= $p->url() ?>">
          <h2 class=""><?= $p->title()->html() ?></h2>
        </a>
        <p><?= $p->place() ?>, year, category(ies)</p>
      </figcaption>
    </figure>

  <?php endif ?>

</div>

If your category field can. contain multiple values, this won’t work, though. Then you have to loop through an array of these values first:

$categories = $p->category()->split(',');
foreach($categories as $category):
  echo $categoryMap[$category];
endforeach;

Ok, that was to be used calling the first picture of a project page, i did not get it ! Thanks for your precious help!

Sorry, it gets confusing pretty easily for me, category field can contain multiple value indeed, how can i get them to display in this snippet of code precisely:

https://pastebin.com/twBa5CEE

thanks!

That is the old code, you should have replaced it with the code from above by now?

You have to put the category loop I posted above into your p tag where you want to display the categories, but maybe change the way you display everything, maybe put the categories into a list or whatever, and add the separating comma via CSS to avoid if statements when to put a comma and when not.