Jump to content


Photo

Page level and sub-navigation


  • Please log in to reply
36 replies to this topic

#21 martinluff

martinluff

    Full Member

  • Members
  • PipPipPip
  • 79 posts
  • 2

  • LocationChristchurch NZ

Posted 14 November 2011 - 02:35 PM

I am actually building simple "navigator" module which should cover most of basic navigation needs. I hope to get it released sometime :)


Cool; I suspect it'll be a very well used module  ;)

I'm trying to improve my PHP coding but unfortunately not a fast learner... The Zend PHP 101 series, although from a while back, seems the best online introduction I've found so far http://devzone.zend....olute-beginner/

#22 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,520 posts
  • 845

  • LocationVihti, Finland

Posted 14 November 2011 - 03:06 PM

This goes little off topic:

IMO good way to learn is to be brave and publish stuff that you have done for feedback. This forum is one fine place to do it (and I remember you have done also) - it's great to get feedback and is many times beneficial for others too! I don't know how to thank Ryan and others enough for all the learning I have got from here.

I have also found that there are some concepts that are very common in web development (php & js for me) and understanding those will speed up your learning (not saying that I have grasped these all, still learning basic stuff also..):

  • arrays, multidimensional
  • looping those arrays
  • functions (especially those that return something)
  • classes and objects
  • Web dev basics: server side vs. client side? sessions, cookies, databases. http-basics: post, get, headers...

Also there are super simple things that we waste a lot of time. Things like string manipulation or simple maths. If you have problems like that and google doesn't help you right away, then just ask for help - it will help you learn faster. Also - learn to love php.net - ugly but working docs there!

There will be boring and depressing phases when you learn slower and even feel going backwards (you realize how much you don't know and it feels bad :)). And then there are those awesome moments when you feel like everything is possible and you just want to build and learn more. Most important thing is to keep building stuff. There are those wizard brain lies that keep telling people that they don't know and they will never know something - that they are just incompetent for doing stuff like coding/painting/music etc. "You are just a designer, don't bother trying to code something yourself, it will never work" or just the opposite: "You are just a developer, don't even try to build something beautiful or even usable"... how much better software we would have without lies like that? :)

#23 martinluff

martinluff

    Full Member

  • Members
  • PipPipPip
  • 79 posts
  • 2

  • LocationChristchurch NZ

Posted 14 November 2011 - 08:03 PM

OK Antti, I think I'm in the depressing stage at this point  ;)

In response to your suggestion here's my mutilated version of slkwrm's beautiful code; in which I'm trying to append a simple 'item-active' class on the current item (adding 'parent-active' on any parent's of the current item would be a bonus):

<?php function treeMenu(Page $page = null, $depth = 1, $id = null) {
            $depth -= 1;
            if(is_null($page)) $page = wire('page');
            if(!is_null($id)) $id = " id='$id'";

            $out = "\n<ul$id>";

            // This is where we get pages we want. You could just say template!=news-item or list the templates you do want
            foreach($page->children() as $child) {
                    $class = "level-" . count($child->parents);
                    $s = '';
                    if($child->numChildren && $depth > 0 ) {
                            $s = str_replace("\n", "\n\t\t", treeMenu($child, $depth));
                        if ($child === $page) { 
                                $class .= " current"; 
                        }
                    }

                    $class .= " page-{$child->id}";
                    $class = " class='$class'";
                    $out .= "\n\t<li$class>\n\t\t<a$class href='{$child->url}'>{$child->title}</a>$s\n\t</li>";
            }
        $out .= "\n</ul>";
  
        return $out;
}

//parameters: current page, menu depth, ul menu id
$menu = treeMenu($page->rootParent, 4, "myMenu");

So from my reading of it and looking at the linked article in Ryan's post (http://processwire.c...790.html#msg790) I'm guessing the argument to test if it should append the active class needs to be in the loop plus needs to work out when current page is same as $child?

Here's another attempt:

