Detect if subpage has tag?

Hi all -

I am having trouble with tags. The basic idea of what I am trying to do is have a page that has all of its subpages listed. The problem is that I want the subpages names to have different css text styles depending on the kind of content they have. So I gave each subpage one of three styles through a tag field in the yml. Each subpage has then a tag that is let’s say styleone, styletwo or stylethree.

Now the tricky part. I tried to write if statements like so:

<?php foreach($page->children() as $subpage): ?>
        <?php if($subpage->$tag() == 'styleone'): ?>
          <div id="itemlistone">
              <a href="<?= $subpage->url() ?>">
                <h2><?= html($subpage->title()) ?> </h2>
              </a>
          </div>
        <?php endif ?>

        <?php if($tag == 'styletwo'): ?>
          <div id="itemlisttwo">
              <a href="<?= $subpage->url() ?>">
                <h2><?= html($subpage->title()) ?> </h2>
              </a>
          </div>
        <?php endif ?>

        <?php if($tag == 'stylethree'): ?>
          <div id="itemlistthree">
              <a href="<?= $subpage->url() ?>">
                <h2><?= html($subpage->title()) ?> </h2>
              </a>
          </div>
        <?php endif ?>

      <?php endforeach ?>

The problem I am encountering is “undefined variable: tag”. Why? But I guess my question is broader: would that even be the correct way of doing that? or am I better off trying to add a class through js? how would that work? I am a bit confused. Thanks for your help in advance!

Should be

$subpage->tag() // without the `$`before `tag`.

In the second if statement, you just use $tag without ever having defined that variable.

But I think your life would be easier (and your code less repetitive) if you use the tags directly as classes and then just do

<?php foreach($page->children() as $subpage): ?>
<div class="<?= $subpage->tag()" ?>
  <a href="<?= $subpage->url() ?>">
    <h2><?= $subpage->title()->html() ?></h2>
  </a>
</div>
<?php endforeach ?>

Or with a default fallback:

<div class="<?= $subpage->tag()->or('defaultstyle')" ?>

And don’t use the id attribute, it is allowed only once per page, use the class attribute instead.

Make sure to restrict your tags to a list of options to not end up with undesired entries or use a select instead.

Of if you want to keep your current setup, use an array map:

<?php
$styles = [
  'styleone' => 'itemlistone',
  'styletwo' => 'itemlisttwo',
  'stylethree' => 'itemlistthree',
];
?>
<?php foreach($page->children() as $subpage): ?>
<div class="<?= $styles[$subpage->tag()->value()] ?? '' ?> ">
  <a href="<?= $subpage->url() ?>">
    <h2><?= $subpage->title()->html() ?></h2>
  </a>
</div>
<?php endforeach ?>

You could also use a default value if no tag is set:

<div class="<?= $styles[$subpage->tag()->value()] ?? 'defaultstyle' ?> ">

Thanks so much for the suggestion! I did it so:

<?php foreach($page->children() as $subpage): ?>
      <div class="<?= $subpage->tag() ?>">
        <a href="<?= $subpage->url() ?>">
          <h2><?= html($subpage->title()) ?> </h2>
        </a>
      </div>
    <?php endforeach ?>

and they seem to display correctly. However - and I am surely missing something super obvious - when I do this in the css:

.styleone a h2{
  color: red;
}

it doesn’t work. what am I doing wrong? thanks again!

That looks like it should work.

Have you cleared the browser cache?
A typo?

I cleared the cache and everything seems to be linked correctly. If I replace “<?= $subpage->tag() ?>” with “styleone” it works, so somehow it doesn’t read the name correctly?

Screen Shot 2020-02-16 at 1.20.27 PM
and it’s the only tag

What output do you get in your rendered HTML?

Is the name of the field correct?

Somehow I get no name…
Screen Shot 2020-02-16 at 1.28.58 PM
just nameless divs

Could you post the blueprint for the subpages, please?

title: Subpagename
pages: true
files: true
fields:
  title:
    label: Title
    type:  text
  tags:
    label: Tags
    type: tags

for now nothing else is on there

it’s “tags” not “tag”!!! I knew it was something simple like that. Now it should work. Thank you very much for your help!

Note that you will get undesired results if users enter more than one value or a wrong value (typos). Since you can’t limit tags to certain options in Kirby 2, consider using a select field with fixed options instead.

1 Like

I will do that! I will be the only one with panel access, but it still sounds like a good safe practice. Thank you so much for all your help!