Class ::xowiki::includelet::folders (public)
::xowiki::IncludeletClass ::xowiki::includelet::folders \ [ -show_full_tree show_full_tree ] \ [ -context_tree_view context_tree_view ]
Defined in /var/www/openacs.org/packages/xowiki/tcl/folder-procs.tcl
List the folder tree of the current instance
- Switches:
- -show_full_tree (optional)
- (default false)
- -context_tree_view (optional)
- (default false)
- Testcases:
- No testcase defined.
Source code: namespace eval ::xowiki::includelet {} ::nsf::object::alloc ::xowiki::IncludeletClass ::xowiki::includelet::folders {set :__default_metaclass ::xotcl::Class set :__default_superclass ::xotcl::Object set :aggregating false set :cacheable false set :localized true set :personalized true} ::xowiki::includelet::folders instproc render {} { :get_parameters set tree [:build_tree] switch [::template::CSS toolkit] { 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 } ::xowiki::includelet::folders instproc collect_folders {-package_id:required -folder_form_id -link_form_id {-parent_id ""} {-subtree_query ""} {-depth 3}} { 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 } ::xowiki::includelet::folders instproc build_sub_tree {-node -folders} { :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 } } ::xowiki::includelet::folders instproc folder_query {-form_id:integer,required -package_id:integer,required {-parent_id:integer,0..1 ""}} { 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) }] } ::xowiki::includelet::folders instproc include_head_entries {} { switch [::template::CSS toolkit] { yui {::xowiki::Tree include_head_entries -renderer yuitree -style folders} bootstrap - default { ::xowiki::Tree include_head_entries -renderer bootstrap3 } } } ::xowiki::includelet::folders instproc build_tree {} { :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 -all -index 0 $menu_entries config] if {$have_config != -1} { # # In case, we have multiple entries, use the last one. # set have_config [lrange $have_config end end] # # 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 } ::xowiki::includelet::folders instparametercmd id ::xowiki::includelet::folders instparametercmd parameter_declaration ::xowiki::includelet::folders instparametercmd __decoration ::nsf::relation::set ::xowiki::includelet::folders superclass ::xowiki::Includelet ::nx::slotObj -container slot ::xowiki::includelet::folders ::xowiki::includelet::folders::slot eval {set :__parameter { {__decoration plain} {parameter_declaration { {-show_full_tree false} {-context_tree_view false} }} {id "[xowiki::Includelet js_name [self]]"} }} ::nsf::object::alloc ::xotcl::Attribute ::xowiki::includelet::folders::slot::id {set :accessor public set :configurable true set :convert false set :default {[xowiki::Includelet js_name [self]]} set :defaultmethods {} set :disposition alias set :domain ::xowiki::includelet::folders set :incremental 0 set :manager ::xowiki::includelet::folders::slot::id set :methodname id set :multiplicity 1..1 set :name id set :per-object false set :position 0 set :required false set :substdefault 0b111 set :trace none : init} ::nsf::object::alloc ::xotcl::Attribute ::xowiki::includelet::folders::slot::__decoration {set :accessor public set :configurable true set :convert false set :default plain set :defaultmethods {} set :disposition alias set :domain ::xowiki::includelet::folders set :incremental 0 set :manager ::xowiki::includelet::folders::slot::__decoration set :methodname __decoration set :multiplicity 1..1 set :name __decoration set :per-object false set :position 0 set :required false set :substdefault 0b111 set :trace none : init} ::nsf::object::alloc ::xotcl::Attribute ::xowiki::includelet::folders::slot::parameter_declaration {set :accessor public set :configurable true set :convert false set :default { {-show_full_tree false} {-context_tree_view false} } set :defaultmethods {} set :disposition alias set :domain ::xowiki::includelet::folders set :incremental 0 set :manager ::xowiki::includelet::folders::slot::parameter_declaration set :methodname parameter_declaration set :multiplicity 1..1 set :name parameter_declaration set :per-object false set :position 0 set :required false set :substdefault 0b111 set :trace none : init}XQL Not present: Generic, PostgreSQL, Oracle