<?php
function treeMenu(Page $page = null, $depth = 1, $id = null) {
            $depth -= 1;
            if(is_null($page)) $page = wire('page');
            if(!is_null($id)) $id = " id='$id'";

            $out = "\n<ul$id>";


            // This is where we get pages we want. You could just say template!=news-item or list the templates you do want
            foreach($page->children() as $child) {
                    $class = "level-" . count($child->parents);
                    $s = '';
                    if($child->numChildren && $depth > 0 && $child->id === $page->$id) {
                        $class .= " current";
                        $s = str_replace("\n", "\n\t\t", treeMenu($child, $depth));
                    } else if ($child->numChildren && $depth > 0) {
                        $class .= "";
                        $s = str_replace("\n", "\n\t\t", treeMenu($child, $depth));
                    }

                    $class .= " page-{$child->id}";
                    $class = " class='$class'";
                    $out .= "\n\t<li$class>\n\t\t<a$class href='{$child->url}'>{$child->title}</a>$s\n\t</li>";
            }
        $out .= "\n</ul>";
  
        return $out;
}

//parameters: current page, menu depth, ul menu id
$menu = treeMenu($page->rootParent, 4, "myMenu");

echo $menu;

If someone could sort out where I'm going wrong (I'm not even sure if it's my argument for detecting when page and child are the same or my placement of the arguments or if I'm just way off track) that would be much appreciated  :)



#24 Soma

Soma

    Hero Member

  • Moderators
  • 3,186 posts
  • 1739

  • LocationSH, Switzerland

Posted 15 November 2011 - 03:39 AM

it's as simple as checking for if the current looped $child is in parents of the current page:

<?php

if($page->parents->has($child) ....)

// may look like this with a fully check
if($page->parents->has($child) || $child === $page || $child === $page->parent) $status = " $class=' on'"; else $class = '';


Since $page->parents returns an array has "has" does check if it's in there.. you got what you look for.
Just think about it for a second, it will be clear as water after you use it sometime.


// not tested but should work I think
<?php
function treeMenu(Page $page = null, $depth = 1, $id = null) {
            $depth -= 1;
            if(is_null($page)) $page = wire('page');
            if(!is_null($id)) $id = " id='$id'";

            $out = "\n<ul$id>";
 
            // This is where we get pages we want. You could just say template!=news-item or list the templates you do want
            foreach($page->children() as $child) {
 
                    $class = "level-" . count($child->parents);
                    $s = '';
 
                    if($child->numChildren && $depth > 0) {
                        $s = str_replace("\n", "\n\t\t", treeMenu($child, $depth));
                    } 

                    if(wire("page")->parents->has($child) || wire("page") === $child || $child === wire("page")->parent){
                        $class .= " current";
                    } else {
                        $class = '';
                    }
 
                    $class .= " page-{$child->id}";
                    $class = " class='$class'";
                    $out .= "\n\t<li$class>\n\t\t<a$class href='{$child->url}'>{$child->title}</a>$s\n\t</li>";
            }
        $out .= "\n</ul>";

        return $out;
}

//parameters: current page, menu depth, ul menu id
$menu = treeMenu($page->rootParent, 4, "myMenu");

echo $menu; 


EDIT: modified code a little... there was something double. And to check for $page, I didn't first recognize it, but in this case to check for current page in the function scope it has to be wire("page")->parents ... I testet and it works now. Current page and its parent get the class "current".

@somartist | modules created | support me, flattr my work flattr.com


#25 martinluff

martinluff

    Full Member

  • Members
  • PipPipPip
  • 79 posts
  • 2

  • LocationChristchurch NZ

Posted 15 November 2011 - 09:40 PM

Thanks a bundle Soma  :) I get the logic - thanks for explaining and taking the time to give a working example, need to read the code a few times to understand it in practice but examples like this help a lot. That will be a really useful bit of re-usable code for me (and probably some others). Cool...

