Class ::xowiki::MenuBar

::xowiki::MenuBar[i] create ... \
           [ -current_folder:object current_folder:object ] \
           [ -dropzone:boolean (default "true") ] \
           [ -id id ] \
           [ -parent_id:integer,0..1 (default "") ]

Class Relations

  • class: ::xotcl::Class[i]
  • superclass: ::xotcl::Object[i]
::xotcl::Class create ::xowiki::MenuBar \
     -superclass ::xotcl::Object

Methods (to be applied on instances)

  • add_extra_item (scripted)

    if {$type ni {"DropZone" "ModeButton"}} {
      error "unknown extra item type: $type"
    }
    set :${type}($name$item
  • add_menu (scripted)

    if {$name in ${:Menus}} {
      error "menu $name exists already"
    }
    if {[string match {[a-z]*} $name]} {
      error "names must start with uppercase, provided name '$name'"
    }
    lappend :Menus $name
    if {$label eq ""} {set label $name}
    set :Menu($name) [list label $label]
    #:log "menus: ${:Menus}"
  • add_menu_item (scripted)

    #
    # The provided items are of the form of attribute-value pairs
    # containing at least attributes "label" and "url"
    #   (e.g. "label .... url ....").
    #
    set full_name $name
    if {![regexp {^([^.]+)[.](.+)$} $name _ menu name]} {
      error "menu item name '$name' not of the form Menu.Name"
    }
    if {$menu ni ${:Menus}} {
      error "menu $menu does not exist"
    }
    if {[string match {[a-z]*} $name]} {
      error "names must start with uppercase, provided name '$name'"
    }
    
    #
    # get group name (syntax: Menu.Group.Item)
    #
    set group_name ""
    regexp {^[^.]+[.]([^.]+)[.].*} $full_name _ group_name
    #
    # provide a default label
    #
    regsub -all -- {[.]} $full_name - full_name
    set item [dict merge [list label "#xowiki.menu-$full_name#" group $group_name$item]
    
    #
    # If an entry with the given name exists, update it. Otherwise add
    # such an entry.
    #
    set updated 0
    set newitems [list]
    foreach {n i} [set :Menu($menu)] {
      if {$n eq $name} {
        lappend newitems $name $item
        set updated 1
      } else {
        lappend newitems $n $i
      }
    }
    if {$updated} {
      set :Menu($menu$newitems
    } else {
      lappend :Menu($menu$name $item
    }
  • additional_sub_menu (scripted)

    set :submenu_pages($kind$pages
    set :submenu_owner($kind$owner
  • clear_menu (scripted)

    set :Menu($menu) [list label [dict get [set :Menu($menu)] label]]
  • config=default (scripted)

    
    #:log folder_link=$folder_link
    #:log parent_id=${:parent_id}
    
    #
    # Define standard xowiki menubar
    #
    set clipboard_size [::xowiki::clipboard size]
    set clipboard_label [expr {$clipboard_size ? "Clipboard ($clipboard_size)" : "Clipboard"}]
    
    :add_menu -name Package   -label [::$package_id instance_name]
    :add_menu -name New       -label [_ xowiki.menu-New]
    :add_menu -name Clipboard -label $clipboard_label
    :add_menu -name Page      -label [_ xowiki.menu-Page]
    
    :config_menu=Package  -folder_link $folder_link  -return_url $return_url  -package_id $package_id  -bind_vars $bind_vars
    
    :config_menu=New  -folder_link $folder_link  -return_url $return_url  -package_id $package_id  -bind_vars $bind_vars
    
    :config_menu=Clipboard  -folder_link $folder_link  -return_url $return_url
    
    :config_menu=Page  -folder_link $folder_link  -return_url $return_url  -current_page $current_page
    
    
    set upload_link [::$package_id make_link ${:current_folder} file-upload]
    :add_extra_item -name dropzone1 -type DropZone  -item [list url $upload_link label DropZone disposition File]
    
    #set modestate [::xowiki::mode::admin get]
    #set modebutton_link [::$package_id make_link ${:current_folder} toggle-modebutton]
    #:add_extra_item -name admin -type ModeButton  #    -item [list url $modebutton_link on $modestate label admin]
    return {}
  • config=test-item-exams (scripted)

    :config=default  -bind_vars $bind_vars  -current_page $current_page  -package_id $package_id  -folder_link $folder_link  -return_url $return_url
    
    # {entry -name New.Item.ExamFolder -form en:Folder.form -query p.configure=exam_folder}
    
    return {
      {clear_menu -menu New}
      {entry -name New.Item.ExamFolder -form en:folder.form -query p.source=ExamFolder&publish_status=ready}
    }
  • config=test-items (scripted)

    :config=default  -bind_vars $bind_vars  -current_page $current_page  -package_id $package_id  -folder_link $folder_link  -return_url $return_url
    
    return {
      {clear_menu -menu New}
    
      {entry -name New.Item.TextInteraction -form en:edit-interaction.wf -query p.item_type=Text}
      {entry -name New.Item.ShortTextInteraction -form en:edit-interaction.wf -query p.item_type=ShortText}
      {entry -name New.Item.SCInteraction -form en:edit-interaction.wf -query p.item_type=SC}
      {entry -name New.Item.MCInteraction -form en:edit-interaction.wf -query p.item_type=MC}
      {entry -name New.Item.ReorderInteraction -form en:edit-interaction.wf -query p.item_type=Reorder}
      {entry -name New.Item.UploadInteraction -form en:edit-interaction.wf -query p.item_type=Upload}
      {entry -name New.Item.CompositeInteraction -form en:edit-interaction.wf -query p.item_type=Composite}
      {entry -name New.Item.PoolQuestionInteraction -form en:edit-interaction.wf -query p.item_type=PoolQuestion}
    
      {entry -name New.Grading.Scheme -form en:edit-grading-scheme.wf}
    
      {entry -name New.App.OnlineExam -form en:online-exam.wf -disabled true}
      {entry -name New.App.InclassQuiz -form en:inclass-quiz.wf -disabled true}
      {entry -name New.App.InclassExam -form en:inclass-exam.wf -query p.realexam=1}
    
    }
  • config=xowf (scripted)

    :config=default  -bind_vars $bind_vars  -current_page $current_page  -package_id $package_id  -folder_link $folder_link  -return_url $return_url
    
    return {
      {entry -name New.Extra.Workflow   -form en:Workflow.form}
      {entry -name New.Extra.ExamFolder -form en:folder.form -query p.source=ExamFolder}
    }
  • config_menu=Clipboard (scripted)

    if {[::xowiki::clipboard is_empty]} {
      set clipboard_copy_link ""
      set clipboard_export_link ""
      set clipboard_content_link ""
      set clipboard_clear_link ""
    } else {
      set clipboard_copy_link    $folder_link?m=clipboard-copy
      set clipboard_export_link  $folder_link?m=clipboard-export
      set clipboard_content_link $folder_link?m=clipboard-content
      set clipboard_clear_link   $folder_link?m=clipboard-clear
    }
    set clipboard_add_link [export_vars -base $folder_link?m=clipboard-add {return_url}]
    
    # TODO: we should check either, whether to user is allowed to
    # copy-to-clipboard from the current folder, and/or the user is
    # allowed to do this with certain items.... (the latter in
    # clipboard-add)
    :add_menu_item -name Clipboard.Add  -item [list url \# listener [list click acs_ListBulkActionMultiFormClick("objects","$clipboard_add_link")]]
    :add_menu_item -name Clipboard.Content     -item [list url $clipboard_content_link]
    :add_menu_item -name Clipboard.Clear       -item [list url $clipboard_clear_link]
    :add_menu_item -name Clipboard.Use.Copy    -item [list url $clipboard_copy_link]
    :add_menu_item -name Clipboard.Use.Export  -item [list url $clipboard_export_link]
  • config_menu=New (scripted)

    
    dict with bind_vars {
    
      set new_folder_link  [::$package_id make_form_link -form en:folder.form  -parent_id ${:parent_id}  -return_url $return_url]
    
      set new_page_link  [::$package_id make_form_link -form en:page.form  -parent_id ${:parent_id}  -return_url $return_url]
      #
      # Two old style links for xowiki::File and xowiki::Form
      #
      set new_file_link  [::$package_id make_link   ::$package_id edit-new  {object_type ::xowiki::File}  parent_id return_url autoname template_file]
    
      set new_form_link [::$package_id make_form_link -form en:form.form  -parent_id ${:parent_id}  -nls_language $nls_language -return_url $return_url]
    }
    
    :add_menu_item -name New.Page   -item [list url $new_page_link]
    :add_menu_item -name New.File   -item [list url $new_file_link]
    :add_menu_item -name New.Folder -item [list url $new_folder_link]
    
    if {[::$package_id get_parameter MenuBarSymLinks:boolean 0]} {
      #
      # Symlinks are configured
      #
      dict with bind_vars {
        set new_sym_link [::$package_id make_form_link -form en:link.form  -parent_id ${:parent_id}  -nls_language $nls_language -return_url $return_url]
      }
      :add_menu_item -name New.SymLink -item [list url $new_sym_link]
    }
    :add_menu_item -name New.Form -item [list url $new_form_link]
  • config_menu=Package (scripted)

    
    set index_link [::$package_id make_link  -link $folder_link  ${:current_folder} list]
    
    set admin_link [::$package_id make_link -privilege admin  -link admin/ ::$package_id]
    dict with bind_vars {
      set import_link  [::$package_id make_link -privilege admin  -link "admin/import"  ::$package_id {} parent_id return_url]
    
      set import_archive_link  [::$package_id make_form_link -form en:import-archive.form  -parent_id ${:parent_id}]
    }
    
    :add_menu_item -name Package.Startpage -item [list url $folder_link]
    :add_menu_item -name Package.Toc -item [list url $index_link]
    
    if {[::$package_id get_parameter with_notifications:boolean 1]} {
      if {[::xo::cc user_id] != 0} {
        #
        # notifications require login
        #
        set notifications_return_url [expr {[info exists return_url] ? $return_url : [ad_return_url]}]
        set notification_type [notification::type::get_type_id -short_name xowiki_notif]
        set notification_text "Subscribe to [::$package_id instance_name]"
        set notification_subscribe_link  [export_vars -base /notifications/request-new  {{return_url $notifications_return_url}
                                                {pretty_name $notification_text}
                                                {type_id $notification_type}
                                                {object_id $package_id}}]
        :add_menu_item -name Package.Notifications  -item [list url /notifications/manage]
      }
    }
    
    :add_menu_item -name Package.Admin  -item [list text #xowiki.admin# url $admin_link]
    :add_menu_item -name Package.ImportDump -item [list url $import_link]
    :add_menu_item -name Package.ImportArchive -item [list url $import_archive_link]
  • config_menu=Page (scripted)

    set package_id [$current_page package_id]
    
    set edit_link   [::$package_id make_link $current_page edit return_url]
    set view_link   [::$package_id make_link $current_page view return_url]
    set delete_link [::$package_id make_link $current_page delete return_url]
    set rev_link    [::$package_id make_link $current_page revisions]
    
    :add_menu_item -name Page.Edit  -item [list text #xowiki.edit# url $edit_link]
    :add_menu_item -name Page.View  -item [list text #xowiki.menu-Page-View# url $view_link]
    :add_menu_item -name Page.Delete  -item [list text #xowiki.delete# url $delete_link]
    :add_menu_item -name Page.Revisions  -item [list text #xowiki.revisions# url $rev_link]
    if {[acs_user::site_wide_admin_p]} {
      set page_show_link [::$package_id make_link -privilege admin  $current_page show-object return_url]
      :add_menu_item -name Page.Show  -item [list text "Show Object" url $page_show_link]
    }
  • content (scripted)

    set result [list id [:id]]
    foreach e ${:Menus} {
      lappend result $e [list kind MenuButton {*}[set :Menu($e)]]
    }
    
    foreach e [:array name ModeButton] {
      lappend result $e [list kind ModeButton {*}[set :ModeButton($e)]]
    }
    
    foreach e [:array name DropZone] {
      lappend result $e [list kind DropZone {*}[set :DropZone($e)]]
    }
    
    return $result
  • current_folder (setter)

  • dropzone (setter)

  • get_prop (scripted)

    if {![dict exists $dict $key]} {
      return $default
    }
    return [dict get $dict $key]
  • id (setter)

  • init (scripted)

    set :Menus [list]
    :destroy_on_cleanup
  • parent_id (setter)

  • render-bootstrap (scripted)

    set dict [:content]
    set mb [::xowiki::BootstrapNavbar  -id [:get_prop $dict id]  -menubar [self] {
                  foreach {att value} $dict {
                    if {$att eq "id"} continue
                    switch [:get_prop $value kind] {
                      "DropZone" {
                        ::xowiki::BootstrapNavbarDropzone  -text [:get_prop $value label]  -href [:get_prop $value url]  -disposition [:get_prop $value disposition File] {}
                      }
                      "ModeButton" {
                        template::head::add_css  -href "/resources/xotcl-core/titatoggle/titatoggle-dist.css"
    
                        ::xowiki::BootstrapNavbarModeButton  -text [:get_prop $value label]  -href [:get_prop $value url]  -button [:get_prop $value button admin]  -on [:get_prop $value on] {}
                      }
                      "MenuButton" {
                        # render erverthing as a dropdown
                        ::xowiki::BootstrapNavbarDropdownMenu  -text [:get_prop $value label] {
                              #ns_log notice "... dropdown att $att menu $value"
                              foreach {item_att item} $value {
                                if {[string match {[a-z]*} $item_att]} continue
                                ::xowiki::BootstrapNavbarDropdownMenuItem  -text [:get_prop $item label]  -href [:get_prop $item url]  -group [:get_prop $item group]  -listener [:get_prop $item listener]  {}
                              }
                            }
                      }
                    }
                  }}]
    #ns_log notice "call menubar asHTML"
    return [$mb asHTML]
  • render-preferred (scripted)

    switch [::template::CSS toolkit] {
      bootstrap -
      bootstrap5 {set menuBarRenderer render-bootstrap}
      default    {set menuBarRenderer render-yui}
    }
    :$menuBarRenderer
  • render-yui (scripted)

    set dict [:content]
    set mb [::xowiki::YUIMenuBar -id [:get_prop $dict id] -configuration {
      {autosubmenudisplay: false, keepopen: true, lazyload: false}
    } {
      foreach {menu_att menu} $dict {
        if {$menu_att eq "id"} continue
        set kind [:get_prop $menu kind]
        #ns_log notice "entry: kind $kind <$menu_att> <$menu>"
    
        if {$kind ne "MenuButton"} continue
        ::xowiki::YUIMenuBarItem -text [:get_prop $menu label] {
          ::xowiki::YUIMenu {
            foreach {item_att item} $menu {
              if {[string match {[a-z]*} $item_att]} continue
              ::xowiki::YUIMenuItem  -text [:get_prop $item label]  -href [:get_prop $item url]  -group [:get_prop $item group]  -listener [:get_prop $item listener] {}
            }
          }
        }
      }
    }]
    return [$mb asHTML]
  • update_items (scripted)

    # A folder page can contain extra menu entries (sample
    # below). Iterate of the extra_menu property and add according
    # menu entries. Sample:
    #
    #   {clear_menu -menu New}
    #   {entry -name New.Page -label #xowiki.new# -form en:page.form}
    #   {entry -name New.File -label File -object_type ::xowiki::File}
    #   {dropzone -name DropZone -label DropZone -disposition File}
    #   {modebutton -name Admin -label admin -button admin}
    
    set config_items [:config=$config  -package_id $package_id  -current_page $current_page  -folder_link $folder_link  -bind_vars $bind_vars  -return_url $return_url]
    
    set menu_entries [list  {*}[::$package_id get_parameter ExtraMenuEntries {}]  {*}$config_items  {*}[${:current_folder} property extra_menu_entries]]
    
    #:log "config=$config DONE menu_entries=$menu_entries"
    
    foreach me $menu_entries {
      set kind [lindex $me 0]
      if {[string index $kind 0] eq "#"} continue
      #:log notice "menu_entry <$kind> full <$me>"
      set properties [lrange $me 1 end]
    
      switch -- $kind {
    
        clear_menu {
          :clear_menu -menu [dict get $properties -menu]
        }
    
        form_link -
        entry {
          # sample entry: entry -name New.YouTubeLink -label YouTube -form en:YouTube.form
          if {$kind eq "form_link"} {
            ad_log_deprecated menu-entry $link entry
          }
          if {[dict exists $properties -link]} {
            set link [dict get $properties -link]
          } elseif {[dict exists $properties -form]} {
            set q [expr {[dict exists $properties -query] ? "-query [dict get $properties -query]" : ""}]
            dict with bind_vars {
              set link [::$package_id make_form_link  -form [dict get $properties -form]  -parent_id ${:parent_id}  -nls_language $nls_language  -return_url $return_url  {*}$q]
            }
          } elseif {[dict exists $properties -object_type]} {
            set link [::$package_id make_link  $package_id edit-new  [list object_type [dict get $properties -object_type]]  parent_id return_url autoname template_file]
          } else {
            :log "Warning: no link specified"
            set link ""
          }
          if {[dict exists $properties -disabled] && [dict get $properties -disabled]} {
            set link ""
          }
          set item [list url $link]
          if {[dict exists $properties -label]} {
            lappend item label [dict get $properties -label]
          } else {
            #
            # We have no explicit label. Replace dots of menu entry
            # names by dashes for message key.
            #
            set locale [::xo::cc locale]
            set dname [string map {. -} [dict get $properties -name]]
    
            foreach message_key [list xowiki.menu-$dname xowf.menu-$dname] {
              if {[lang::message::message_exists_p en_US $message_key]} {
                lappend item label [lang::message::lookup $locale $message_key]
                break
              }
            }
          }
          :add_menu_item -name [dict get $properties -name] -item $item
        }
    
        dropzone {
          foreach {var default} {
            name dropzone
            uploader File
            disposition File
            label DropZone
          } {
            set $var $default
            if {[dict exists $properties -$var]} {
              set $var [dict get $properties -$var]
            }
          }
          if {![info exists disposition] && [info exists uploader]} {
            # use the legacy name
            set disposition $uploader
          }
    
          set link [::$package_id make_link ${:parent_id} file-upload]
          :add_extra_item -name $name -type DropZone  -item [list url $link disposition $disposition label $label]
        }
    
        modebutton {
          foreach {var default} {
            name modebutton
            button admin
            label ""
          } {
            set $var $default
            if {[dict exists $properties -$var]} {
              set $var [dict get $properties -$var]
            }
          }
          if {$label eq ""} {set label $button}
          set state [::xowiki::mode::$button get]
          set link [::$package_id make_link ${:parent_id} toggle-modebutton]
          :add_extra_item -name $name -type ModeButton  -item [list url $link on $state label $label]
        }
        config {}
        default {
          error "unknown kind of menu entry: $kind"
        }
      }
    }