MarcC Posted December 14, 2011 Share Posted December 14, 2011 I have an automatically-generated menu that is probably pretty typical for ProcessWire sites--looping through the children and putting the URL inside the <a> tags, etc. My client has asked that one child menu item be essentially a symlink that points to another child page under a different parent. Like so: About Our Club History Rock Music History of Rock (Points to the History page, above, or #rockmusic on that page) The current code for the menu is this, from a post on the forum: <div class="menu"> <?php // Let's build ourselves a menu. if(strstr($_SERVER['HTTP_USER_AGENT'],’iPad’) || strstr($_SERVER['HTTP_USER_AGENT'],’iPod’) || strstr($_SERVER['HTTP_USER_AGENT'],’iPhone’)) { // iPhone, iPod, or iPad. $mobile = 1; } function listChildrenTree($children) { foreach($children as $c) { echo "<ul class='{$c->name}'>"; echo "<li><a href='". ($mobile == 1 ? '#': $c->url) ."'>{$c->title}</a>"; if($c->numChildren) { // Render submenus (dropdowns) echo "<ul class='sub'>"; foreach($c->children as $subpage) { echo "<li><a href='{$subpage->url}'>{$subpage->title}</a> "; } echo "</ul>"; } echo "</li>"; echo "</ul>"; } } listChildrenTree($pages->get('/')->children); ?> </div><!-- menu --> Advice? Thanks. Link to comment Share on other sites More sharing options...
Pete Posted December 14, 2011 Share Posted December 14, 2011 Change this bit to do the following: foreach($c->children as $subpage) { if ($subpage->name == 'history-of-rock') { echo "<li><a href='{$c->url}#rockmusic'>{$subpage->title}</a> "; } else { echo "<li><a href='{$subpage->url}'>{$subpage->title}</a> "; } } I think that will do it. Not sure if the dashes are required when checking for history-of-rock - think I'm right as the name is the SEO-friendly title of the page. Link to comment Share on other sites More sharing options...
ryan Posted December 14, 2011 Share Posted December 14, 2011 Another option, if you want something you can reuse anytime: 1. Create a new field and call it 'redirect_url' or something like that, and use the 'URL' fieldtype. 2. Add that field to your template where you'd want to use it, or create a new template just for the purpose, like a template named 'redirect'. 3. Edit the page that you want to be a symlink and populate the 'redirect_url' field with the URL you want it to redirect to. 4. In your nav-generation code that links to the pages, do something like this: <?php $url = $subpage->get("redirect_url|url"); // use redirect_url if there, otherwise use url echo "<a href='$url'>{$subpage->title}</a>"; 5. You might also want to add this to your template that has the 'redirect_url' field: just in case there's anything linking to it directly. That way it'll send people to the right place either way: <?php if($page->redirect_url) $session->redirect($page->redirect_url); 2 Link to comment Share on other sites More sharing options...
Pete Posted December 14, 2011 Share Posted December 14, 2011 Oh yeah, much better solution ryan - I keep forgetting how flexible fields and templates are Link to comment Share on other sites More sharing options...
MarcC Posted December 14, 2011 Author Share Posted December 14, 2011 Very cool idea, Ryan. I'll give it a try. Thanks to both of you. Link to comment Share on other sites More sharing options...
formmailer Posted December 15, 2011 Share Posted December 15, 2011 Great idea! I have a similar (but different) problem: I need to do this for quite large part of the navigation tree. Example: Holiday - Transport -- Bus -- Airplane -- Car Some other page Transport - Bus - Airplane - Car Of course I can use Ryan's method but it would be quite a lot work and, more important, if I add a page under Transport, it has to be added twice. Is there a way to get around this? I currently use this code to create the menu tree: <?php function menuTree($page) { if ($page != wire('pages')->get('/')) { // Don't list home as the parent of every page echo "<li><a href='{$page->url}'>{$page->title}</a> "; } if($page->numChildren) { echo "<ul>"; foreach($page->children as $child) menuTree($child); echo "</ul>"; } } /Jasper Link to comment Share on other sites More sharing options...
Pete Posted December 15, 2011 Share Posted December 15, 2011 I'd go for ryan's suggestion still. It's really not a lot of work. Unless you mean that the second set of identical links will always be identical? In which case why not just add an if statement in your function to check if you're currently outputting the "Some Other Page" menu item and then simply get the Holiday subpages with: $pages->get('/holiday/')->children; and then just loop through them as part of that if statement? If it's just this one place and the submenu is always going to be identical with links back to the holiday sub-pages then that would be the way I'd think about doing it. Link to comment Share on other sites More sharing options...
ryan Posted December 15, 2011 Share Posted December 15, 2011 I'm not sure that I understand the context here well enough to say which is the best path to take. But if you've got trees of nav that you need to repeat in various places, then I wouldn't try to build that as a structure of redirect pages. I think your best bet is just to build that logic into your nav generation function. I've also done this kind of repetition just with jQuery since the links didn't really need to be repeated in the underlying markup. An example is http://villarental.com – it has pull down menus at the top, but if you view the source at look at the top nav UL (#topnav), you'll see there's no markup for it. Some javascript is just duplicating the links from the footer into the topnav. So if your nav repetition is for something that's for look + feel rather than accessibility, consider a little jQuery which probably provides the simplest answer. Link to comment Share on other sites More sharing options...
formmailer Posted December 15, 2011 Share Posted December 15, 2011 Hi! Thanks for your replies. I don't think the jquery is going to solve my (little) problem. I'd might be able to explain the context a bit more with a real life example. My site http://www.zwedenweb.com is a site without CMS that I am converting to Processwire. When you take a look at the navigation menu, you will see "Vakantie in Zweden" (Vacation in Sweden), which contains a submenu called "Vervoer naar Zweden" (Transport to Sweden). This submenu contains exactly the same links like the menu item "Vervoer naar Zweden" at root level. The same goes for the Accommodatie (Accommodations) submenu. Reason for this is that, logically, the best place is under "Vakantie in Zweden", but page visitors wanted to have an quicker way to get to these pages. I hope this explains the question. /Jasper Link to comment Share on other sites More sharing options...
ryan Posted December 15, 2011 Share Posted December 15, 2011 You could hard code that check in your nav output and just say something like: when the page ID is 123, pull in this other nav and display it. If it's something that is going to remain relatively static, that's what I'd do. If not static, you could use a checkbox field instead. But here's an example of how you might do it statically: <?php function menuTree(PageArray $children) { echo "<ul>"; foreach($children as $child) { echo "<li><a href='{$child->url}'>{$child->title}</a>"; // below, 123, 456, 789 are IDs of pages where duplicate nav should appear if(in_array($child->id, array(123, 456, 789)) { // below, 321 is ID of page having the children you want to duplicate $out .= menuTree(wire('pages')->get(321)->children); } else if($child->numChildren) { $out .= menuTree($child->children); } $out .= "</li>"; } $out .= "</ul>"; return $out; } echo menuTree($pages->get("/")->children); Link to comment Share on other sites More sharing options...
formmailer Posted December 15, 2011 Share Posted December 15, 2011 Thanks Ryan! That's exactly what I needed. These submenus are quite static, they have been there since 2001 and will certainly be there the next couple of years. (but the content has changed of course ) /Jasper Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now