Forum OpenACS Q&A: Is this it?

Collapse
25: Is this it? (response to 24)
Posted by Richard Hamilton on
nbsp; Category instproc render_category {{-open:boolean false} cat_content} {
    set open_state [expr {[my set open_requests]>0?"class='liOpen'" : "class='liClosed'"}]
    set c [expr {[my exists count] ? "<a href='[my href]'>([my count])</a>" : ""}]
    return "<li $open_state>[my label] $c\n <ul>$cat_content</ul>\n"
  }

If I change :

return "<li $open_state>[my label] $c\n <ul>$cat_content</ul>\n"

to :

return "<li $open_state>[my label] $c\n <div class="submenu"><ul>$cat_content</ul></div>\n"

Will that work?


Lets try and see!
Collapse
26: Aha!! (response to 25)
Posted by Richard Hamilton on
Hole in one!!

Goody goody gum drops! 😊

Happy chappy.

Sorry, in case any of you think I'm nuts (you're probably right) but my intention is to document these discoveries for the future reference of others (and probably me as well some months down the line).

Thank you Gustaf - what an absolutely FANTASTIC tool this xowiki contraption is! 😊

Richard

Collapse
27: Re: Is this it? (response to 25)
Posted by Steve Manning on
Why <div class="submenu">
    $cat_content
</div> instead of ?

- Steve
Collapse
28: Re: Is this it? (response to 27)
Posted by Steve Manning on
That'll teach me to use enhanced text :o( what I meant to say was...

Why

<div class="submenu"><ul>$cat_content</ul></div>

instead of

<ul class="submenu">$cat_content</ul>?


    - Steve

Collapse
29: Re: Is this it? (response to 25)
Posted by Gustaf Neumann on
As Steve asked, do you really need the div around the ul, would not be a CSS class for ul sufficient?

If yes, you would not need the class for ul either, when you use -decoration plain" for the includelet. Then you could address the ul via "div.categories ul" in CSS ("-decoration none" supresses even the surrounding div).

Collapse
30: Re: Is this it? (response to 29)
Posted by Richard Hamilton on
I fully understand the thrust of that comment, I spent hours working through it with that assumption in mind. However, I have explained in the comments that because the top level menu is to be rendered horizontally, it has to be:

display: inline;

This is fine until you add the vertically rendered submenus, i.e. setting the <ul> to display: block. What happens then is that the vertical menu is positioned inline to the top level menu, thereby displacing the subsequent horizontal menu items from their expected positions. This cannot (to the limit of my knowledge) be rectified by adjusting the <ul> class because its position cannot change the inline positions of its parent element.

If you remove the submenu <ul> from the inline display sequence by making it position absolute, your containing block for position reference is the grandparent <ul> rather than the parent <li> element! As the menu is dynamically generated, you cannot risk making absolute position adjustments because you don't know how many elements or subsubmenus there will be.

The containing <div> that I have proposed provides you with a new position reference for the <ul> block where 100% of the <div>'s width is equal to the width of its parent <li> element. This allows you to absolutely position the submenus and subsubmenus with reference to the left hand edge of the <li> that gives rise to it. Page 208, para 2 of the Lie & Bos CSS book refers. I don't think that there is a more minimal solution.

I agree that my style sheet could perhaps have been written to work with the -decoration none version, but actually some of the added classes and wrapping div blocks are useful for precision in the selectors.

I have had to alter a few details and will post back. However one thing I have found is that wherever a series of subcategories are rendered by xowiki inside a parent <li>, the rendered does not close the tag with a </li>. Now I know that under the HTML spec this omission is legitimate, however there are circumstances where this can cause ambiguity. I would therefore recommend a change to close the tags.

