--- loncom/interface/lonmenu.pm 2014/02/23 22:36:16 1.369.2.51
+++ loncom/interface/lonmenu.pm 2015/03/03 16:53:59 1.431.2.1
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines to control the menu
#
-# $Id: lonmenu.pm,v 1.369.2.51 2014/02/23 22:36:16 raeburn Exp $
+# $Id: lonmenu.pm,v 1.431.2.1 2015/03/03 16:53:59 musolffc Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -118,9 +118,9 @@ Same as primary_menu() but operates on @
=item create_submenu()
-Creates XHTML for unordered list of sub-menu items which belong to a
+Creates XHTML for unordered list of sub-menu items which belong to a
particular top-level menu item. Uses hover pseudo class in css to display
-dropdown list when mouse hovers over top-level item. Support for IE6
+dropdown list when mouse hovers over top-level item. Support for IE6
(no hover psuedo class) via LC_hoverable class for
tag for top-
level item, which employs jQuery to handle behavior on mouseover.
@@ -128,30 +128,37 @@ Inputs: 4 - (a) link and (b) target for
(c) title for text wrapped by anchor tag in top level item.
(d) reference to array of arrays of sub-menu items.
+ The underlying datastructure used in (d) contains data from mydesk.tab.
+ It consists of an array which has an array for each item appearing in
+ the menu (e.g. [["link", "title", "condition"]] for a single-item menu).
+ create_submenu() supports also the creation of XHTML for nested dropdown
+ menus represented by unordered lists. This is done by replacing the
+ scalar used for the link with an arrayreference containing the menuitems
+ for the nested menu. This can be done recursively so that the next menu
+ may also contain nested submenus.
+
+ Example:
+ [ # begin of datastructure
+ ["/home/", "Home", "condition1"], # 1st item of the 1st layer menu
+ [ # 2nd item of the 1st layer menu
+ [ # anon. array for nested menu
+ ["/path1", "Path1", undef], # 1st item of the 2nd layer menu
+ ["/path2", "Path2", undef], # 2nd item of the 2nd layer menu
+ [ # 3rd item of the 2nd layer menu
+ [[...], [...], ..., [...]], # containing another menu layer
+ "Sub-Sub-Menu", # title for this container
+ undef
+ ]
+ ], # end of array/nested menu
+ "Sub-Menu", # title for the container item
+ undef
+ ] # end of 2nd item of the 1st layer menu
+]
+
=item innerregister()
This gets called in order to register a URL in the body of the document
-=item loadevents()
-
-=item unloadevents()
-
-=item startupremote()
-
-=item setflags()
-
-=item maincall()
-
-=item load_remote_msg()
-
-=item get_menu_name()
-
-=item reopenmenu()
-
-=item open()
-
-Open the menu
-
=item clear()
=item switch()
@@ -203,7 +210,7 @@ use HTML::Entities();
use Apache::lonwishlist();
use vars qw(@desklines %category_names %category_members %category_positions
- $readdesk @primary_menu %primary_submenu @secondary_menu %secondary_submenu);
+ $readdesk @primary_menu %primary_submenu @secondary_menu);
my @inlineremote;
@@ -231,7 +238,7 @@ sub prep_menuitem {
# @primary_menu is filled within the BEGIN block of this module with
# entries from mydesk.tab
sub primary_menu {
- my %menu;
+ my (%menu);
# each element of @primary contains following array:
# (link url, icon path, alt text, link text, condition, position)
my $public;
@@ -273,9 +280,9 @@ sub primary_menu {
my @primsub;
if (ref($primary_submenu{$title}) eq 'ARRAY') {
foreach my $item (@{$primary_submenu{$title}}) {
- next if (($item->[2] eq 'wishlist') && (!$env{'user.adv'}));
- next if ((($item->[2] eq 'portfolio') ||
- ($item->[2] eq 'blog')) &&
+ next if (($item->[2] eq 'wishlist') && (!$env{'user.adv'}));
+ next if ((($item->[2] eq 'portfolio') ||
+ ($item->[2] eq 'blog')) &&
(!&Apache::lonnet::usertools_access('','',$item->[2],
undef,'tools')));
push(@primsub,$item);
@@ -351,19 +358,22 @@ sub secondary_menu {
if ($canviewroster eq 'disabled') {
undef($canviewroster);
}
- my $canviewgrps = &Apache::lonnet::allowed('vcg', $crs_sec);
- my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);
- my $canviewwnew = &Apache::lonnet::allowed('whn', $crs_sec);
+ my $canviewgrps = &Apache::lonnet::allowed('vcg', $crs_sec);
+ my $canmodifyuser = &Apache::lonnet::allowed('cst', $crs_sec);
+ my $canviewwnew = &Apache::lonnet::allowed('whn', $crs_sec);
my $canmodpara = &Apache::lonnet::allowed('opa', $crs_sec);
my $canvgr = &Apache::lonnet::allowed('vgr', $crs_sec);
- my $canmgr = &Apache::lonnet::allowed('mgr', $crs_sec);
+ my $canmgr = &Apache::lonnet::allowed('mgr', $crs_sec);
my $author = &getauthor();
my ($cdom,$cnum,$showsyllabus,$showfeeds,$showresv);
if ($env{'request.course.id'}) {
$cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
$cnum = $env{'course.'.$env{'request.course.id'}.'.num'};
- unless ($canedit) {
+ if ($canedit) {
+ $showsyllabus = 1;
+ $showfeeds = 1;
+ } else {
unless (&Apache::lonnet::is_on_map("public/$cdom/$cnum/syllabus")) {
if (($env{'course.'.$env{'request.course.id'}.'.externalsyllabus'}) ||
($env{'course.'.$env{'request.course.id'}.'.uploadedsyllabus'}) ||
@@ -384,7 +394,7 @@ sub secondary_menu {
}
}
- my ($canmodifycoauthor);
+ my ($canmodifycoauthor);
if ($env{'request.role'} eq "au./$env{'user.domain'}/") {
my $extent = "$env{'user.domain'}/$env{'user.name'}";
if ((&Apache::lonnet::allowed('cca',$extent)) ||
@@ -404,14 +414,10 @@ sub secondary_menu {
# evaluate conditions
next if ref($menuitem) ne 'ARRAY';
next if $$menuitem[4] ne 'always'
- && ($$menuitem[4] ne 'author' && $$menuitem[4] ne 'cca')
+ && ($$menuitem[4] ne 'author' && $$menuitem[4] ne 'cca')
&& !$env{'request.course.id'};
next if $$menuitem[4] =~ /^mdc/
&& !$canedit;
- next if $$menuitem[4] eq 'mdcCourse'
- && ($crstype eq 'Community');
- next if $$menuitem[4] eq 'mdcCommunity'
- && ($crstype eq 'Course');
next if $$menuitem[4] eq 'nvgr'
&& $canvgr;
next if $$menuitem[4] eq 'vgr'
@@ -428,8 +434,9 @@ sub secondary_menu {
&& !$canviewwnew;
next if $$menuitem[4] eq 'opa'
&& !$canmodpara;
- next if $$menuitem[4] eq 'nvcg'
- && ($canviewgrps || !%groups);
+ next if $$menuitem[4] =~ /showgroups$/
+ && !$canviewgrps
+ && !%groups;
next if $$menuitem[4] eq 'showsyllabus'
&& !$showsyllabus;
next if $$menuitem[4] eq 'showfeeds'
@@ -439,35 +446,7 @@ sub secondary_menu {
next if $$menuitem[4] eq 'cca'
&& !$canmodifycoauthor;
- my $title = $menuitem->[3];
- if (defined($secondary_submenu{$title})) {
- my ($link,$target);
- if ($menuitem->[0] ne '') {
- $link = $menuitem->[0];
- $target = '_top';
- } else {
- $link = '#';
- }
- my @scndsub;
- if (ref($secondary_submenu{$title}) eq 'ARRAY') {
- foreach my $item (@{$secondary_submenu{$title}}) {
- if (ref($item) eq 'ARRAY') {
- next if ($item->[2] eq 'vgr' && !$canvgr);
- next if ($item->[2] eq 'opa' && !$canmodpara);
- next if ($item->[2] eq 'cst' && !$canmodifyuser);
- next if ($item->[2] eq 'mgr' && !$canmgr);
- next if ($item->[2] eq 'vcg' && !$canviewgrps);
- next if ($item->[2] eq 'mdc' && !$canedit);
- push(@scndsub,$item);
- }
- }
- if (@scndsub > 0) {
- $menu .= &create_submenu($link,$target,$title,\@scndsub,1);
- } elsif ($link ne '#') {
- $menu .= '
';
- }
- }
- } elsif ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
+ if ($$menuitem[3] eq 'Roles' && $env{'request.course.id'}) {
# special treatment for role selector
($roleswitcher_js,$roleswitcher_form,my $switcher) =
&roles_selector(
@@ -511,7 +490,7 @@ sub secondary_menu {
}
$menu =~ s/\[uname\]/$$author{user}/g;
$menu =~ s/\[udom\]/$$author{dom}/g;
- if ($env{'request.course.id'}) {
+ if ($showsyllabus || $showfeeds) {
$menu =~ s/\[cnum\]/$cnum/g;
$menu =~ s/\[cdom\]/$cdom/g;
}
@@ -547,66 +526,77 @@ sub create_submenu {
''.
' ▼'.
'
';
+
+ # $link and $title are only used in the initial string written in $menu
+ # as seen above, not needed for nested submenus
+ $menu .= &build_submenu($target, $submenu, $translate, '1');
+ $menu .= '
';
+
+ return $menu;
+}
+
+# helper routine for create_submenu
+# build the dropdown (and nested submenus) recursively
+# see perldoc create_submenu documentation for further information
+sub build_submenu {
+ my ($target, $submenu, $translate, $first_level) = @_;
+ if (!defined(@{$submenu})) {
+ return '';
+ }
+
+ my $menu = '';
my $count = 0;
my $numsub = scalar(@{$submenu});
foreach my $item (@{$submenu}) {
$count ++;
if (ref($item) eq 'ARRAY') {
my $href = $item->[0];
- if ($href =~ /(aboutme|rss\.html)$/) {
- next unless (($env{'user.name'} ne '') && ($env{'user.domain'} ne ''));
- $href =~ s/\[domain\]/$env{'user.domain'}/g;
- $href =~ s/\[user\]/$env{'user.name'}/g;
- }
+ my $bordertop;
my $borderbot;
- if ($count == $numsub) {
- $borderbot = 'border-bottom:1px solid black;';
- }
- unless (($href eq '') || ($href =~ /^\#/)) {
- $target = ' target="_top"';
- }
- $menu .= '