Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Function: multi-level navigation. / Plugin for version 2!
#1
USING GETSIMPLE VERSION 2.0 AS YOU SHOULD?
STILL WANT TO USE MY MULTI-LEVEL NAVIGATION?
GET THE PLUGIN — READ MORE.

As this seems to be a problem I shared with many others I thought it might be nice to publish my solution.

The problem is simple to explain. GetSimple offers a way to assign pages to certain parents, but the menu function doesn't built the menu accordingly. With this function it will!

I have to point out that I'm a little ill and wrote this within the last hour to throw into my own template, so please tell me if you notice any faults!

How to use it.

Really easy, just call this function instead of the standard one that comes with GetSimple. The standard get_navigation() is normally used as followed:
Code:
get_navigation(return_page_slug());
My function is used like this:
Code:
menu_master();
You will find the function at the bottom of this post, just put it in your template's functions.php.

What HTML does it generate?

Very important to know once you start adding CSS to spruce it up. Here is the HTML generated when I'm on subpage-2. I think this is nice and clear HTML for generic use. The HTML outputted by the function does not include any white space at all!
Code:
<ul class="menu">
  <li>
    <a href="http://example.com/">Home</a>
  </li>
  <li class="parent">
    <a href="http://example.com/page-1">First page</a>
    <ul class="submenu">
      <li>
        <a href="http://example.com/page-1/subpage-1">First sub-page</a>
      </li>
      <li class="active">
        <a href="http://example.com/page-1/subpage-2">Second sub-page</a>
      </li>
      <li>
        <a href="http://example.com/page-1/subpage-3">Third sub-page</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="http://example.com/page-2">Second page</a>
  </li>
  <li>
    <a href="http://example.com/page-3">Third page</a>
  </li>
  <li>
    <a href="http://example.com/page-4">Fourth page</a>
    <ul class="submenu">
      <li>
        <a href="http://example.com/page-4/subpage-4">Fourth sub-page</a>
      </li>
      <li>
        <a href="http://example.com/page-4/subpage-5">Fifth sub-page</a>
      </li>
    </ul>
  </li>
  <li>
    <a href="http://example.com/page-5">Fifth page</a>
  </li>
</ul>

Edits.

2009-11-16 22:40 (GMT+1):
  • Fixed the fact that li-elements were not being closed.
  • Removed a double semi-colon on one of the lines.
  • Added extra classes, see the example HTML. [Requested by Texta]
2009-11-18 16:56 (GMT+1)
  • Fixed li-elements being closed before the submenu is added. [Pointed out by Patricia]
2009-11-18 20:54 (GMT+1)
  • Removed subval_sort(). [Adviced by n00dles101]

The function as is.

I provide this function as it is. I will probably update it when a GetSimple update breaks it or when others come up with suggestions, but I won't promise that. If anything suddenly wipes your system clean when you use this, don't look at me either.
Code:
function menu_master() {
        $data = simplexml_load_string(menu_data('',true));
        $menu = $data->xpath('//*[menuStatus="Y"][parent=""]');
        if (count($menu)>0) {
            echo '<ul class="menu">';
            foreach ($menu as $link) {
                if ("$link->slug"=="") $link->slug = "index";
                $prnt = count($data->xpath('//item[slug="'.return_page_slug().'"][parent="'.$link->slug.'/"]'));
                echo '<li'.("$link->slug"==return_page_slug()?' class="active"':($prnt>0?' class="parent"':'')).'><a href="'.$link->url.'">'.($link->menu!=""?$link->menu:$link->title).'</a>';
                $menu = $data->xpath('//*[menuStatus="Y"][parent="'.$link->slug.'/"]');
                if (count($menu)>0) {
                    echo '<ul class="submenu">';
                    foreach ($menu as $link) {
                        echo '<li'.("$link->slug"==return_page_slug()?' class="active"':'').'><a href="'.$link->url.'">'.($link->menu!=""?$link->menu:$link->title).'</a></li>';
                    }
                    echo '</ul>';
                }
                echo '</li>';
            }
            echo '</ul>';
        }
    }
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#2
Thanks a lot. It works. Got errors first, but I set up the cms new and integrated your bugfixes http://get-simple.info/forum/viewtopic.php?id=213, so it works now. Must have been something else wrong.

Edit: two things...

1. it's sorted the other way round then the GS build-in function - the page with the highest priority get's displayed at the end of the list.

2. it would be really usefull to have some 'class' added to the list and the submenu list, too. Because
<li class="parent"> is only added to the direct-parent of the sub-page, when I'm on a sub-page.
All the other times, there's no class added - strangely enough. Because in your example, I see at least the <li class="parent"> set correctly.
Reply
#3
First let me thank you for this.

Anyway it is not working atm. As Texta says the Navigation order is now reversed.

The second problem is that my subpages are not displayed when i hold the mouse over a parentpage.

Should'nt it do so?
Reply
#4
exmethix Wrote:subpages are not displayed when i hold the mouse over a parentpage.
exmethix, have you any CSS declared? Because that's rather strange...

Anyway; I modified the function a bit:
Code:
if (count($menu)>0) {
                    echo '<ul class="sub_menu">';
So now (well all) the sub-pages have the class 'sub_menu' added.
Reply
#5
Texta Wrote:It's sorted the other way round then the GS build-in function - the page with the highest priority get's displayed at the end of the list.
exmethix Wrote:Anyway it is not working atm. As Texta says the Navigation order is now reversed.
This is odd. I better run some tests on that and will report back.

It is very weird because I use the same sorting function as get_navigation() uses. The official function uses this:
Code:
$pagesSorted = subval_sort($pagesArray,'menuOrder');
And I use this:
Code:
$menu = subval_sort($data->xpath('//*[menuStatus="Y"][parent=""]'),'menuOrder');
Same function is used to sort the elements, subval_sort(), which I did not change myself.

Texta Wrote:It would be really usefull to have some 'class' added to the list and the submenu list, too. Because
<li class="parent"> is only added to the direct-parent of the sub-page, when I'm on a sub-page.
All the other times, there's no class added - strangely enough. Because in your example, I see at least the <li class="parent"> set correctly.
This is due to the way I use it. I wanted to be able to give alternative styling to the currently active link, and possibly to its parent. As all the other lists, to me, seem like standard lists and can therefore easily be styled with CSS by targeting them by parent:
Code:
ul { /* menu style. */ }
ul ul { /* sub-menu style. */ }
But I can add this to the script, hang on, I'm fixing another error just now (it doesn't close the li-elements, this doesn't matter for HTML but does for xHTML.)

exmethix Wrote:The second problem is that my subpages are not displayed when i hold the mouse over a parentpage.

Should'nt it do so?
No, it shouldn't. It should already be displaying all your sub-menus by default. It is up to you to hide them and make them pop-up on mouse over.
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#6
Zegnåt Wrote:As all the other lists, to me, seem like standard lists and can therefore easily be styled with CSS by targeting them by parent:
Code:
ul { /* menu style. */ }
ul ul { /* sub-menu style. */ }
But I can add this to the script...

Well, thanks for that hint. I didn't know it was possible to use a "sub-level" like "ul ul" in CSS. That helps a lot.
Still, I have to figure out how to hide the sub-menu normally and how to have it pop up, while hovering or selecting the parent.
Guess it'll work with
Code:
li. active
li. parent

Thanks for the work!
Reply
#7
Well, I edited the function to support your suggested classes as well.
Texta Wrote:Still, I have to figure out how to hide the sub-menu normally and how to have it pop up, while hovering or selecting the parent.
Code:
.menu .submenu { display: none; }
.menu .active .submenu,
.menu .parent .submenu,
.menu li:hover .submenu { display: block; }
Untested but I hope that will get you started. (Using classes from the updated function.)
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#8
Zegnåt Wrote:I hope that will get you started.
Wow! I bet it will! Thank you very (!) much. I'll try it soon and will report, if it works!

Edit: it does do a great job! classes are dsiplayed correctly, as far as I figured out! Thanks again.
Reply
#9
wonderful, thanks a lot, I will test it today!
Patricia
Reply
#10
Texta Wrote:It does do a great job! classes are dsiplayed correctly, as far as I figured out! Thanks again.
If you are just running my CSS please keep in mind that Internet Explorer 6 (everybody’s favourite browser) won’t understand it. This is because it only supports :hover on the a-element while we need to use it on the li-element to get the effect you want.

Felt like I had to point that out.

Patricia Wrote:wonderful, thanks a lot, I will test it today!
Be sure to let me know how it turns out for you!
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#11
tested, it's almost perfect Smile on my test, it does close the </li> before the submenu <ul>, and it shouldn't, the closing </li> should be after the closing submenu </ul> (or am I wrong?)... it's correct in your 1st post example

tack Wink
Patricia
Reply
#12
Patricia Wrote:On my test, it does close the </li> before the submenu <ul>, and it shouldn't, the closing </li> should be after the closing submenu </ul> (or am I wrong?)...
Are you running the function as it is now in the first post?
If you are having, or think you are having, problems with the HTML it gives could you please post your HTML so I can take a look?
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#13
Zegnåt Wrote:Are you running the function as it is now in the first post?
If you are having, or think you are having, problems with the HTML it gives could you please post your HTML so I can take a look?

Yes I do. And I even copied it again after your question Smile

The output is not formated, and has the issue I mention, furthermore, the pages are in reverse order

Code:
<ul class="menu"><li><a href="http://localhost/process/GetSimple/page-3">Page 3</a></li><li><a href="http://localhost/process/GetSimple/page-2">Page 2</a></li><ul class="submenu"><li><a href="http://localhost/process/GetSimple/page-2/sub2">sub2</a></li></ul><li class="active"><a href="http://localhost/process/GetSimple/">Home</a></li></ul>



if I format better reading :
Code:
<ul class="menu">
        <li>
            <a href="http://localhost/process/GetSimple/page-3">Page 3</a>
        </li>
        <li>
            <a href="http://localhost/process/GetSimple/page-2">Page 2</a>
        </li>
            <ul class="submenu">
                <li>
                    <a href="http://localhost/process/GetSimple/page-2/sub2">sub2</a>
                </li>
            </ul>
        <li class="active">
            <a href="http://localhost/process/GetSimple/">Home</a>
        </li>
    </ul>

but it should be (clsing </li> from page-2, after the sub2 submenu, and Home is first, Page 3 is last)

Code:
<ul class="menu">
        <li>
            <a href="http://localhost/process/GetSimple/">Home</a>
        </li>
        <li>
            <a href="http://localhost/process/GetSimple/page-2">Page 2</a>
            <ul class="submenu">
                <li>
                    <a href="http://localhost/process/GetSimple/page-2/sub2">sub2</a>
                </li>
            </ul>
        </li>
        <li class="active">
            <a href="http://localhost/process/GetSimple/page-3">Page 3</a>
        </li>
    </ul>

I have applied priority to pages, if not, even with the standard menu, it appears in another order

Thanks a lot in advance
Patricia
Reply
#14
Hi Patricia, I think it's fine, closing the <li> before the the sub-<ul>. Do you experience any problems with that?
Reply
#15
Texta Wrote:Hi Patricia, I think it's fine, closing the <li> before the the sub-<ul>. Do you experience any problems with that?

I think it's actually not a valid code, for my test, W3c validator will say :
Code:
Line 30, Column 183: document type does not allow element "ul" here; assuming missing "li" start-tag

…">Page 2</a></li><ul class="submenu"><li><a href="http://localhost/process/Ge

edit: info here http://www.w3schools.com/XHTML/xhtml_html.asp
Patricia
Reply
#16
Looks like you're right (XHTML).
Reply
#17
Thanks Patricia, I updated the script in the first post accordingly. Apparently I really can't code right when sick!
Patricia Wrote:I have applied priority to pages, if not, even with the standard menu, it appears in another order
Yes, there is something wrong with the sorting. As I stated earlier, I have no clue about this yet. Will probably end up writing my own sorting function for this later.
Patricia Wrote:I think it's actually not a valid code
Very true, an ul-element should only have li-elements as childs.
Texta Wrote:Looks like you're right (XHTML).
This also goes for standard HTML, not just XHTML. It was simply a mistake I made in the function.
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#18
My Bad.... I included this in my original functions and never even noticed the sorting problem....

the sorting function will not work properly on the returned XML data, it's only for Arrays.

I have something that should work, will post once I test.

Mike...

^^^^^ Scrub this see my post below... Big Grin
My Github Repos: Github
Website: DigiMute
Reply
#19
menu_data function already sorts the returned XML data on menuOrder so there is no need to sort it again,
just change the top 2 lines and replace with

Code:
function menu_master() {
        $data = simplexml_load_string(menu_data('',true));
        $menu = $data->xpath('//*[menuStatus="Y"][parent=""]');
        if (count($menu)>0) {
            echo '<ul class="menu">';
            foreach ($menu as $link) {
                if ("$link->slug"=="") $link->slug = "index";
                $prnt = count($data->xpath('//item[slug="'.return_page_slug().'"][parent="'.$link->slug.'/"]'));
                echo '<li'.("$link->slug"==return_page_slug()?' class="active"':($prnt>0?' class="parent"':'')).'><a href="'.$link->url.'">'.($link->menu!=""?$link->menu:$link->title).'</a>';
                $menu = $data->xpath('//*[parent="'.$link->slug.'/"]');
                if (count($menu)>0) {
                    echo '<ul class="submenu">';
                    foreach ($menu as $link) {
                        echo '<li'.("$link->slug"==return_page_slug()?' class="active"':'').'><a href="'.$link->url.'">'.($link->menu!=""?$link->menu:$link->title).'</a></li>';
                    }
                    echo '</ul>';
                }
                echo '</li>';
            }
            echo '</ul>';
        }
    }

EDIT: ************ IGNORE BELOW THIS, I'm talking rubbish....

Not sure about the second submenu query? Why are you checking for menuStatus=Y for the submenu, will this not be off ??

They way I do it is,

o - create all the top level pages and set the menu order as normal.
o - for each page as a submenu, just create the page and set the parent to be to top level menu.

Also function won't work for us poor unfortunates who cant use prettyUrls.... Smile

Mike
My Github Repos: Github
Website: DigiMute
Reply
#20
EDIT: ************ IGNORE THIS, more rubbish....

To order the submenu items you can do the follwoing.

o - click page option on the submenu page
o - click on "add to menu'
o - select a priority
o - click off add to menu.
o - save it, it will save the priority.

Sub menu items wil then be sorted also..

Mike...
My Github Repos: Github
Website: DigiMute
Reply
#21
n00dles101 Wrote:menu_data function already sorts the returned XML data on menuOrder so there is no need to sort it again
I now removed the subval_sort() from my function. But I will still be writing my own sorting script as I don’t feel like this one works so well. I need alphabetic sorting for when menuOrder is failing.

n00dles101 Wrote:Not sure about the second submenu query? Why are you checking for menuStatus=Y for the submenu, will this not be off?
Of course not, that would beat the purpose of being able to say whether a page should show in the menu or not. GetSimple gives you the choice to add a certain page to the menu. If you don’t check it the page should not appear in the menu. This goes just as much for sub pages as it goes for the top level pages.

n00dles101 Wrote:Also function won't work for us poor unfortunates who cant use prettyUrls…
If it doesn’t then I apologise. Then again, I’m just offering this as is and as I myself never go with queries in the page URLs I will probably not go back to change that. At least not yet.

n00dles101 Wrote:To order the submenu items you can do the follwoing.
That should already be supported by my function right? Because you need to have “add to menu” checked for it to work anyway.
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#22
There must have been something in the coffee this morning...
not thinking straight at all ...

scrap everything I posted in those postsl.... except for removing the sort...

Mike....
My Github Repos: Github
Website: DigiMute
Reply
#23
Zegnåt Wrote:Thanks Patricia, I updated the script in the first post accordingly. Apparently I really can't code right when sick!

Thank you ver much Zegnåt, it's now working perfectly for me!! Sick or not, at least you code! and on this, you save my life Big Grin

the only "strange" thing now, is the date of script update in the first post
2009-10-19 20:54 (GMT+1), should be 2009-11-18 20:54 (GMT+1) Wink
(I was lost at first : the script posted 2 days ago, but updated 1 month ago Smile )
Patricia
Reply
#24
n00dles101 Wrote:scrap everything I posted in those posts… except for removing the sort…
As I am too hard headed anyway I wasn't planning to change more than the sorting. Still good to hear we're on the same page now.

Patricia Wrote:Thank you very much Zegnåt, it's now working perfectly for me!
Great! Is the order of the menu items right now too, since I took away the sorting function?

Patricia Wrote:the only "strange" thing now, are the dates of script updates in the first post
Thank you for noticing, I changed them.
“Don’t forget the important ˚ (not °) on the a,” says the Unicode lover.
Help us test a key change for the core! ¶ Problems with GetSimple? Be sure to enable debug mode!
Reply
#25
Quote:Is the order of the menu items right now too, since I took away the sorting function?
Well, I'm not Patricia, but I can tell you: the menu is in order now.
Thanks a lot Zegnåt & n00dles101!
Reply




Users browsing this thread: 2 Guest(s)