There can be more than one field value - do not forget it in your templates :)


#1

Hello.

I have big problem in my template, can someone help to understand what’s wrong?

  1. I have simple pages collection, like this:
<?php $news = $site->find("news")->children()->listed(); ?>
  1. I go thru them in foreach:
<?php foreach ($news as $news_item) : ?>
...
<?php endforeach; ?>
  1. I have field linkto_theme in my $news_item page object, and can get it with no problem like this:
<?= $news_item->linkto_theme(); ?>

This field in blueprints is simple multiselect field, where I selecting other pages to “linking them” to my news page.

  1. It returns other page ID for me, like otherpage.

  2. So there is I falling in troubles:

a) there is no way to get "label of this otherpage value, because it page’s ID, not blueprint value.

b) Ok, I can use API and get this page title by using somtehing like

dump(page('otherpage')->title());

c) It works perfect, but I need it in “dynamic” - there is more than one news page in my collection, and there is someother and somethirdpage values in next collection page objects.

d) Logically I can use something like this:

dump(page($news_item->linkto_theme()->toString()));

where

$news_item->linkto_theme()->toString()

is an argument (other page’s id) getted “dynamically” from field value,

but it works ONLY ONCE!

When I increase limit to 2+, there is no error, but dump returns me only FIRST page’s dump in collection.

e) And there is other problem -

page($news_item->linkto_theme()->toString())

returns me a Page object, but

page($news_item->linkto_theme()->toString())->title()

wont work too on more than one page collection!

It returns me

Kirby\Cms\Field Object
(
    [title] => My Other Page Title
)

when I set collection limit to 1, but throws me an error when I set collection limit to 2+ !!!

 Error
Call to a member function title() on null

I broke my brain, please someone help me, what I did wrong?

I think this is simple logical way - go thru pages collection, get some field values as other page’s ids and get titles from this ids and print it to template etc. ?!

Thank you very much.


#2
if($p = $news_item->linkto_theme()->toPage): {
  echo $p->title();
}

should work, provides your select field contains a single string and you store the full path to the referenced page.

If this doesn’t work, please post your blueprint with the select field.


#3
                    <?php
                    if($p = $news_item->linkto_theme()->toPage()) {
                        echo $p->title();
                    }
                    ?>

It works but again ONLY ON FIRST item in collection (foreach). Is this templating system bug or page object restriction or something else I don’t know…


#4

This is my main problem here - getting toPage() or page('id') or similar methods cannot work in foreach cycles.


#5

My blueprint for this field is simplest of simple :slight_smile:

              linkto_theme:
                label: News Themes
                type: multiselect
                options: query
                query: site.children.filterBy("section_type","section_theme").sortBy("admin_position","asc")

#6

Ok, I’m on a way to find the solution :slight_smile:

Parsing toPage() stops working when next item having TWO or more field values, looks like I need to foreach this values instead of directly calling toPage


#7

Ok, sorry me, I’ve found the solution, it was very simple :smile:

There can be more than one field value in my page item in foreach (!) - this was a tip, what I have not seen :smiley:

So I need to obtain field values as array first with split(','), and THEN foreach them to make my linkto_page titles.

Thank you all very much, I think I need some drink this hard friday night :smiley:


#8

This is working piece of code, may be useful for noobs like me :smiley:

                <?php
                    $a = $news_item->linkto_theme()->split(',');
                    $b = array();
                    foreach ($a as $item) {
                        $p = page($item);
                        $b[] = "<a href='" . $p->url() . "'>" . $p->title()->toString() . "</a>";
                    }
                    $c = implode(", ", $b);
                ?>

#9

Great work in finding a solution! As a suggestion, you clean it up a bit more:

$links = [];

foreach ($news_item->linkto_theme()->toPages(',') as $item) {
  $links[] = Html::a($item->url(), $item->title());
}

$linksString = implode(', ', $links);