Check if page exists based on something other than URI

Hello. I have a case where I need to see if a page exists based on the value of its title. Here’s the run down…

I built a site for a law firm. They can write articles. When composing an article they can select an attorney as the author of an article. That’s done with a select field which gets populated from the attorney’s section. The author’s page title/full name gets saved as for the author field (not the URI).

A few attorneys left the firm, now they want to keep their articles, but do not wish to display the author names for those attorneys that are no longer at the firm. So the logic needs to be, "show the author’s name only if the author’s page exists. Seems like a job for the findBy() function but I’m having a hell of a time with it. This is my logic simplified…

<?php foreach($articles as $article): if($pages->find('/attorneys)->findBy('title', $article->author())): ?>by: <?= $article->author() ?><?php endif ?>

The findBy() function doesn’t seem to like the variable. Is there some other way to check to see if a page exists based on one of the field values (the title in this case)?

I think you need filterby instead, that way you can sift out the workers that dont work there. This will get all articles that have an author field that has a value that is NOT in the array.

  <?php
  $workers = $page->site()->index()->filterBy('author', '!=', ['idontworkhere', 'idontworkhereeither']);
  foreach($workers as $worker): ?>
  <?= $worker->author() ?>
  <?php endforeach ?>

It’s often easier to get the set of data you want to work with upfront rather then getting funky in a foreach loop.

Thanks for the quick reply.

Well… the client still wants to display all articles. They just don’t want to show the author’s name if that author is no longer an employee. Authors that no longer work there get their page deleted from the site. So I need to check if the author’s page exists. If it does, show the author, if it doesn’t exist, do nothing.

Actually, filterBy() did the trick. Here’s the real-world piece of logic (for those that might find it useful).

<?php if($pages->find('/attorneys')->children()->filterBy('title', $pg->author())->count() > 0): ?> by: <?= $pg->author() ?><?php endif ?>

Thanks much.

I think your problem was not the findBy() vs. filterBy(), but the missing children() in the first code snippet.

Nice one. I’m not sure that you need the slash in the find either '/attorneys'. My understanding is it will find that page regardless of depth and go from there. Someone please correct me if i am talking rubbish :slight_smile:

Thanks for your input. Right. I failed to include children() in my example above, but when I do include the children() function it still doesn’t work with findBy(). The following doesn’t work.

<?php if($pages->find('/attorneys')->children()->findBy('title', $pg->author())->count() > 0): ?> by: <?= $pg->author() ?><?php endif ?>

Probably because of that count() business… but the following doesn’t work either…

<?php if($pages->find('/attorneys')->children()->findBy('title', $pg->author())): ?> by: <?= $pg->author() ?><?php endif ?>

How are you setting $pg?

count() will not work with findBy() because it does not return a collection but a single page. The slash is indeed not necessary, but you have to pass an URI, so if it is deeper than first level, it will not find it, slash or no slash.

I don’t know why your second example does not work.

I think you could use isEmpty() or isNotEmpty() instead of count. This will check if a field has a value (or not). if a page doesnt exist, it wont have a value. Thats my logic.

No, these are field methods. If you call a method on an object that does not exist, you’ll get an error. @thewebprojects wants to check if a page exists.

Sure, but thats what the OP is using it on. He wants to check the author() field. Unless i’m missing something?

See my edit above (and some characters)

Somethin’ like…

<?php foreach($pages->find('articles')->children()->visible() as $pg): ?>

BTW: Instead of $pages->find('whatever') you might as well use page('whatever')

Yep. I’m aware of that shorter one. I like how it’s short and sweet, but it’s kinda odd. Maybe I’m just odd. Maybe it’s that it’s too close to $page?

Yes, maybe. It was just a suggestion, anyway, I always use it because it’s shorter.

Just to throw something out there…how about filling an array with the current attorney pages then checking the current pages author field against the array (not tested but should work):

<?php
$authors = array ();
foreach ($pages->find('attorneys')->children()->visible() as $author) {
  $authors[] = array(
    'author' => $author->author(),
}
if (in_array($page->author(), $authors)) {
    echo $page->author();
}
?>

This code works in a Starterkit:

<?php

if($pages->find('blog')->children()->findBy('title', 'Extending Kirby')) {
  echo 'page exists';
} else {
  echo 'page does not exist';
}

so the question is rather what $pg->author() returns.

@jimbobrjames: Possible, but too much overhead. And you are even creating a multi-dimensional array here.

$authors[] = $author->author();

would be enough. Or

$authors['author'] = $author->author();

And learning PHP a little piece at a time every day… :slight_smile: