Problems, need help? Have a tip or advice? Post it here.
9 posts Page 1 of 1
hello all. I am using folders with subfolders for the first time and have scoured the docs and forum and cannot put together the code to work for what must be a relatively common scenario. In other words I've hit a brick wall and my head hurts!

It is a website for a singer and the Repertoire is a cloned page with dynamic folders. I've set up 2 parent folders Song and Opera. There is only one level of folders for Opera but I've created 3 subfolders for Song, say Song1 Song2 and Song3. There is nothing contained in the top level folder for Song.

I want the Repertoire navigation to have 2 levels:

1. Opera / Song

2. if there are subfolders show these only for the active link - so when current link is Song we'll also see Song1 / Song2 / Song3 (suitably styled as subnavigation links underneath Opera / Song)

When Opera is clicked I want to show the contents of that folder.
When Song is clicked I want to show the contents of Song1 by default. Then Song1, Song2, Song3 when clicked would show their respective contents.

I've fiddled about with all sorts to get this working and it won't come together - any help appreciated! Thanks.
Hi,

Perhaps the following will provide you with some pointers -
Code: Select all
<!-- show top-level folders (i.e. 'opera' and 'song') -->
<cms:folders hierarchical='1' depth='1' >
    <a href="<cms:show k_folder_link />"><cms:show k_folder_title /></a> <br/>
</cms:folders>

<!-- if folder being visited is 'song', redirect to its first child -->
<cms:if k_folder_name='song'>
    <cms:folders hierarchical='1' childof='song' >
        <cms:redirect k_folder_link />
    </cms:folders>
</cms:if>

<!-- get current folder (in folder-view and also page-view) -->
<cms:if k_is_page || k_is_folder >
    <cms:if k_folder_name ><cms:set current_folder=k_folder_name /></cms:if>
    <cms:if k_page_foldername ><cms:set current_folder=k_page_foldername /></cms:if>
</cms:if>

<!-- is the current-folder a child of 'song'? -->
<cms:if "<cms:is_ancestor parent='song' child=current_folder />" >

   <!-- if yes, show its siblings i.e. children of 'song' -->
    <cms:folders hierarchical='1' childof='song' >
        <a href="<cms:show k_folder_link />"><cms:show k_folder_title /></a> <br/>
    </cms:folders>
   
</cms:if>

<!-- if in folder-view, show pages -->
<cms:if k_is_folder >
    <h1><cms:show k_folder_title /></h1>
    <cms:pages folder=k_folder_name >
        <a href="<cms:show k_page_link />"><cms:show k_page_title /></a> <br/>
    </cms:pages>
</cms:if>

Hope it helps.
Many thanks indeed ... I was a long way off this.

Looking at the code I'm assuming it wouldn't be readily possible to reach a dynamic solution i.e. to be able to cope if the client were to add another folder + subfolders in the future?
I have now added to your code KK and am trying to get class of 'current' for highlighting current position and have this code
Code: Select all
               <!-- show top-level folders (i.e. 'opera' and 'song') -->
                 <cms:set current_folder=k_folder_name />
               <ul class="tabs clearfix">
               <cms:folders hierarchical='1' depth='1' >
                   <li><a<cms:if k_folder_name==current_folder> class="current"</cms:if> href="<cms:show k_folder_link />"><cms:show k_folder_title /></a></li>
               </cms:folders>
               </ul>
               <!-- if folder being visited is 'song', redirect to its first child -->
               
               <cms:if k_folder_name='song'>
                   <cms:folders hierarchical='1' childof='song' >
                       <cms:redirect k_folder_link />
                   </cms:folders>
               </cms:if>
               
               <!-- get current folder (in folder-view and also page-view) -->
               <cms:if k_is_page || k_is_folder >
                   <cms:if k_folder_name ><cms:set current_folder=k_folder_name 'global' /></cms:if>
                   <cms:if k_page_foldername ><cms:set current_folder=k_page_foldername 'global'/></cms:if>
               </cms:if>
               
               <!-- is the current-folder a child of 'song'? -->
               <cms:if "<cms:is_ancestor parent='song' child=current_folder />" >
                  <!-- if yes, show its siblings i.e. children of 'song' -->
                  <cms:set current_subfolder=k_folder_name />
                  <ul class="tabs clearfix">
                   <cms:folders hierarchical='1' childof='song' >
                       <li><a<cms:if k_folder_name==current_subfolder> class="current"</cms:if> href="<cms:show k_folder_link />"><cms:show k_folder_title /></a></li>
                   </cms:folders>
                   </ul>
                  
               </cms:if>
               
               <!-- if in folder-view, show pages -->
               <cms:if k_is_folder >
                   <cms:pages folder=k_folder_name >
                   <h2><cms:show k_page_title /></h2>
                   <div class="repertoire-listing table-responsive">
                       <cms:show repertoire_details />
                  </div><!-- /.table-responsive -->
                   </cms:pages>
               </cms:if>

