Jump to content

don't show pages without template file


joshuag
 Share

Recommended Posts

Hi all,

I always create a few templates that do not have a template file. For example, a lot of times I create a "testimonials" page that displays all it's "testimonial" children. But I never want the users of the website to navigate to a single testimonial. I on'y want to list out the testimonials on the "Testimonials" page and store the individual testimonials as children of this page. I never ever want the individual testimonials to be visible. As it stands, if you were to try to visit an individual testimonial, you would get a 404.

But if I made a loop and was outputting all the pages, like for a sitemap or menu, I am going to get all the children.

How do I ask processwire if the page is visible because it has a template file or doesn't.

I want to do something like this:

if($page->template->hasFile()) {

do something...

}

Is this possible?

Thanks in advance for the help.

Link to comment
Share on other sites

Thanks for the reply nik, but where did u find that method filenameExists()? I swear I read the documentation! I just double checked this after reading your post. noti n the docs as far as I can tell. Also, viewable() didn't seem to work in my experiments.

Link to comment
Share on other sites

I've got a habit of first reading the "definitive documentation", source code that is ;). That's where that filenameExists() came up.

I mentioned viewable() as it's definitely something that's supposed to be used (as everything else in the documentation) rather than going for something undocumented. Still, it seemed to me that it's ok to use filenameExists() if that would solve your problem. I'm sure Ryan will tell if I were wrong.

  • Like 1
Link to comment
Share on other sites

$

Thanks for the reply nik, but where did u find that method filenameExists()? I swear I read the documentation! I just double checked this after reading your post. noti n the docs as far as I can tell. Also, viewable() didn't seem to work in my experiments.

$template->filenameExists would be ok. or file_exists($page->template->filename);

$page->viewable() does not check if there's a template file, just if the page is viewable by the user rights. If you would remove view access completly for the template it would work.

If you use $page->template->filenameExists you already have them loaded, so it would be more efficient to use a selector template!=testimonials if possible, as that won't load those pages in the first place.

Link to comment
Share on other sites

Actually $page->viewable(); does check if the template file exists. See the viewable() function in the file /wire/modules/PagePermissions.module. One of the first checks it performs is $page->template->filenameExists(). If you've run into some scenario where viewable() isn't responding properly, let me know how to reproduce?

What doesn't check if a template file exists are any functions that return a Page or PageArray. So you can end up with pages that don't have template files from a non-specific $pages->find() call, or $page->children call, for instance. These functions are only bound by access control (defined in the template) and page status (hidden, unpublished, etc.).

The intended way to exclude pages from results like this is to use the 'hidden' status that you see on the 'Settings' tab of every page. Once page has a 'hidden' status, it's not going to show up in any find() or children() results unless you add "include=hidden" (or include=all) to your selector string.

Soma's suggestion to use specific selectors to include only the things you want (or exclude the things you don't) is also a good way to go.

  • Like 2
Link to comment
Share on other sites

Thanks for the feedback and explanation guys!

The reason that I don't just use a selector is because I used a simple example to a complex problem I have. I actually have like 10 types of templates that don't have files in different places in my website. So I was looking for a generic way to do this, not just a specific example.

I am going to read all the source code in PW. I think that will go a long way.

Thanks again for the help.

Link to comment
Share on other sites

@soma, just like Ryan said, I was using the ->children() method, so that makes it makes sense that I was getting back those pages even with viewable. But with the suggestions about, I was able to do what I was trying to do. Thanks a lot guys! I appreciate it!

Link to comment
Share on other sites

I think you understood it maybe wrong. Let's speak some code. :D

foreach($page->children as $child) {
 if(!$child->viewable) continue;
 echo "<li><p><a href='{$child->url}'>{$child->title}</a><br /><span class='summary'>{$child->summary}</span></p></li>";
}

Just spinning this further with selectors, you could even do a search for all template's that don't have a "view" and exclude them in find()/children().

Eeasiest name the templates "nofile_name". Then use this in navigation find()/children():

$tmpls = $templates->find("name^=nofile_");

foreach($page->children("template!=$tmpls") as $child) {
 echo "<li><p><a href='{$child->url}'>{$child->title}</a><br /><span class='summary'>{$child->summary}</span></p></li>";
}

Just love to think of different ways as PW is so flexible and easy.

Edit: also posting your solution, may help others too.

  • Like 1
Link to comment
Share on other sites

rather then namen "nofile_*" u.cann also do $this alsos


$tamplons = '';
foreach($templates as $t) {
 if(!$t->filenameExists()) $tamplons .= $tamplons ? "|$t" : $t;  
}

foreach($page->children("template!=$tamplons") as $babby) {
 // $babby.not tamplon
}

cd ..

  • Like 4
Link to comment
Share on other sites

  • 1 year later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...