Jump to content

problem with hierarchy


Manfred62
 Share

Recommended Posts

hi to all

just making my first steps with ProcessWire and porting a static website to PW (locally on xampp).

But now I'm stucked with a hierarchy problem (limited php knowledge..).

I have a parent side (Menu recommendations) with children (various menus of the month).

parent template:

<?php
  include("./head.inc");
?>

<ul id="empfehlung">
  <?php foreach($page->children->find('template=empfehlung_list') as $child){
  echo $child->render();
  };?>
</ul>

<?php
  include("./foot.inc");
?>

list items:

<li><?php echo $page->title; ?></li>

that's working and really simple. But now I want to expand the structure with months. So the user can prepare the menus and only publish the needed 'month'.

Parent-site

- January

-- Spaghetti

-- Bruschetta

- February

-- Steak

-- Fish

I don't know how to get this done correctly. How can I fetch the published month and render the content? Will publish/unpublish like said above work despite of published children-pages? Also a nice to have: time scheduling (publish) of the months. Possible?

thanks in advance

Manfred

Link to comment
Share on other sites

Hi Manfred, welcome to pw.

I'm not sure I understood what you want to do, so I'm making a guess. So, right now you have this, right?

-recommendations

-- Spaghetti
-- Bruschetta
-- Steak
-- Fish
 
If you change it to this:
 

-recommendations

-- January
--- Spaghetti
--- Bruschetta
-- February
--- Steak
--- Fish
 

You could simply change your selector to get only the recommendations from January to this:

foreach($page->get('name=january') as $food)

Of course this would imply that someone would have to change the code every month, not ideal...

What you can do, is get the current time to find out what month we are in and publish only the children of that month:

$this_month = strtolower ( date("F") );

foreach($page->get('name=$this_month') as $food)

Just an idea of the kind of things you can do. Of course you have to adapt it to exactly what you want.

Also a nice to have: time scheduling (publish) of the months. Possible?

How exactly do you want this to work?

Link to comment
Share on other sites

Hi Diogo,

thanks for help. The structure is like you described it. I also got it running with the exact path, but this is not flexible to use.

  <?php foreach($pages->get('/empfehlungen/juli/')->children->find('template=empfehlung_list') as $child){
  echo $child->render();
  };?>

Tried your solution, but no success (e.g. no understanding..).

  <?php 
  $this_month = strtolower (date("F"));
  foreach($page->get('name=$this_month')->children->find('template=empfehlung_list') as $child){
  echo $child->render();
  };?>

Maybe there will be another problem (even when this runs): month names in german. Had read something about this in the forum.

Time schedule... How exactly do you want this to work?

On monthly base is enough.

Hmm, not sure if PW is the right thing for me. I'm no php developer. Coming from MODX and in the moment it feels, like I can do this page in shorter time with MODX.

Will take a break for coffee, to get my head clear. Thanks.

Link to comment
Share on other sites

You don't have to be a PHP developer to work with PW, but what you are trying to do is not that simple.

About the month, that was just an example, there are lots of possibilities to fix it. For the dates you can use all these http://php.net/manual/en/function.date.php, so you can use the number of the month for instance. So, imagine you have this structure:

-recommendations

--2013

--- January
--- February
---- Spaghetti
---- Bruschetta
--- March
--- ...
--2014
--2015
You could get the current month by cheking the position on the tree like this:
 
$this_month = date("n"); //gets the number of the month "2"
$this_year = date("Y");
$year_page = $pages->get("name=$this_year"); 

// get the page that is in the position that the current month has in the year
// eq() is 0 indexed so we have to subtract 1
$month_page = $year_page->children->eq($this_month - 1);

foreach($month_page->children as $child){
   echo $child->render();
}

Hope this example is clear

Link to comment
Share on other sites

now I got it. A little bit old style. Maybe there's a shorter way. Now only one month (published) will be shown.

That's the wanted effect in this example.

But for understanding: if all months are published, the array renders always the last found (published) name. Correct?

  <?php 
  $januar = $pages->get('/empfehlungen/januar/');
  $februar = $pages->get('/empfehlungen/februar/');
  $maerz = $pages->get('/empfehlungen/maerz/');
  $april = $pages->get('/empfehlungen/april/');
  $mai = $pages->get('/empfehlungen/mai/');
  $juni = $pages->get('/empfehlungen/juni/');
  $juli = $pages->get('/empfehlungen/juli/');
  $august = $pages->get('/empfehlungen/august/');
  $september = $pages->get('/empfehlungen/september/');
  $oktober = $pages->get('/empfehlungen/oktober/');
  $november = $pages->get('/empfehlungen/november/');
  $dezember = $pages->get('/empfehlungen/dezember/');

foreach($pages->get('name=januar|februar|maerz|april|mai|juni|juli|august|september|oktober|november|dezember')->children->find('template=empfehlung_list') as $child){
  echo $child->render();
  };?>

@diogo

thanks for help. But confusing.. why use another hierarchy level (year)?

