Class ::xowiki::includelet::folders

::xowiki::includelet::folders[i] create ... \
           [ -__decoration (default "plain") ] \
           [ -id (default "[xowiki::Includelet js_name [self]]") ] \
           [ -parameter_declaration (default " {-show_full_tree false} {-context_tree_view false} ") ]

List the folder tree of the current instance
Documented Parameters:
show_full_tree
(default false)
context_tree_view
(default false)
Defined in packages/xowiki/tcl/folder-procs.tcl

Class Relations

  • class: ::xowiki::IncludeletClass[i]
  • superclass: ::xowiki::Includelet[i]
::xowiki::IncludeletClass create ::xowiki::includelet::folders \
     -superclass ::xowiki::Includelet

Methods (to be applied on instances)

  • __decoration (setter)

  • build_sub_tree (scripted)

    :get_parameters
    
    set current_object [$node object]
    set current_item_id [$current_object item_id]
    set sub_folders [list]
    set remaining_folders [list]
    
    foreach f $folders {
      if {[$f parent_id] ne $current_item_id} {
        lappend remaining_folders $f
      } else {
        lappend sub_folders $f
      }
    }
    
    #:msg "[$node label] has [llength $sub_folders] subfolders"
    foreach c $sub_folders {
    
      set label [$c title]
      if {[regexp [lang::util::message_key_regexp$label . innerValue]} {
        set label [_ $innerValue]
      }
      set folder_href [$c pretty_link]
    
      set is_current [expr {${:current_folder_id} eq [$c item_id]}]
      set is_open [expr {$is_current || $show_full_tree}]
    
      #regexp {^..:(.+)$} $label _ label
    
      set subnode [::xowiki::TreeNode new  -href $folder_href  -label $label  -object $c  -highlight $is_current  -expanded $is_open  -open_requests 1  -destroy_on_cleanup]
      $node add $subnode
    
      if {$is_current} {
        $node open_tree
    
        if {[nsf::is object ::__xowiki__MenuBar]
            && [::__xowiki__MenuBar exists submenu_pages(folder)]} {
          set owner [::__xowiki__MenuBar set submenu_owner(folder)]
          $subnode add_pages -full true  -book_mode [$owner set book_mode]  -owner $owner  [::__xowiki__MenuBar set submenu_pages(folder)]
        }
      }
    
      :build_sub_tree -node $subnode -folders $remaining_folders
    }
  • build_tree (scripted)

    :get_parameters
    
    set page ${:__including_page}
    if {[$page exists __link_source]} {
      set page [$page set __link_source]
    }
    set package_id [::xo::cc package_id]
    
    set lang [::xo::cc lang]
    set return_url [::xo::cc url]
    set nls_language [$page get_nls_language_from_lang $lang]
    
    set :folder_form_id [::$package_id instantiate_forms -forms en:folder.form]
    set :link_form_id   [::$package_id instantiate_forms -forms en:link.form]
    
    #:msg folder_form=${:folder_form_id}
    
    set :current_folder [$page get_folder -folder_form_ids ${:folder_form_id}]
    set :current_folder_id [${:current_folder} item_id]
    
    #:msg "FOLDERS [$page name] package_id $package_id current_folder ${:current_folder} [${:current_folder} name]"
    
    if {[::$package_id get_parameter MenuBar:boolean 0]} {
    
      #
      # We want a menubar. Create a menubar object, which might be
      # configured via the menu_entries property in the current
      # folder.
      #
      set menu_entries [list  {*}[::$package_id get_parameter ExtraMenuEntries {}]  {*}[${:current_folder} property extra_menu_entries]]
      set have_config [lsearch -index 0 $menu_entries config]
    
      if {$have_config > -1} {
        #
        # We have a special configuration for the menubar, probably
        # consisting of a default setup and/or a menubar class. The
        # entry should be of the form:
        #
        #    {config -use xxxx -class MenuBar}
        #
        set properties [lrange [lindex $menu_entries $have_config] 1 end]
        if {[dict exists $properties -class]} {
          set p_class [dict get $properties -class]
        }
        foreach p {-class -use} {
          if {[dict exists $properties $p]} {
            set p$p [dict get $properties $p]
          }
        }
      }
      set class ::xowiki::MenuBar
      if {[info exists p-class]
          && [info commands ::xowiki::${p-class}]
          && [::xowiki::${p-class} istype ::xowiki::MenuBar]
        } {
        set class ::xowiki::${p-class}
      } else {
        set class ::xowiki::MenuBar
      }
      set mb [$class create ::__xowiki__MenuBar -id menubar]
    
      if {[info exists p-use]
          && [$mb procsearch config=${p-use}] ne ""
        } {
        set config ${p-use}
      } else {
        set config default
      }
    
      #
      # Now we have a menubar $mb. Add folder-specific content to it.
      #
      # "bind_vars" will contain the variables used by "make_link" to
      # set the query parameters.  We do not want to see parent_ids in
      # the links of the root folder. When we insert to the root
      # folder, set opt_parent_id to empty to make argument passing
      # easy. "make_link" just checks for the existence of the
      # variable, so no add "parent_id" to the "bind_vars".
      #
    
      if {[${:current_folder_id} is_package_root_folder]} {
        set opt_parent_id ""
        set folder_link [::$package_id package_url]
        set bind_vars {}
        #:msg "use instance name as title to [::$package_id instance_name]"
        ${:current_folder} title [::$package_id instance_name]
      } else {
        set parent_id ${:current_folder_id}
        set opt_parent_id $parent_id
        ::xo::db::CrClass get_instance_from_db -item_id $parent_id
        set folder_link [${:current_folder} pretty_link]
        set bind_vars [list parent_id $parent_id opt_parent_id $parent_id]
      }
      lappend bind_vars nls_language $nls_language
    
      $mb current_folder ${:current_folder}
      $mb parent_id $opt_parent_id
      #:log "folders: call update_items with config '$config' bind_vars=$bind_vars"
      $mb update_items  -bind_vars $bind_vars  -config $config  -current_page $page  -folder_link $folder_link  -package_id $package_id  -return_url [ad_urlencode_folder_path [::xo::cc url]]
    }
    
    # Start with the "package's folder" as root folder
    set root_folder [::xo::db::CrClass get_instance_from_db  -item_id [::$package_id folder_id]]
    
    #
    # Check, if the optional context tree view is activated
    #
    set top_folder_of_tree $root_folder
    if {$context_tree_view || [::$package_id get_parameter FolderContextTreeView:boolean false]} {
      set parent_id [${:current_folder} parent_id]
      if {$parent_id ne -100} {
        set top_folder_of_tree $parent_id
        #:msg top_folder_of_tree=$top_folder_of_tree
      }
    }
    
    if {$top_folder_of_tree eq $root_folder
        || [$top_folder_of_tree parent_id] eq "-100"
      } {
      set href  [::$package_id package_url]
      set label [::$package_id instance_name]
      #:msg "use instance name in tree display"
    } else {
      set href  [$top_folder_of_tree pretty_link]
      set label "[$top_folder_of_tree title] ..."
    }
    
    set t [::xowiki::Tree new -id foldertree_[:id] -destroy_on_cleanup]
    set node [::xowiki::TreeNode new  -href $href  -label $label  -highlight [expr {${:current_folder_id} == [$top_folder_of_tree item_id]}]  -object $top_folder_of_tree  -expanded 1  -orderby label  -open_requests 1  -destroy_on_cleanup]
    $t add $node
    set folders [:collect_folders  -package_id $package_id  -folder_form_id ${:folder_form_id}  -link_form_id ${:link_form_id}]
    
    #:msg "folder ${:folder_form_id} has [llength $folders] entries"
    #:msg [lmap f $folders {$f item_id}]
    
    :build_sub_tree -node $node -folders $folders
    return $t
  • collect_folders (scripted)

    set folders [list]
    
    #
    # In case no "folder_form_id" or "link_form_id" were provided,
    # fetch it here.
    #
    foreach {var form} {
      folder_form en:folder.form
      link_form en:link.form
    } {
      if {![info exists ${var}_id]} {
        set $var [::$package_id instantiate_forms -forms $form]
        set ${var}_id [[set $var] item_id]
      }
    }
    
    # safety belt, for recursive structures
    if {$depth < 1} {
      return $folders
    }
    
    #
    # Get Folders
    #
    set sql [:folder_query -form_id $folder_form_id  -parent_id $parent_id  -package_id $package_id]
    
    #ns_log notice "folder_pages:\n$sql"
    set folder_pages [::xowiki::FormPage instantiate_objects -sql $sql  -named_objects true -object_named_after "item_id"  -keep_existing_objects true  -object_class ::xowiki::FormPage -initialize true]
    
    #
    # Get links.
    #
    set sql [:folder_query -form_id $link_form_id  -parent_id $parent_id  -package_id $package_id]
    #ns_log notice "links (parent-id ='$parent_id'):\n$sql"
    set links [::xowiki::FormPage instantiate_objects -sql $sql  -named_objects true -object_named_after "item_id"  -object_class ::xowiki::FormPage -initialize true]
    
    #:msg "[llength [$links children]] links under $parent_id "
    
    set folders [$folder_pages children]
    
    #
    # filter links to folders.
    # links might be cross-package links
    #
    foreach l [$links children] {
      set link_type [$l get_property_from_link_page link_type]
      set cross_package [$l get_property_from_link_page cross_package]
      #:log "==================== [$l name]: link_type  $link_type cross package $cross_package"
    
      if {$link_type ne "folder_link"} continue
    
      if {$cross_package} {
        #
        # We found a cross-package link. These kind of links require
        # further queries.
        #
        set target [$l get_target_from_link_page]
        set sub_folders [:collect_folders -package_id [$target physical_package_id]  -folder_form_id $folder_form_id -link_form_id $link_form_id  -parent_id [$target item_id]  -depth [expr {$depth -1}]]
    
        foreach f $sub_folders {
    
          #:msg "$f [$f name] is a folder-link pointing to $target [$target name] current ${:current_folder_id}"
          if {[$f parent_id] eq [$target item_id]} {
            #:msg "1 found child [$f name] and reset parent_id from [$f parent_id] to [$l item_id], package_id [$l package_id]"
            #
            # reset the current_folder if necessary
            #
            if {${:current_folder_id} eq [$f parent_id]} {
              set :current_folder_id [$l item_id]
            }
            #
            # set the resolve_context
            #
            $f set_resolve_context -package_id [$l package_id] -parent_id [$l item_id]
            #
            # TODO we could save the double-fetch by collecting in
            # get_form_entries via item_ids, not via new objects.
            #
            #::xo::db::CrClass get_instance_from_db -item_id [$f item_id]
            [$f item_id] set_resolve_context -package_id [$l package_id] -parent_id [$l item_id]
          } else {
            #:msg "2 found child [$f name] and reset parent_id from [$f parent_id] to [$f parent_id], package id [$l package_id]"
            $f set_resolve_context -package_id [$l package_id] -parent_id [$f parent_id]
            #::xo::db::CrClass get_instance_from_db -item_id [$f item_id]
            [$f item_id] set_resolve_context -package_id [$l package_id] -parent_id [$f parent_id]
          }
    
          #:msg "including $f [$f name] [$f item_id]"
          lappend folders $f
        }
      }
      #:msg link=$link
      lappend folders $l
    }
    return $folders
  • folder_query (scripted)

    if {$parent_id eq ""} {
      return [subst {
        select * from xowiki_form_instance_item_view
        where page_template = '$form_id' and package_id = '$package_id'
        and publish_status = 'ready'
      }]
    }
    
    #
    # Oracle query missing
    #
    return [subst {
    select
         xi.package_id, xi.parent_id, xi.name,
         xi.publish_status, xi.assignee, xi.state, xi.page_template, xi.item_id,
         o.object_id, o.object_type, o.title AS object_title, o.context_id,
         o.security_inherit_p, o.creation_user, o.creation_date, o.creation_ip,
         o.last_modified, o.modifying_user, o.modifying_ip,
         cr.revision_id, cr.title, content_revision__get_content(cr.revision_id) AS text,
         cr.description, cr.publish_date, cr.mime_type, cr.nls_language,
         xowiki_form_page.xowiki_form_page_id,
         xowiki_page_instance.page_instance_id,
         xowiki_page_instance.instance_attributes,
         xowiki_page.page_id,
         xowiki_page.page_order,
         xowiki_page.creator
      from (
         WITH RECURSIVE child_items AS (
           select * from xowiki_form_instance_item_index
           where item_id = '$parent_id'
         UNION ALL
           select xi.* from xowiki_form_instance_item_index xi, child_items
           where xi.parent_id = child_items.item_id
      )
      select * from child_items
         where page_template = '$form_id' and package_id = '$package_id' and publish_status = 'ready') xi
         left join cr_items ci on (ci.item_id = xi.item_id)
         left join cr_revisions cr on (cr.revision_id = ci.live_revision)
         left join acs_objects o on (o.object_id = ci.live_revision)
         left join xowiki_page on (o.object_id = xowiki_page.page_id)
         left join xowiki_page_instance on (o.object_id = xowiki_page_instance.page_instance_id)
         left join xowiki_form_page on (o.object_id = xowiki_form_page.xowiki_form_page_id)
    }]
  • id (setter)

  • include_head_entries (scripted)

    switch [::${:package_id} get_parameter PreferredCSSToolkit:graph bootstrap] {
      yui     {::xowiki::Tree include_head_entries -renderer yuitree -style folders}
      bootstrap -
      default { ::xowiki::Tree include_head_entries -renderer bootstrap3 }
    }
  • parameter_declaration (setter)

  • render (scripted)

    :get_parameters
    
    set tree [:build_tree]
    switch [::${:package_id} get_parameter PreferredCSSToolkit:graph bootstrap] {
      yui {
           set js "
           var [:js_name];
           YAHOO.util.Event.onDOMReady(function() {
             [:js_name] = new YAHOO.widget.TreeView('foldertree_[:id]');
             [:js_name].subscribe('clickEvent',function(oArgs) {
               var m = /href=\"(\[^\"\]+)\"/.exec(oArgs.node.html);
               return false;
             });
             [:js_name].render();
           });
           "
        set HTML [$tree render -style yuitree -js $js]
      }
      bootstrap -
      default   {
        #:msg "render tree $tree // [$tree procsearch render ]"
        set HTML [$tree render -style bootstrap3-folders]
        #set HTML [$tree render -style list -properties {CSSclass_top_ul xowiki-tree}]
      }
    }
    #:log HTML=$HTML
    return $HTML