But for the life of me I cannot establish class of 'current' for the parent folder 'song'. I find the code you kindly supplied KK more or less incomprehensible - so can't logic out how to get the info I need. ***tearing hair out***

I am wondering if this folder/subfolder structure is the best approach for this data - especially if it isn't possible to make it dynamic for future changes via the Admin Panel by the client. Maybe there's a simpler way?
@potato,

Let us simplify things by creating a very generic code that'll work with all folder structures and output HTML that can be used to create menus. An example of the generated HTML being this -
Code: Select all
<ul class="level-0">
   <li id="item-home" class="level-0"><a href="http://www.yoursite.com/index.php?f=1">Home</a></li>
   <li id="item-about-us" class="level-0 has-submenu active"><a href="http://www.yoursite.com/index.php?f=2">About Us</a>
      <ul class="level-1">
         <li id="item-what-we-do" class="level-1 has-submenu active"><a href="http://www.yoursite.com/index.php?f=6">What we do</a>
            <ul class="level-2">
               <li id="item-portfolio" class="level-2"><a href="http://www.yoursite.com/index.php?f=7">Portfolio</a></li>
               <li id="item-testimonials" class="level-2 active current"><a href="http://www.yoursite.com/index.php?f=8">Testimonials</a></li>
            </ul>
         </li>
         <li id="item-our-team" class="level-1"><a href="http://www.yoursite.com/index.php?f=9">Our Team</a></li>
         <li id="item-contact-us" class="level-1"><a href="http://www.yoursite.com/index.php?f=10">Contact Us</a></li>
      </ul>
   </li>
   <li id="item-blog" class="level-0"><a href="http://www.yoursite.com/index.php?f=11">Blog</a></li>
   <li id="item-privacy-policy" class="level-0"><a href="http://www.yoursite.com/index.php?f=12">Privacy Policy</a></li>
</ul>

As you can see, the code above provides vital information about each element (e.g. level, whether it has a sub-menu (i.e. has children), is current (i.e. is the immediately selected folder), is active (i.e folder lies in the path to the immediately selected folder) etc.).

This info then can be used to craft CSS styles and make almost any kind of menu.

OK, so here is the generic code -
Code: Select all
<!-- get current folder (in folder-view and also page-view) -->
<cms:if k_is_page || k_is_folder >
    <cms:if k_folder_name ><cms:set current_folder=k_folder_name /></cms:if>
    <cms:if k_page_foldername ><cms:set current_folder=k_page_foldername /></cms:if>
</cms:if>

<cms:folders hierarchical='1' extended_info='1'>
    <cms:if k_level_start >
        <ul class="level-<cms:show k_level />">
    </cms:if>

    <cms:if k_element_start >
        <cms:set is_active='0' />
        <cms:set is_current='0' />
        <cms:if "<cms:is_ancestor parent=k_folder_name child=current_folder />" >
            <cms:set is_active='1' />
           
            <cms:if k_folder_name=current_folder >
                <cms:set is_current='1' />
            </cms:if>
        </cms:if>
       
        <li id="item-<cms:show k_folder_name />" class="level-<cms:show k_level /><cms:if k_folder_totalchildren> has-submenu</cms:if><cms:if is_active> active</cms:if><cms:if is_current> current</cms:if>">
    <a href="<cms:show k_folder_link />"><cms:show k_folder_title /></a>
    </cms:if>

    <cms:if k_element_end ></li></cms:if>
    <cms:if k_level_end ></ul></cms:if>
</cms:folders>

For the folder hierarchy you mentioned -
opera
songs
--song1
--song2 *
--song3
the code will output something like this -
Code: Select all
<ul class="level-0">
    <li id="item-opera" class="level-0">
        <a href="http://localhost/test.php?f=91">opera</a>
    </li>

    <li id="item-song" class="level-0 has-submenu active">
        <a href="http://localhost/test.php?f=92">song</a>
        <ul class="level-1">
            <li id="item-song1" class="level-1">
                <a href="http://localhost/test.php?f=93">song1</a>
            </li>

            <li id="item-song2" class="level-1 active current">
                <a href="http://localhost/test.php?f=94">song2</a>
            </li>

            <li id="item-song3" class="level-1">
                <a href="http://localhost/test.php?f=95">song3</a>
            </li>
        </ul>
    </li>
