Ok.
Please allow me to explain the 'menu-maker' concept a little here.
Assume index.php is a clonable template. Additionally it is also nestable so its cloned pages can be arranged in an hierarchy.
Anyway, now if we use <cms:nested_pages> tag to list pages from this template, the tag goes through the cloned pages and spits out info about them.
This is just the same as using <cms:pages> except that now it also provides info about the hierarchy.
Point is that <cms:nested_pages> tag
can only output info about pages that actually exist as cloned pages of the template (index.php in our example). That is to say, that if a page is not visible in the tree you see for the nested template, it won't/can't be listed using <cms:nested_pages> alone. This should be easy to understand as it cannot possibly list what is not there to begin with.
To understand a second point, let us use <cms:pages> instead of <cms:nested_pages> as you are likely to be more familiar with it.
Take a look at the following code -
- Code: Select all
<ul>
<cms:pages masterpage='index.php'>
<li><a href="<cms:show k_page_link />"><cms:show k_page_title /></a></li>
</cms:pages>
</ul>
It should be easy to see that it is outputting a linear list of pages with links pointing to those pages.
Now suppose we defined a simple text region in the template (say named 'external_link') and use it to input URL of arbitrary pages (on the same site or from elsewhere on the net). Now take a look at the modified version of the code above -
- Code: Select all
<ul>
<cms:pages masterpage='index.php'>
<cms:if external_link >
<cms:set my_link = external_link>
<cms:else />
<cms:set my_link = k_page_link>
</cms:if>
<li><a href="<cms:show my_link />"><cms:show k_page_title /></a></li>
</cms:pages>
</ul>
As you can see, we are checking if a cloned page has a value set for the 'external_link' and use it, instead of k_page_link, in the <A> links.
So suppose a cloned page has 'http://www.google.com' set in the text box, the generated link will point to google instead of the page itself.
Basically now that cloned page is acting as a 'pointer page' - a page pointing to some other existing resource on the net.
When you declare a template as 'nestable', this text region that can be used to input a URL gets defined automatically.
So every cloned page of a nestable template can be used as a pointer-page. Which only means that it can store a link to any other resource on the net (it could be on the same site or anywhere).
So the two points that I stressed upon above are -
1. <cms:nested_pages> tag can only output info about pages that actually exist as cloned pages of the template (i.e. are visible in the tree).
2. Each of the above pages is capable of storing URL of any other page (i.e. act as a pointer-page).
With that understood we can finally tackle the problems that are stumping you.
just need to understand how to say This History page that is a sub of the About page loads the about.php template and content associated with that page
In the admin panel you'll see all cloned pages of 'about.php' template listed. The 'history' page would be one of them. If you click on the magnifying glass icon next to the 'history' page, the browser will, of course, show you the history page with all its data. In fact, Couch has loaded "the about.php template and content associated with that page" for you.
Now, following the two points we made just a while back, if we were to create a cloned page of our nestable-template (say named 'History') and make it point to the URL of the page we just visited above, when <cms:nested_pages> lists the cloned pages of index.php, the page named 'History' will simply be pointing to the original 'History' page. This way we have added the history page belonging to 'about.php' in our menu created using 'index.php'.
To reiterate - to add a menu item that points to another page, you have to create a cloned-page and make it point to the other page.
This could have been done with a slicker interface like drag-n-drop but essentially this is what would need to be done.
I hope this has made the concept of menu somewhat clearer.
That said, I agree that it would be chore to add a new page in the menu every time you create a page elsewhere but please consider this -
One is likely to add only a very finite number of pages in the menu (it seems highly unlikely that you'd add all blog posts in the menu).
For templates with large number of cloned-pages, it is usually sufficient to add only a single entry in the menu (e.g. showing 'Blog') that points to the home-view of that template. For templates with smaller number of cloned-pages, it shouldn't be too painful to add a separate menu entry in the tree pointing to the pages that would be visible in the menu.
If, however, you'd really want to 'dynamically' show cloned pages from other template in the menu without manually creating an entry for each, we can do that throwing in a bit of <cms:pages> in the mix. Allow me to explain how.
Suppose you have two templates 'about-us.php' and 'news.php' and you'd want cloned pages of both to appear dynamically in the menu.
To do that create two normal menu entries pointing to the home-views of both templates. Name these two pages 'about-us' and 'news' (please note that these match exactly the names of the two templates except for the '.php' extension). Those were the 'names' - you can set the 'titles' to anything you wish.
Normally you'd use the following code to list pages from the nestable template to create the menu (this is a little simplified for explanation purpose)
- Code: Select all
<cms:nested_pages masterpage='index.php' extended_info='1' >
<cms:if k_level_start ><ul></cms:if>
<cms:if k_element_start ><li>
<a href="<cms:show k_menu_link />"><cms:show k_menu_title /></a>
</cms:if>
<cms:if k_element_end ></li></cms:if>
<cms:if k_level_end ></ul></cms:if>
</cms:nested_pages>
The meat of the code above lies in the <cms:if k_element_start > block where we list the actual names of the pages.
We'll make the following changes to that code -
- Code: Select all
<cms:if k_element_start ><li>
<a href="<cms:show k_menu_link />"><cms:show k_menu_title /></a>
<cms:if k_is_pointer && (k_nestedpage_name='about-us' || k_nestedpage_name='news') >
<ul>
<cms:pages masterpage="<cms:show k_nestedpage_name />.php">
<li><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></li>
</cms:pages>
</ul>
</cms:if>
</cms:if>
As you can make out, in that block we check if the page being pointed to is either 'about-us' or 'news' and then we introduce a <cms:pages> block to loop through those templates and output their cloned pages.
The technique above can be refined to take folders into consideration too (as @trendoman wanted) and also to dynamically highlight the selected page. Since that is regular coding, I leave that to you.
Of course, the code above would list *all* cloned pages of the two templates. One of your requirement was to allow the user the ability to control which pages shows up in the menu.
To do that, define the following in both the templates (it is important to do so in both) -
- Code: Select all
<cms:editable name='my_show_in_menu' label='Show in menu' desc='tick if this page appears in the menu' opt_values='Yes=1' type='checkbox' order='200'
/>
now on each cloned-page of both the templates, you'll see a checkbox that can be set if the page is to be listed in the menu.
On the front-end, our code will now become as follows to take the checkbox into consideration -
- Code: Select all
<cms:if k_element_start ><li>
<a href="<cms:show k_menu_link />"><cms:show k_menu_title /></a>
<cms:if k_is_pointer && (k_nestedpage_name='about' || k_nestedpage_name='contact') >
<ul>
<cms:pages masterpage="<cms:show k_nestedpage_name />.php" custom_field="my_show_in_menu=1">
<li><a href="<cms:show k_page_link />"><cms:show k_page_name /></a></li>
</cms:pages>
</ul>
</cms:if>
</cms:if>
It has been a very long post but I sincerely hope it helps.