Version 4 of Tclhttpd Content Wrapping

Updated 2004-12-03 08:35:39 by CMCc

Sometimes it's useful to be able to abstract away structural stuff, like headers, margins, footers and such.

The following code can be put in the custom directory, and is suitable as a post-generation filter.

What this means is that if you put [Httpd_Filter [Httpd_CurrentSocket] Wrap] into the .tml of a directory, any template will be substituted into wrapper.html instead of the token %BODY%.

It's not perfect: changes in the wrapper won't regenerate the whole page.

-- CMcC 20041203


    # wrap.tcl
    #
    # This code will use the post-content filter to substitute content
    # into a file called wrapper.tml or wrapper.html at the point where %BODY% occurs.
    # 
    # To trigger this, put the following in a Doc domain's .tml
    #
    #        Httpd_Filter [Httpd_CurrentSocket] Wrap

    package require struct::list
    proc Wrap {sock content} {
        upvar #0 Httpd$sock data

        foreach dir [::struct::list::Lreverse [Doc_GetPath $sock]] {
            set template [file join $dir wrapper.tml]
            set wrapper [file join $dir wrapper.html]

            if {![file exists $wrapper]
                && [file exists $template]} {
                # instantiate the wrapper
                set dynamic 0
                set wrapper [TemplateInstantiate $sock $template $wrapper $data(suffix) dynamic 0]
                set content [string map [list %BODY% $content] $wrapper]
                break
            } elseif {[file exists $wrapper]} {
                # the wrapper exists
                set fd [open $wrapper]; set wrapper [read $fd]; close $fd
                set content [string map [list %BODY% $content] $wrapper]
                break
            }
        }

        return $content
    }

[Category Tclhttpd]