(Example; I have been asked to make the dropdowns about 80% opaque. If you reduce an element's opacity in CSS or javascript, all descendents are affected and the effect cannot be reversed by subsequent more specific rules. Therefore to add a partially transparent background without reducing the opacity of the text, I have to add another <div class="opaque"><div>which is sized and positioned to provide the transparent backdrop to the menu. Without the explicit closing </li> the browser assumes this <div> to be another top level <li> rather than a block element still in the previous one).

Sorry, this is all rather arcane detail, but it takes hours to thrash through and I may as well record it.

Regards
Richard

Collapse
32: Correction! (response to 29)
Posted by Richard Hamilton on
The example of ambiguity relating to the unclosed <li> tags is not correct. I had made an error - the lack of a closing tag makes no difference (except perhaps to my sense of symmetry!)

However, for the time being I stand by the rest of the previous posting!! 😊

R.

Collapse
34: Re: Correction! (response to 32)
Posted by Gustaf Neumann on
When i make an HTML document out of your example, using the usual openacs stylesheet + cattree.css and xowiki.css, nothing is displayed under FF 3.5.5 (because of the display nones and fontsize 0). When "cattree.css" + mktree.js are removed, it shows. anyhow, i see, your CSS markup is already quite tricky.

Anyhow, it is not likely that the mktree renderer is a good choice for rendering menus. Furthermore, "Category instproc render_category ... " is gone since early this year and has been replaced by some more generic tree renderer classes (in tree-procs.tcl) which are used for various purposes in xowiki (not only for categories). The right approach seems to be write your own tree renderer and pass the tree-renderer via "-style" to the categories includelet. This way, you can use arbitrary CSS classes and you can freely add / remove divs without breaking anything else.

Collapse
35: Re: Correction! (response to 34)
Posted by Richard Hamilton on
Gustav,

Yes, you're right. Piggybacking something not designed for the purpose was sloppy, but time is my enemy at the moment!

Also, I posted that code from a set of working static files rather than from a working installation and there were faults in it. I have refined my CSS quite considerably since I posted the code and will post it back here now that I have it working on a live system.

Perhaps to create a more general solution, when time is available, I will do as you recommend and create a custom renderer with a horiz-menu-view paramter option to activate it. That would be the better solution to post here.

Happily though, at least for this application, what I have done seems to work ok.

Is the deprecation of "Category instproc render_category" relevant to the current release OpenACS codebase or will this happen in the next release?

Regards
Richard

Collapse
36: Re: Correction! (response to 35)
Posted by Gustaf Neumann on
since xowiki is not part of any official OpenACS releases, and since xowiki in general tries to work with multiple OpenACS versions, you can use the version you have now as long as you are happy with it.

For testing i have added a small addition to xowiki head, which add a menu-renderer in the style i believe you want. One can use this via {{categories -style samplemenu}}.

  #
  # List-specific renderer based for some menus
  #
  TreeRenderer create TreeRenderer=samplemenu \
      -superclass TreeRenderer=list \
      -li_expanded_atts [list "class='menu-open'" "class='menu-closed'"] \
      -subtree_wrapper_class "submenu"

  TreeRenderer=samplemenu proc include_head_entries {args} {
    # add your CSS here...
  }
  TreeRenderer=samplemenu proc render {tree} {
    return "<ul class='menu' id='[$tree id]'>[next]</ul>"
  }
Collapse
37: Re: Correction! (response to 36)
Posted by Richard Hamilton on
Gustaf,

Oh, fantastic. Thank you very much indeed. That will make a great general purpose solution for this kind of menu.

I have finished working through the CSS changes required to make this work with {{categories -decoration none}} which I have posted below. I noticed that even with -decoration none the categories tree is still rendered with class="mktree" in the version I am using.

At the moment this assumes and requires a containing <div> with class="foregroundcontainer" which is my main page content container. The only reason this is needed in the CSS is to eliminate the <h3>@category_name@</h3> without destroying the general case of the <h3> tag. If a specific class is added to this <h3> tag the requirement for a containing div would be eliminated.

The root of the category tree <ul> for the menu bar is identified as class="mktree" which seems to be still there even with -decoration none. I don't know if this will be true in later versions.

This also still requires each <ul> block to be wrapped in a <div class"submenu">. This demo carries fonts and colours specific to the site I am working on but these can obviously be altered to taste.

I hope it works this time!

Regards
Richard

/* ################### */
/* Menu system classes */
/* ################### */

/* Set the style for links on the menu bar */
div.foregroundcontainer > ul.mktree a:link {font-family: "Segoe UI", arial, sans-serif;
                                            font-weight: bold;
                                            font-size: 10pt;
                                            background-color: transparent}

/* Set style for visited links on the menu bar */
div.foregroundcontainer > ul.mktree a:visited {font-family: "Segoe UI", arial, sans-serif;
                                              font-weight: bold;
                                              font-size: 10pt;
                                              background-color: transparent}

/* Vanish the bits of the OpenAcs Category tree that we don't want */
div.foregroundcontainer > img + img + img + img +h3 {display: none}

/* Hide top layer of PowerofAloe Category tree by fiddling with font size */
div.foregroundcontainer > ul.mktree > li {position: absolute;
                                          left: 40px;
                                          font-size: 0pt;
                                          color: #ffffff;
                                          margin: 0px;
                                          list-style: none}

/* Have to immediately more explicitly re set to size required for menu bar */
div.foregroundcontainer > ul.mktree > li > div.submenu {font-family: "Segoe UI", arial, sans-serif;
                                                        font-weight: bold;
                                                        font-size: 10pt;
                                                        overflow: visible}

/* Use to set position of menubar */
ul.mktree {position: absolute;
          border: none;
          width: 720px;
          top: 9em;
          left: 0em;
          margin: 0em;
          padding: 0em;
          z-index: 1}

/* Make sure that the first layer is displayed horizontally */
ul.mktree > li > div.submenu > ul:first-child > li {position: relative;
                                                    top: 0px;
                                                    left: 0px;
                                                    display: inline;
                                                    padding: 2px 20px 5px 20px;
                                                    color: #6d6f71}

/* Adjust gap between seperate <li> entries in submenus, but not between wrapped entries */
ul.mktree > li > div.submenu > ul:first-child > li div.submenu > ul > li {margin: 7px 0px 7px 6px}

/* Add in the horizontal menu item separator bars */
ul.mktree > li > div.submenu > ul:first-child > li + li {border-left: solid 2px;
                                                        border-color: #4a9a44}

/* The addition of this <div> is unavoidable because with a horizontal menubar */
/* you have to take the dropdown out of the flow whilst preserving its position */
/* relative to the top level option selected. A <div> block allows for relative */
/* positioning without upsetting the flow of the horizontal elements.          */
div.foregroundcontainer > ul.mktree > li > div.submenu div.submenu {display: none;
                                                                    position: absolute;
                                                                    width: 100%;
                                                                    top: 80%;
                                                                    left: 0%;
                                                                    margin: 0px;
                                                                    padding: 0px;
                                                                    overflow: visible;
                                                                    background-color: #ffffff;
                                                                    opacity: 0.90;
                                                                    filter:alpha(opacity=90);
                                                                    -moz-border-radius: 12px}

/* All subsequent descendents are block displayed submenus */
div.foregroundcontainer > ul.mktree > li > div.submenu > ul > li > div.submenu ul {display: block;
                                                                                  list-style: none;
                                                                                  position: relative;
                                                                                  width: 70%;
                                                                                  left: 0px;
                                                                                  top: 0px;
                                                                                  padding: 5px 7px 12px 17px;
                                                                                  margin: 0px;
                                                                                  line-height: 0.9em;
                                                                                  text-align: left;
                                                                                  color: #6d6f71;
                                                                                  z-index: 1}

/* The following pushes sub-sub-menus to the right and down slightly*/
ul.mktree > li > div.submenu > ul > li > div.submenu div.submenu {left: 7.1em; top: 4.3em}

/* The following makes the menus appear when the mouse moves over the items */
ul.mktree > li > div.submenu > ul li:hover > div.submenu {display: block}

Collapse
38: Re: Correction! (response to 37)
Posted by Gustaf Neumann on
Concerning "-decoration": This flag just controls the outer wrapper of an includelet and works exactly the same way for all kind of includelets in xowiki. The mktree markup is coming from the default renderer of the categories includelet. If a different renderer is specified for the categories, the inner markup of this includelet will look differently.
Collapse
Posted by Richard Hamilton on
I have two categories defined:

Site-Root and Dropdown


Under Site-Root I have content pages 1-4 as top level xowiki pages, and a dropdown menu containing five subordinate pages. The structure is:

Site-Root
    page01
    page02
    page03
    page04
    Dropdown
        paged01
        paged02
        paged03
        paged04
        paged05


Site-Root is an invisible category so that I get a horizontal menu. It looks like this:

page01  |  page02  |  page 03  |  page04  |  Dropdown
                                               paged01
                                               paged02
                                               paged03
                                               paged04
                                               paged05


For user interface design reasons I need the layout order to be:

page01  |  page02  |  page 03  |  Dropdown  |  page 04
                                    paged01
                                    paged02
                                    paged03
                                    paged04
                                    paged05

I have racked my brains and tried various ordering numbers in the Section field, but I cannot work out how to do this. 
The page ordering seems to work perfectly within a category, but is there a way of specifying that a subcategory
(and its children) should be listed in between sibling items that are not categories?

Richard

Collapse
40: Re: Correction! (response to 36)
Posted by Richard Hamilton on
Gustaf,

After checking out and playing with a HEAD version of xowiki, I thought I should take the opportunity to move my work across on the new version.

I have therefore adjusted my CSS to work with the samplemenu renderer that you so kindly provided, and it works beautifully. Thank you for posting that, it has really helped me to start to understand your code and the whole oo way of doing things.

I will strip out the project specific stylistic elements and will post a short samplemenu.css file (that could, if deemed suitable, be included in the distribution) and some brief documentation.

When I have more time I will work up a LHS vertical menu that works in a similar way. I will use your code as a boilerplate to create a renderer for the two styles - something like { -style horizontalmenu } and { -style vertical menu }.

I am a great believer in CSS, and where it can be used as a substitute for Javascript code I am all for having the choice.

Thank you so very much for all your help.

Regards
Richard