Jump to content
ptjedi

Display Menu using Selectors and Checkboxes

Recommended Posts

Greetings all,

I am trying to separate which pages display on the header menu and those which appear on footer menu. For that I created two checkbox fields, applied them to the templates, and now I am trying to filter them in the menu list.

Here's my code:

<?php
   [b]$homepage = $pages->get("/")->find("visibility_in_top_menu=1");[/b]
   $children = $homepage->children;
   // $children->prepend($homepage);

   $i = count($children)-1;
   foreach($children as $child) {
  $class = $child === $page->rootParent ? " class='on'" : '';
  if($i>0){echo "<li><a$class href='{$child->url}'>{$child->title}</a></li>";}
  else {echo "<li><a$class href='{$child->url}' id='last'>{$child->title}</a></li>";}
  $i-=1;
   }
  ?>

The thing is that I am probably not setting up the first line well.

Can anybody help me out?

Thanks!

Share this post


Link to post
Share on other sites

I think this is what you want

$homepage = $pages->get("/");
$children = $homepage->children->find("visibility_in_top_menu=1");
  • Like 2

Share this post


Link to post
Share on other sites

Perfect. Now I understand how it's done.

Many thanks!

Share this post


Link to post
Share on other sites

One more thing:

I understand that the following line adds the "on" class to the menu item if the current page matches that item, however I don't understand how that works.

$class = $child === $page->rootParent ? " class='on'" : '';

Could you please explain it to me?

This is because I've changed pages level like this:

$homepage = $pages->get("/en/");

and now the on states aren't working...

Thanks

  • Like 1

Share this post


Link to post
Share on other sites

I think I got it even though I really don't understand why now this is needed.

Changed

$class = $child === $page->rootParent ? " class='on'" : '';

to

$class = $child === $page ? " class='on'" : '';

Share this post


Link to post
Share on other sites
$class = $child === $page->rootParent ? " class='on'" : '';

is a short way of writing

if($child === $page->rootParent) {
$class = " class='on'";
} else {
$class = '';
}

$page->rootParent gets the ancestor that is closer to the root (a direct children of the homepage). If you change the homepage variable to a something different from the root, they will never match. For this to work you have to replace $page->rootParent for this page's ancestor that is closer to /en/.

Put something like this after the first lines:

foreach($page->parents as $v) {
if($children->has($v)) {
	$newRootParent = $v;
}
}

Then replace $page->rootParent by $newRootParent.

I'm not on my computer, and I can't test this right now, so, no guarantees here :)

  • Like 4

Share this post


Link to post
Share on other sites

Many thanks for your support Diogo. It is working perfectly.

Share this post


Link to post
Share on other sites

Thanks, diogo! Your post helped me to solve my (quite similar) problem. I'm still not used to the short version of this if-function - but the long version helped me understand it and to fill in the right pieces. 

Share this post


Link to post
Share on other sites

@Georgson - That is called the ternary conditional operator. 

From the manual .. 

<?php
$first ? $second : $third
?>

If the value of the first subexpression is TRUE (non-zero), then the second subexpression is evaluated, and that is the result of the conditional expression. Otherwise, the third subexpression is evaluated, and that is the value.

 
For those interested read more at php.net ... 

Share this post


Link to post
Share on other sites

It can be better explained with this:

result = ifonething==something ? iftrue : iffalse;
 
  • Like 1

Share this post


Link to post
Share on other sites

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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By snck
      Hi there,
      I have a problem constructing a selector that finds all pages that refer to pages with a specific template.
      I have pages using an event template and I want to show events based on a specific context. In this example I want to filter the results and only show event pages that relate to a specific template (exhibitions) in their page field related_pages.
      What I tried:
      $events = $pages->find("template=event, related_pages.template.name=exhibition"); Unfortunately it does not work (0 results).
      Same with this:
      $events = $pages->find("template=event, related_pages=[template.name=exhibition]"); At the moment I am helping myself with the following lines, but I have a strong feeling that there is a more efficient solution:
      $events = $pages->find("template=event"); foreach($events as $event){ if(!count($event->related_pages->find("template=exhibition"))){ $events->remove($event); } }  
      I really hope that one of you can help me out.
      Thanks in advance!
      Flo
    • By Kiwi Chris
      The selector in the following code included in a template is returning nothing, however if I take out the compId.resultsdate<={$today} bit, it works fine, although obviously not filtered on the date field.
      $today = strtotime(date('Y-m-d')); $setImages = $pages->find("template=competitionImage, compId={$page->id}, compId.resultsdate<={$today}, compSubject.name=s, imageRating.title=Merit|Honours,check_access=0"); Here's the results of an example from Tracey Debugger
      templates_id=79, resultsdate<=1587729600, status<2048   SELECT pages.id,pages.parent_id,pages.templates_id FROM `pages` JOIN field_resultsdate AS field_resultsdate ON field_resultsdate.pages_id=pages.id AND (((field_resultsdate.data<='2020-04-25 00:00:00' ) )) WHERE (pages.templates_id=79) AND (pages.status<2048) GROUP BY pages.id Over in my ready.php I have inside a hook that refers directly to the page template that's used for the pages in the page field above:
      $today = strtotime(date('Y-m-d')) $event->return = $event->pages->find("template=competition,eventEnd>={$today},eventStart<={$today}"); In this case the filtering on date fields (albeit different ones) works fine. Can anyone suggest why the filter on the date subfield of the page field isn't working?
      Just to confirm, I do have a date value in the field, and it is a date before today. 🙂
      The problem may be something blatantly obvious, but I can't for the life of me figure out why the selector is returning no results when I include the date filter.
    • By ngrmm
      I have a page with a table. Each table row has a page-reference field and a checkbox.
      The Page sends emails to all users (page-refrence->email-field) and change the value of the checkbox in a row to 1.
      It works with this:
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?> But i have to use a variable in my emailbody.inc which i'm able to get in the table-loop.
      So i do the including of the body inside my loop. But this doesn't work anymore. Page sends out the emails but is unable to change the value of the checkbox.
      I get no errors!
      I'm using ProTable
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?>  
    • By Matze
      Hi,
      is there a way to activate the option Input > Visibility > Presentation > "Open when populated + Closed when blank" for a Fieldset (Page) containing some fields like text or textarea?
      To me it is always open, even if all fields inside are empty.
      Thx, Matze
    • By Roberts R
      I have simple page structure:
      category subcategory simple-product simple-product simple-product simple-product subcategory .... category2 so Im at category page and running
      $pages->find("template=simple-product, has_parent=$page, limit=8"); and it returns 0 pages
       
      but this returns 4 pages
      $pages->find("template=simple-product, has_parent=$page"); Can someone explain why limit does not work here?
      EDIT:
      So I did some tests and it seems that any limit=n where n is >= actual page count that is possible ... selector return 0 results.
×
×
  • Create New...