::xo::library doc { XoWiki - definition of link types and their renderers @creation-date 2006-04-15 @author Gustaf Neumann @cvs-id $Id: link-procs.tcl,v 1.98 2017/09/30 18:12:53 gustafn Exp $ } namespace eval ::xowiki { # # generic link methods # Class create BaseLink -parameter { cssclass cssid href label title target extra_query_parameter {anchor ""} {query ""} } BaseLink instproc built_in_target {} { # currently, we do not support named frames, which are mostly deprecated return [expr {[my target] in {_blank _self _parent _top}}] } BaseLink instproc anchor_atts {} { set atts {} if {[my exists title]} {lappend atts "title='[string map [list ' {'}] [my title]]'"} if {[my exists target] && [my built_in_target]} { lappend atts "target='[my target]'" } return [join $atts " "] } BaseLink instproc mk_css_class {{-additional ""} {-default ""}} { set cls [expr {[my exists cssclass] ? [my cssclass] : $default}] if {$additional ne ""} { if {$cls eq ""} {set cls $additional} else {append cls " " $additional} } if {$cls ne ""} {set cls "class='$cls'"} return $cls } BaseLink instproc mk_css_class_and_id {{-additional ""} {-default ""}} { if {[my exists cssid]} {set id "id='[my cssid]'"} else {set id ""} set cls [my mk_css_class -additional $additional -default $default] return [string trim "$cls $id"] } # # external links # Class create ExternalLink -superclass BaseLink ExternalLink instproc render {} { my instvar href label set css_atts [my mk_css_class_and_id -additional external] return "$label " } # # internal links # Class create Link -superclass BaseLink -parameter { {type link} name lang stripped_name page parent_id package_id item_id {form ""} revision_id is_self_link } Link instproc init {} { my instvar page name set class [self class]::[my type] if {[my isclass $class]} {my class $class} if {![my exists name]} { set name [string trimleft [my lang]:[my stripped_name] :] } elseif {![my exists stripped_name]} { # set stripped name and lang from provided name or to the default my instvar stripped_name lang if {![regexp {^(..):(.*)$} $name _ lang stripped_name]} { set stripped_name $name; set lang "" } } if {![my exists label]} {my label $name} if {![my exists parent_id]} {my parent_id [$page parent_id]} if {![my exists package_id]} {my package_id [$page package_id]} #my msg "--L link has class [my info class] // $class // [my type] // [my parent_id]" } Link instproc link_name {-lang -stripped_name} { return $lang:$stripped_name } Link instproc resolve {} { return [my item_id] } Link instproc render_target {href label} { #ns_log notice render_target set target [my target] if {[info commands ::xowiki::template::$target] ne ""} { # # The target template exists. use the template # # This is a situation, where potentially a # recursive inclusion is happening. The included content is # added to the html output only once, with a unique id, which # can be referenced multiple times. The link is included for # each occurrence. # set item_id [my item_id] set targetId [xowiki::Includelet html_id [my item_id]-$target] set page [::xo::db::CrClass get_instance_from_db -item_id $item_id -revision_id 0] set content "Loading ..." set withBody true if {[::xowiki::template::$target render_content]} { set key ::__xowiki_link_rendered($targetId) if {![info exists $key]} { set $key 1 set content [$page render_content] } else { #ns_log notice "modal with is already included: $key" set page ::$item_id set withBody false } } set result [::xowiki::template::$target render \ -with_body $withBody \ -title [$page title] \ -id $targetId \ -content $content \ -label $label \ -href $href] return $result } else { ns_log notice "xowiki::link: unknown target $target" return "$label" } } Link instproc render_found {href label} { if {$href eq ""} { return "$label" } elseif {[my exists target] && ![my built_in_target]} { return [my render_target $href $label] } else { return "$label" } } Link instproc render_not_found {href label} { if {$href eq ""} { return \[$label\] } else { return " $label" } } Link instproc pretty_link {item_id} { my instvar package_id return [::$package_id pretty_link -parent_id [my parent_id] -lang [my lang] \ -anchor [my anchor] -query [my query] [my name]] } Link instproc new_link {} { my instvar package_id form set page [my page] set nls_language [$page get_nls_language_from_lang [my lang]] if {$form ne ""} { return [$package_id make_form_link -form $form \ -parent_id [my parent_id] \ -name [my name] \ -nls_language $nls_language] } if {[$page exists __unresolved_object_type]} { # get the desired object_type for unresoved entries set object_type [$page set __unresolved_object_type] } else { set object_type [[$page info class] set object_type] if {$object_type ne "::xowiki::Page" && $object_type ne "::xowiki::PlainPage"} { # TODO: this is a temporary solution. we should find a way to # pass similar to file or image entries the type of this # entry. Maybe we can get the type as well from a kind of # blackboard, where the type of the "edit" wiki-menu-entry is # stored as well. set object_type ::xowiki::Page } } return [$page new_link \ {*}[expr {[info exists object_type] ? [list -object_type $object_type] : {}}] \ -name [my name] -title [my label] -parent_id [my parent_id] \ -nls_language $nls_language $package_id] } Link instproc render {} { my instvar package_id set page [my page] set item_id [my resolve] if {$item_id} { $page references resolved [list $item_id [my type]] ::xowiki::Package require $package_id if {![my exists href]} { my set href [my pretty_link $item_id] } my render_found [my set href] [my label] } else { set new_link [my new_link] set html [my render_not_found $new_link [my label]] $page references unresolved $html return $html } } Link instproc lookup_xowiki_package_by_name {name start_package_id} { set ancestors [site_node::get_ancestors \ -node_id $start_package_id \ -element node_id] foreach a $ancestors { set package_id [site_node::get_children -node_id $a -package_key xowiki \ -filters [list name $name] -element package_id] if {$package_id ne ""} { #my log "--LINK found package_id=$package_id [my isobject ::$package_id]" ::xowiki::Package require $package_id return $package_id } } return 0 } # # Link template # ::xotcl::Class create ::xowiki::LinkTemplate -parameter {link_template body_template {render_content true}} ::xowiki::LinkTemplate instproc render { {-with_link:boolean true} {-with_body:boolean true} {-title "TITLE"} {-id "ID"} {-content ""} {-label "LABEL"} {-href ""} } { set result "" # this can be used into templates as id to safely attach event # handlers to elements set timed_id [clock microseconds] if {$with_link} {append result [subst [my link_template]]} if {$with_body} {append result [subst [my body_template]]} return $result } # # Small bootstrap modal # ::xowiki::LinkTemplate create ::xowiki::template::modal-sm -link_template { $label } -body_template {
} # # Large bootstrap modal # ::xowiki::LinkTemplate create ::xowiki::template::modal-lg -link_template { $label } -body_template { } # # Small bootstrap modal using ajax # ::xowiki::LinkTemplate create ::xowiki::template::modal-sm-ajax -render_content false -link_template { $label } -body_template { } # # Large bootstrap modal using ajax # ::xowiki::LinkTemplate create ::xowiki::template::modal-lg-ajax -render_content false -link_template { $label } -body_template { } # # folder links # Class create ::xowiki::Link::folder -superclass ::xowiki::Link ::xowiki::Link::folder instproc link_name {-lang -stripped_name} { return $stripped_name } ::xowiki::Link::folder instproc pretty_link {item_id} { my instvar package_id return [::$package_id pretty_link \ -anchor [my anchor] -parent_id [my parent_id] -query [my query] [my name] ] } # # language links # Class create ::xowiki::Link::language -superclass ::xowiki::Link -parameter { return_only } ::xowiki::Link::language instproc render {} { set page [my page] my instvar lang name package_id set item_id [my resolve] if {$item_id} { set image_css_class "found" set link [$package_id pretty_link -lang $lang -parent_id [my parent_id] [my stripped_name]] } else { set image_css_class "undefined" set last_page_id [$page set item_id] set object_type [[$page info class] set object_type] set link [$package_id make_link $package_id \ edit-new object_type name last_page_id] } # my log "--lang_link=$link" if {[my exists return_only] && [my return_only] ne $image_css_class} { set link "" } if {$link ne ""} { $page lappend lang_links($image_css_class) \ "" } return "" } # # image links # Class create ::xowiki::Link::image -superclass ::xowiki::Link \ -parameter { center float width height padding padding-right padding-left padding-top padding-bottom margin margin-left margin-right margin-top margin-bottom border border-width position top botton left right } ::xowiki::Link::image instproc resolve_href {href} { set l [[my page] create_link $href] if {[$l istype ::xowiki::ExternalLink]} { set href [$l href] } else { set href_item_id [$l resolve] set href [$l pretty_link $href_item_id] } return $href } ::xowiki::Link::image instproc render {} { my instvar name package_id label set page [my page] set item_id [my resolve] #my log "-- image resolve for $page returned $item_id (name=$name, label=$label)" if {$item_id} { set link [$package_id pretty_link -download true -query [my query] \ -absolute [$page absolute_links] -parent_id [my parent_id] $name] #my log "--l fully quali [$page absolute_links], link=$link" $page references resolved [list $item_id [my type]] my render_found $link $label } else { set last_page_id [$page set item_id] set object_type ::xowiki::File set link [$package_id make_link $package_id edit-new object_type \ [list parent_id [my parent_id]] \ [list title [ad_html_to_text -no_format -- $label]] \ [list return_url [::xo::cc url]] \ autoname name last_page_id] set html [my render_not_found $link $label] $page references unresolved $html return $html } } ::xowiki::Link::image instproc render_found {link label} { set style ""; set pre ""; set post "" foreach a { float width height center padding padding-right padding-left padding-top padding-bottom margin margin-left margin-right margin-top margin-bottom border border-width position top botton left right } { if {[my exists $a]} { if {$a eq "center"} {set pre "