Also tried it with the first example. But how to find the first level (/empfehlungen/) before specifing the month with

$this_month = strtolower (date("F"));

Also corrected this typo: 'name=$this_month'.

Link to comment
Share on other sites

I'm scratching my head trying to understand your code :)

As I understand, you want to get the only month that is published, right? The intention is that the editors would publish one month and and unpublish the previous? If it's this, than I don't think it's the best way to go... But you should explain exactly what kind of effect you are trying to achieve before I start giving solutions just by guessing.

why use another hierarchy level (year)?

because eventually 2014 will come, and you will have two Januars to deal with.

But how to find the first level (/empfehlungen/) before specifing the month with

You can change the selector to: $page->get('parent=/empfehlungen/ name=$this_month')

Link to comment
Share on other sites

explanation of the site:

a small restaurant. There's a page 'recommendations'. Here you find some special menus, based on a monthly turn.

Example: in July italian cooking, in September some chinese menus etc. So there's no need for sorting by year.

The editor can work on the 'month' pages. In my solution, the editor publish only the needed month-page.

just tried the other code in this way, but no output. Month names must be english (February instead of Februar)? Also tested, no sucess.

Hmm, what's the problem here?

  <?php 
  $this_month = strtolower (date("F"));
  
  foreach($pages->get('parent=/empfehlungen/ name=$this_month')->children->find('template=empfehlung_list') as $child){
  echo $child->render();
  }; ?>
Link to comment
Share on other sites


Don't make things complicated :) Since php generated date strings are english you'd have to name you pages in english or use a mapping. Diogo already posted some code with using eq(n) which would take the position in the pages tree to get the current month. Here's another example how I would do it with using month names.

$month = date("n"); // month integer
$month_names = array("januar","februar","maerz","april","mai","juni","juli","august","september","oktober","november","dezember");
$curr_month = $month_names[$month-1];
$menues = $pages->get("/empfehlungen/$curr_month/")->children("template=empfehlung_list");

if(count($menues)){
    foreach($menues as $child){ 
        echo $child->render();
    }
} else {
    echo "Keine Menues gefunden.";
}


In selector you should use "field=$value" instead of 'field=$value', or the variable won't get parsed. Also you need to separete selector pair with comma. "field=value1,field2=value=2".

Link to comment
Share on other sites

Also instead of doing


$pages->get("parent=/empfehlungen/, name=$curr_month")->children->find("template=empfehlung_list");

You can do just 



$pages->get("/empfehlungen/$curr_month/")->children("template=empfehlung_list");
Link to comment
Share on other sites

thanks for replying, but... no sucess. Tried this snippet:

<?php
$month = date("F"); // month integer
$month_names = array("januar","februar","maerz","april","mai","juni","juli","august","september","oktober","november","dezember");
$curr_month = $month_names[$month-1];
$menues = $pages->get("parent=/empfehlungen/$curr_month")->children("template=empfehlung_list");

if(count($menues)){
    foreach($menues as $child){ 
        echo $child->render();
    }
} else {
    echo "Keine Menues gefunden.";
} ?>

beside the missing bracket in if(count($menues)) it gives me the same output like my solution above by chance.

Can not reproduce how this works. Think, if I publish only one month --> this content will be shown.

changed F to n (because of counting the months, like diogo mentioned) gives me the "no menus found" message.

Are there any constraints, to get the snippet above to work? I have all 12 months under /empfehlungen/, in the correct order, named like in the array uncapitalized. Any more to check about?

thanks

Link to comment
Share on other sites

Manfred, look at my comment above. On Soma's code you have to change date("F") for date("n")

edit: delete :)

edit2: just for debbuging, does this work?

$curr_month = $month_names[2]; // <- hardcode a number here
Link to comment
Share on other sites

no

2. EDIT: without parent= it shows the content. Seems logical, because we already have the parent /empfehlungen/ in the string?

$menues = $pages->get("/empfehlungen/$curr_month")->children("template=empfehlung_list");
Edited by Manfred62
Link to comment
Share on other sites

Ok back on laptop. I corrected my code example with "n" and missing bracket. Thanks for pointing out, but I wrote it in the browser and didn't test.

Glad you figured it out finally :) It can take time to adapt brain to PW but it's worth.

Concerning your publish month question. The current example with getting current month doesn't require a publish unpublish scenario.

If you would really want to make it it would be as simple as getting the published page from the parent with children(selector). This function will only return pages that are published and not hidden.

// return published and visible children from /empfehlungen/
$menues = $pages->get("/empfehlungen/")->children("template=empfehlung_list");
if(count($menues)) {
    foreach($menues as $child) echo $child->render();
} else {
    echo "Keine Menues gefunden.";
}

// return all children, even hidden
$menues = $pages->get("/empfehlungen/")->children("template=empfehlung_list, include=hidden");

// return all children, even published and hidden
$menues = $pages->get("/empfehlungen/")->children("template=empfehlung_list, include=all");
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...