</ul>

I am sure you'll be able to use the info provided by the classes to show the songs submenu only when the level-0 LI is active, right?

Does this help? Please let me know.
Thanks.
thanks this has helped ... up to a point.

I want a folder link which has subfolders to display the first subfolder contents. I've tried redirections but am getting into loops. I can't identify where / how to set a flag to then do a redirect outside the cms:folders tag. Is this possible? :?

My failed attempt at setting redirect_reqd
Code: Select all
            <cms:if k_is_page || k_is_folder >
                <cms:if k_folder_name ><cms:set current_folder=k_folder_name /></cms:if>
                <cms:if k_page_foldername ><cms:set current_folder=k_page_foldername /></cms:if>
            </cms:if>
            
            <cms:folders hierarchical='1' extended_info='1'>
                <cms:if k_level_start >
                    <ul class="level-<cms:show k_level />">
                </cms:if>
            
                <cms:if k_element_start >
                  <cms:set redirect_reqd='0' />
                    <cms:set is_active='0' />
                    <cms:set is_current='0' />
                    <cms:if "<cms:is_ancestor parent=k_folder_name child=current_folder />" >
                        <cms:set is_active='1' />
                       
                        <cms:if k_folder_name=current_folder >
                            <cms:set is_current='1' />
                        </cms:if>
                    </cms:if>
                   
                    <li id="item-<cms:show k_folder_name />" class="level-<cms:show k_level /><cms:if k_folder_totalchildren> has-submenu</cms:if><cms:if is_active> active</cms:if><cms:if is_current> current</cms:if>"> <cms:if is_active><cms:if "<cms:is_ancestor parent=k_folder_name child=current_folder />" ><cms:set redirect_reqd='1' 'global' /></cms:if></cms:if>
                   <a href="<cms:show k_folder_link />"><cms:show k_folder_title /></a>
                </cms:if>
            
                <cms:if k_element_end ></li></cms:if>
                <cms:if k_level_end ></ul></cms:if>
            </cms:folders>


And then of course I'll want to set a class of 'current' on both the top level folder and the subfolder when there is a redirection - am anticipating more lengthy headscratching over this. Am on the brink of giving up on this and settling for a page with a huge long list rather than divided into sub navigation!!!
@potato,

We are dealing with two separate issues -
1. Creation of a generic menu using folder structure
2. If a folder does not contain any immediate pages, redirect to a child that is not empty.

The code that I supplied in my last post was for the first mentioned point and, I assume, it is doing the job.

Please use it for menu creation only. Don't mix it with the second point.
We'll handle the redirection issue separately as follows.

Please place the following anywher in your template (below the menu would be fine) -
Code: Select all
<!-- if folder-view --> 
<cms:if k_is_folder>
    <!-- and the current folder does not contain any pages -->
    <cms:if k_folder_pagecount='0'>
   
        <!-- loop though the children to find a folder that has pages -->
        <cms:folders hierarchical='1' childof=k_folder_name >
            <cms:if k_folder_pagecount>
                <cms:redirect k_folder_link />
            </cms:if>
        </cms:folders>
    </cms:if>
</cms:if>
This bit of code kicks in only in folder-view. If it finds that the current folder (e.g. 'song') is empty, it loops through its child-folders looking for a folder that has pages and redirects to that. Like the menu code, this is also a generic code and should work for all kinds of folder structures.

Hope this helps.
Do let me know.

Thanks.
Many thanks for your patience and help ... I have progressed to more or less what I envisaged. I'm not sure why this has seemed so hard - perhaps I am looking at the whole thing sequentially.

I wanted to hide a heading when showing the contents of a child folder as it is shown highlighted in the subnavigation and looked repetitive. I did the following
Code: Select all
<h2 <cms:if k_page_folderparentid gt '0'> class="hide-heading"</cms:if>><cms:show k_page_title /></h2>
with css
Code: Select all
.hide-heading {display: none;}
That works and from my inspection of various data I think it is generic i.e. that any page with k_page_folderparentid LT 0 is not a child.

I usually allow ordering of folders by weight
Code: Select all
orderby='weight'
- but this is causing problems - but I suspect that is a CSS issue!

Thanks again.
thank you for that explanations
9 posts Page 1 of 1
cron