Empty element in foreach

hey ,

i am using a simple foreach to display my subpages.
Since, i dont know when, in the code appears an empty “a” do u know why?

<div class="footer__links col3 ta-left">
            <a href="<?= page('company')->url() ?>"><?= page('company')->title()->text() ?> </a>
            <a rel="follow" href="https://typestudio.co/blog">Blog</a>
            <a>
                <?php
                foreach (page('company')->children()->filterBy('footer', true) as $subpage) : ?>
                    <?= $subpage->title()->link() ?>
                <?php endforeach ?>
            </a>
        </div>

browser output->

i have the problem with every foreach wich works in that way…

Your loop is only executed within that <a> element, i.e. you are creating the list of links inside it. Anchor elements within an anchor element is invalid HTML; the browser “corrects” that by automatically closing the <a> tag before the next, hence the “empty” <a> element.

Try this:

<div class="footer__links col3 ta-left">
            <a href="<?= page('company')->url() ?>"><?= page('company')->title()->text() ?> </a>
            <a rel="follow" href="https://typestudio.co/blog">Blog</a>
                <?php
                foreach (page('company')->children()->filterBy('footer', true) as $subpage) : ?>
                    <?= $subpage->title()->link() ?>
                <?php endforeach ?>
        </div>

Thank you Sebastian :slight_smile:
Your hint solved the problem and pushed the seo to 100% :heart_eyes:

Keep in mind that code like this might throw an error if the page you are trying to fetch does not exist (because it was deleted or renamed).

Unless text() is a custom method or yours: this function does not exist in Kirby’s core so won’t have any effect.

uff…
honestly didnt knew that.
Since it always worked as i wanted it to work.

I used ->html() once and that broke my code.
After changing it to ->text() it worked like i expected.

Didnt knew that it overall didnt worked…
Obviously i have to make some changes

The safe way to code this would be:

<?php if ( $p = page('company') ) : ?>

<div class="footer__links col3 ta-left">
            <a href="<?= $p->url() ?>"><?= $p->title()->html() ?> </a>
            <a rel="follow" href="https://typestudio.co/blog">Blog</a>
                <?php
                foreach ($p->children()->filterBy('footer', true) as $subpage) : ?>
                    <?= $subpage->title()->link() ?>
                <?php endforeach ?>
        </div>
<?php endif; ?>

With the additional advantage that you don’t have to keep repeating page('company') all the time.

Background: Methods like url(), children() etc. are member methods of a class, in this case the Page class. They can only be used with instances of that class (objects). These methods throw an error when they are called on something that is not an object of the given class, like a string, null, boolean etc.

If – like in this example – you use the page helper to create a page object with the given argument company, but that folder does not exist in your file system, then page('company') returns null and not a page object and therefore any class method call on that result will not work.

It is therefore super important that we always make sure that we have an object before we try to call any class methods.

1 Like