Solution to achieve manual showcase builder

Hi,

I have almost finished my website with this amazing tool, but i’m know struggling to find a solution to this issue:

I’d like to have project showcased into a grid, so far it sounds pretty simple to do, but the interface in the panel should allow user to manually select existing projects, and decide what project, and what picture attached to this project goes into what part of the grid, and what will be the width of the displayed picture (4/4 rows, width can be 1/4,2/4, 3/4, or 4/4) and user must be able to leave some blank or text squares.

On the front end picture should link to project page.

ex ("x “are pictures “-” are blank”:

  • x x -
    x - - x
    x x - -
    x x x x

I tried to play with kirby builder, kirby structure eetc… but i always end up with an issue: i can’t have a field that let backend user select existing projects pictures…

ideally it would have structure fields like this:

Project Item:
Select project to showcase.
Select the display image, among images attached to the previously selected project.
(user should have preview of images when selecting, and a preview of selected image)
Select item width (selector) : 1/4, 2/4, 3/4, 4/4

Project Item:
Textarea
Select item width (selector) : 1/4, 2/4, 3/4, 4/4

Leave Blank Space
Select item width (selector) : 1/4, 2/4, 3/4, 4/4

Yeah, sounds easy at first sight, and a structure field would be the way to go, but I think you need a custom field within the structure that listens to what project has been selected in the first select and then updates its image options to reflect this.

I’m not aware of an existing plugin field that does that.

As workaround: Show all images of all projects, but with the project name in front of the image, not super comfortable but doable. Maybe best in combination with. the Quickselect field, which features a search.

I will try this, but i have another question, how do i display the name of the project in front of the image?
How do i ask quickselect to display images from /projects and all of its childrens?

Other questions about more trivial things about the frontend:
How do i output the image and the corresponding project’s URL (for the link).

Thanks for your help.

Kirby is amazing and so fun, can’t wait for v3!

Unfortunately, the multiselect field doesn’t support a function to select images of all. children.

So the only feasible way is to use the API option. That is, you pass a URL as option and the URL returns your options in JSON format.

https://getkirby.com/docs/cheatsheet/panel-fields/select

The JSON itself you would create via a route, as a JSON encoded flat array of key/value pairs, where the key is the value that is stored in the file, and the value what is presented to the user.

The key would in this case be the path to the file, so that you can fetch the correct image in your templates. The value the name of the project followed by the filename.

Edit: it is actually pretty straightforward to extend the quick select field in such a way that it accepts a controller as well, see my PR:

Thanks a lot, i’ll try with that.

Im running through another issue by the way, must be simple to solve but i can’t figure it out. On my projects page im trying to display the simple project’s category list but i have no idea how to achieve that.

Here is a “project” blueprint excerpt, the category list would be displayed on “projects” template.

category:
label: Category
type: checkboxes
required: true
options:
restaurant: Restaurant
hotel: Hotel
store: Store

I’m just trying to output a “foreach”, listing all the “options” (categories):

Result would be on the frontend:

Restaurant, Hotel, Store.

I successfully outputed, the corresponding categories for a given project, this data is needed mainly to serve as a css class, but as soon as there is two category it doesnt work because the categories ar eoutputed with a “,” separator… Is there any way to output it just with a space and no “,”… my code:

<?php foreach($projects as $project): ?>
<div class="column is-3 element-item transition <?= $project->category() ?> all" data-category="<?= $project->category() ?>">
        <figure class="showcase-container">
        <a href="<?= $project->url() ?>" class="showcase-link">
          <?php if($image = $project->images()->sortBy('sort', 'asc')->first()): $thumb = $image->crop(800, 800); ?>
            <img src="<?= $thumb->url() ?>" alt="Thumbnail for <?= $project->title()->html() ?>" class="showcase-image" />
          <?php endif ?>
          <div class="showcase-caption">
            <h3 class="showcase-title"><?= $project->title()->html() ?></h3>
          </div>
        </a>
        <figure>
</div>

Do you want to fetch all the possible options or only those that are actually used in all projects.

For the latter, you can fetch them like this:

$categories = $page->children()->visible()->pluck('category', ',', true);
foreach($categories as $category) {
  // do something
}

If you want to get all the options, no matter if their are used or not, you would need a plugin.

If you want to get only the categories for a single project within the loop

foreach($projects as $project):
  $categories = $project->category()->split();
  foreach($categories as $category):
    // do something
  endforeach;
endforeach;

Sorry but none of your code work for me, i have

" Whoops \ Exception \ ErrorException (E_NOTICE)
Array to string conversion"

error…

For which piece of code? Please indicate the exact line where this is happening, maybe with a screenshot of the error

ok so i think this was because the forum cut some php tags. Sorry im really bad at php, just copy pasting code snippets i find around here ^^. Now i dont have any error, but i dont have any data shown neither ^^

So i copy pasted the first snippet of your code, to display all used categories:

<? php $categories = $page->children()->visible()->pluck('category', ',', true);

foreach($categories as $category) {
// do something
} ?>

I dont see the categorie list… I have a small clue that it might be because i havent written anything in the place of “do something”, because i dont really have an idea on what to do… i just want the category list…

Thanks for your time and patience !

Ok, let’s start from the beginning. Which exactly of the three options I outline above do you want to output? Just the categories per project? Or all categories of all projects?

Ok,

  • I’d like to output categories of all projects, simply for a category menu.

  • I’d also like to output categories per project to use as a css class. (i’m using metafizzy isotope and it detect css class to filter items). The thing is I already managed to output categories per project, but it break the code as soon as a project have more than one category, because my code output a project’s category names with a “,” separator. I’d need only a space to separate category names.

Ok, then.

Number 1 and you are on the PROJECTS page (projects.php template). Assuming you want them in a list:

<?php $allCategories = $page->children()->visible()->pluck('category', ',', true); ?>
<ul>
<?php foreach($allCategories as $category): ?>
  <li><?= ucfirst($category) ?></li>
<?php endforeach ?>
</ul>

Number 2, for each project in the loop

<?php foreach($projects as $project) ?>

<!--- Wherever you want to echo this, implode joins the array elements of $project->category()->split() to string separated by a blank -->
<?= implode(' ', $project->category()->split(',')) ?>
<?php endforeach ?>

Absolutely nailed it ! Thanks it’s working wonder !

So it was indeed the right snippet of code for that matter, but i’m again running into few details that prevent it from working properly:

Everything is happening in the first snippet you provided:

<div id="filters" class="button-group"> <button class="button is-checked" data-filter="*">show all</button> <?php $allCategories = $page->children()->visible()->pluck('category', ',', true); ?> <?php foreach($allCategories as $category): ?> <button class="button" data-filter=".<?= ucfirst($category) ?>"><?= ucfirst($category) ?></button> <?php endforeach ?> </div>

Specialy here:

<button class="button" data-filter=".<?= ucfirst($category) ?>"><?= ucfirst($category) ?></button>

which is supposed to output:

<button class="button" data-filter=".category">Category</button>

The first issue is in the class name, <?= ucfirst($category) ?> output the category name with an UPPERCASE. whisch doesnt work in the code. I tried <?= ucfirst($category)->lower() ?> with no success as is throw me a
" Error
Call to a member function lower() on string"

How can i output the category name without Uppercase?

2nd issue:

<button class="button" data-filter=".<?= ucfirst($category) ?>"><?= ucfirst($category) ?></button>

I call for the category name a second time, this tile to display the name, except that the code output the “machine” name, which is different in my case than the “human readable” name (i have a category “Apartment and house” that have “apthouse” machine name.)

Thanks again for your precious help and patience !

The ucfirst() method capitalises the first lettter, if you don’t want that, just echo the category.

<?= $category ?>

For the second issue, that is a bit more complicated, because you can’t access the human readable category name. this is best solved with a category map in your config.php

c::set('categoryMap', [
   'apthouse' => 'Apartment and house',
   'architecture' => 'Architecture',
   'photography' => 'Photography',
]);

In template:

<?php  $categoryMap = c::get('categoryMap'); ?>
<div id="filters" class="button-group">
 <button class="button is-checked" data-filter="*">show all</button> 

  <?php $allCategories = $page->children()->visible()->pluck('category', ',', true); ?> 
  <?php foreach($allCategories as $category): ?> 
    <button class="button" data-filter=".<?= $category ?>">
      <?= $categoryMap[$category] ?>
</button> 
<?php endforeach ?> 
</div>

This work well ! Thanks a lot for your help !