Edit: OK, have had a bit more time with the code now... that's great. See I never would have thought it would be a simple solution like that  :) Thanks again.

#26 newbie140

newbie140

    Newbie

  • Members
  • Pip
  • 7 posts
  • 0

Posted 04 June 2012 - 04:53 AM

Hi, I'm new to PW and php, and i need your help guys. My problem is im trying to include the "Home" menu to this code below that
slkwrm posted..can anyone help me?..tnx



function treeMenu($page, $depth = 1, $id = null) {
$depth -= 1;
if(is_null($page)) $page = wire('page');
if(!is_null($id)) $id = " id='$id'";
$out = "\n<ul$id>";
$parents = $page->parents;
// This is where we get pages we want. You could just say template!=news-item
foreach($page->children() as $child) {
$class = "level-" . count($child->parents);
$s = '';
if($child->numChildren && $depth > 0 ) {
$s = str_replace("\n", "\n ", treeMenu($child, $depth));
}
$class .= " page-{$child->id}";
$class = " class='$class'";
$out .= "\n <li$class>\n <a$class href='{$child->url}'>{$child->title}</a>$s\n </li>";
}
$out .= "\n</ul>";
return $out;
}
//parameters: current page, menu depth, ul menu id
$menu = treeMenu($pages->get("/"), 2, "myMenu");
echo $menu;



#27 newbie140

newbie140

    Newbie

  • Members
  • Pip
  • 7 posts
  • 0

Posted 04 June 2012 - 09:37 PM

If it's still relevant. I took Apeisa's code from the above-mentioned topic and modified it a bit and it seems to work the way you wanded, Soma :)

<?php

function treeMenu(Page $page = null, $depth = 1, $id = null) {

            $depth -= 1;
           
            if(is_null($page)) $page = wire('page');
            if(!is_null($id)) $id = " id='$id'";

            $out = "\n<ul$id>";

            $parents = $page->parents;

            // This is where we get pages we want. You could just say template!=news-item
            foreach($page->children() as $child) {
                    $class = "level-" . count($child->parents);
                    $s = '';
                    if($child->numChildren && $depth > 0 ) {
                            $s = str_replace("\n", "\n		", treeMenu($child, $depth));
                    }

                    $class .= " page-{$child->id}";
                    $class = " class='$class'";
                    $out .= "\n	<li$class>\n		<a$class href='{$child->url}'>{$child->title}</a>$s\n	</li>";
            }
        $out .= "\n</ul>";
 
        return $out;
}

//parameters: current page, menu depth, ul menu id
$menu = treeMenu($page, 3, "myMenu");

echo $menu;

You shoud pass depth as a second parameter. By default it will output only one level.

Edit: optimized code a bit

I like this code, but i need the "Home" menu to be always included...thanks..please help..

#28 diogo

diogo

    Hero Member

  • Moderators
  • 1,982 posts
  • 1061

  • LocationPorto, Portugal

Posted 05 June 2012 - 03:43 AM

Welcome newbie :)

I did a small change to the code, so it includes the self page on the tree.

EDIT: the code I posted wasn't working. Using the same code you posted here, just change the end (after the function closes) to this:

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

$menu = treeMenu($homepage, 3, "");

echo "<ul id='myMenu'>";
echo "<li class='level0'><a class='level0' href='{$homepage->url}'>{$homepage->title}</a>";
echo $menu;
echo "</li></ul>";

This is not a very elegant way of doing this. Would be best to change the function. But it works.

Edited by diogo, 05 June 2012 - 04:09 AM.


#29 newbie140

newbie140

    Newbie

  • Members
  • Pip
  • 7 posts
  • 0

Posted 06 June 2012 - 02:42 AM

Thanks very much diogo...but it doesnt work the way i want it...my point is to include the "Home" menu together with other menus...thanks for your help

#30 diogo

diogo

    Hero Member

  • Moderators
  • 1,982 posts
  • 1061

  • LocationPorto, Portugal

