Forum OpenACS Development: New templating tag

Posted by Tom Jackson on

The ACS templating system has a reasonable number of tags. One tag is called 'include' and is used to include another adp template in the current template. Unfortunately, you have to pass all the variables and values to the sub-template, so it is not very convenient.

It turns out to be fairly easy to add new tags. I added a tag called 'read', for lack of a better name. What it does is to read a sub-template and include it into the current template, without the need to pass any variables. It also works recursively. Here is the code, which should be placed in acs-templating/tcl/tag-init.tcl:

template_tag read { params } {

  set source [ns_set iget $params src]
  if {![string match "absolute" [file pathtype $source]]} { 
    set source [ns_normalizepath [ad_conn adp_root]/$source]
  set chunk [template::util::read_file $source]
  template::adp_compile_chunk $chunk

Problems include the fact that compiled templates are cached. Only the mtime of the parent adp is used to determine if the template is up-to-date. On a stable system, this should not be a problem. For development, however, you need to touch parent.adp You can use the tag as follows:

<read src="child.adp"> or <read src="/absolute/path/to/child.adp">

If using a relative path, you need to set ad_conn(adp_root) to something useful:

global ad_conn
set ad_conn(adp_root) "/absolute/path/to"
Posted by David Walker on
Sounds good.

Your tag usage doesn't display because my browser thinks it's html
so I've reproduced it here

<read src="child.adp">
<read src="/absolute/path/to/child.adp">

You might also consider writing a command to make the parent's
variables available to the child.
Assuming the templating system uses the same ideas as the rest of
tcl a tag that does the following should make all the parent's
variables available to the child

foreach var [uplevel 1 {info vars}] {
  upvar $var $var

Posted by Tom Jackson on

Actually all the vars available in the parent are available in the child, That was the intent! The tag reads the file and evaluates it as if it were in the current file.

However, it looks like adp tags (<% %>) do not get evaluated in the child. I don't know why this is, but you can use the templating 'tcl' tag instead.

Posted by David Walker on
I'm sorry. I was unclear.  I meant that rather than using your read
tag you could use the include tag with a get_parent_vars (using the
code from my previous post) tag for a similar effect
Posted by Tom Jackson on

Unfortunately the include tag doesn't work like that. To pass in arrays (to a multiple tag) you have to prepend & to the array name. The upvaring is done in a parse proc that takes into account the level, which isn't always 1.

Posted by Tom Jackson on

Sorry for two short posts. I probably should have called this tag 'source', because it does pretty much what the tcl source command does. One confusing item with the templating system should be noted. These templates are actually converted to tcl code. They look like adp files, but AOLserver never sees them like that. This is why you get a visible error when you make a mistake.