Posted 06 June 2012 - 02:48 AM

I'm not sure if i understand. What do you mean by together? Can you put a scheme of what you want here?

#31 newbie140

newbie140

    Newbie

  • Members
  • Pip
  • 7 posts
  • 0

Posted 06 June 2012 - 04:05 AM

hi drogo..thanks for discussing with me...

Home About Media Bills & Resolutions Publications Projects Gallery Contact Us

thats what i want..even if i will go to "about" page or other page, the navigation structure will still looks the same...thanks

#32 Soma

Soma

    Hero Member

  • Moderators
  • 3,186 posts
  • 1739

  • LocationSH, Switzerland

Posted 06 June 2012 - 04:55 AM

Sorry to disrupt you discussion. Why not simply use https://github.com/s...impleNavigation ?

@somartist | modules created | support me, flattr my work flattr.com


#33 newbie140

newbie140

    Newbie

  • Members
  • Pip
  • 7 posts
  • 0

Posted 06 June 2012 - 05:49 AM

Thank you very much Soma...but i only need to display the treemenu up to the 2nd level only at th homepage page...tnx

#34 diogo

diogo

    Hero Member

  • Moderators
  • 1,982 posts
  • 1061

  • LocationPorto, Portugal

Posted 06 June 2012 - 06:04 AM

I'm still a bit confused with what you need... still, another try:


function treeMenu(Page $page = null, $depth = 1, $id = null) {

    $depth -= 1;
				  
    if(is_null($page)) $page = wire('page');
    if(!is_null($id)) $id = " id='$id'";

    $out = "\n<ul$id>";
    $out .= "\n	 <li class='level-1'>\n			<a  class='level-1' href='{$homepage->url}'>{$homepage->title}</a>\n   </li>"; // added the homepage here					  

    $parents = $page->parents;

    // This is where we get pages we want. You could just say template!=news-item
    foreach($page->children() as $child) {
        $class = "level-" . count($child->parents);
        $s = '';
        if($child->numChildren && $depth > 0 ) {
            $s = str_replace("\n", "\n			  ", treeMenu($child, $depth));
        }

        $class .= " page-{$child->id}";
        $class = " class='$class'";
        $out .= "\n	 <li$class>\n			<a$class href='{$child->url}'>{$child->title}</a>$s\n   </li>";
    }
    $out .= "\n</ul>";

    return $out;
}

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

//parameters: current page, menu depth, ul menu id
$menu = treeMenu($homepage, 2, "myMenu"); // this will make the menu be the same in any page

echo $menu;


#35 Soma

Soma

    Hero Member

  • Moderators
  • 3,186 posts
  • 1739

  • LocationSH, Switzerland

Posted 06 June 2012 - 07:08 AM

Thank you very much Soma...but i only need to display the treemenu up to the 2nd level only at th homepage page...tnx


That's what can be done with this module pretty easily.

if($page->template == "home"){
	$options = array(
		'max_levels' => 2,
		'show_root' => true
	);

	echo $treeMenu->render($options);
}

https://github.com/s...n-Documentation

@somartist | modules created | support me, flattr my work flattr.com


#36 newbie140

newbie140

    Newbie

  • Members
  • Pip
  • 7 posts
  • 0

Posted 06 June 2012 - 07:24 AM

Thank you very much Soma and drogo for your help..i've already modified the simpleNavigation module to display what i want....thanks more power...


Thanks again Soma, that's exactly what i did in the module...forgive me im weak in php...hehehe....thanks

#37 Soma

Soma

    Hero Member

  • Moderators
  • 3,186 posts
  • 1739

  • LocationSH, Switzerland

Posted 06 June 2012 - 07:53 AM

Thank you very much Soma and drogo for your help..i've already modified the simpleNavigation module to display what i want....thanks more power


What did you modify if I might ask? :)

@somartist | modules created | support me, flattr my work flattr.com





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users