Forum OpenACS Development: Looking for guidance is using template_tag to modify "input" tag

Request notifications

Hi

My use case is as follows: I want to intercept all usage of the "input" tag in ADPs, and in the case where it is of type "hidden", I want to do some further processing. Otherwise, display it is as normal.

I thought to use template_tag to do this, but I must confess that I'm struggling a little. In my tags-init.tcl, I have defined my tag:

template_tag input { params } {
    aims_template_tag_input $params 
}
Then in tags-procs.tcl I define the aims_template_tag_input proc.

I don't fully understand the context that I am now in. Changes to the files aren't always being picked up even when file is watched (seems to be some sort of caching of ADPs going on, but it's not consistent).

Below is the outline of what I'm trying to achieve. How can I display the input tag as defined in the ADP, in the case where it is not "type =hidden"?

ad_proc -public aims_template_tag_input { params } {
} {
  set type [template::get_attribute input $params type]
  if { $type ne "hidden" } {
    #here I want to display the input tag as normal 
  } else {
    #do further processing
  }
}
Any other advice about working with these tags? I have seen some very old threads describing this as a "dark art", and also stuff like "if you touch the source .adp it will recompile it again", but I can't get this to behave consistently.

many thanks for any pointers
Brian

Hi Brian,

below is a simple study that shows how to translate certain input tags in .adp pages (the example translates such tags into input tags of type 'text' with class "invisible"). I've tested this with plain NaviServer in an .adp page.

The OpenACS templating system is in some respects more tricky, since it has it own templating system on top of this for processing of the @-variables. It "compiles" such .adp file into low-level NaviServer pages and uses these later for delivery. So, when you add some tag definitions at runtime, there is no code that invalidates the already compiled pages.... that might be an explanation for the strange behavior you observed. .... so the best thing is to restart the server after adding tags.

all the best -g


library script


namespace eval ::template {

    proc tag-input {set} {
        set attrs [ns_set array $set]

        if {[dict exists $attrs type] && [dict get $attrs type] eq "hidden"} {
            dict set attrs class hidden
            dict set attrs type text
        } else {
            dict set attrs class visible
        }
        set output [join [lmap {k v} $attrs {set _ $k='$v'}] " "]
        return "<input $output>"
    }
}

ns_adp_registerscript input ::template::tag-input

page.adp

<!DOCTYPE html>
<html>
<body>
 <form action="/action.tcl">
  Name: <input type="text" name="fname"><br>
  <input type="hidden" name="foo" value="bar">  
  <input type="submit" value="Submit">
</form> 

page in browser:

<!DOCTYPE html>
<html>
<body>
 <form action="/action.tcl">
  Name: <input type='text' name='fname' class='visible'><br>
  <input type='text' name='foo' value='bar' class='hidden'>  
  <input type='submit' value='Submit' class='visible'>
</form> 
Dear Gustaf

many thanks for the help! I'll give this a try.

all the best
Brian

Hi Gustaf

I got a chance to play with your code and it works quite well. A few comments/questions.

I had to add the following to deal with XHTML tags e.g. <input... /> as there was an additional forwardslash key in the attrs dict.
set attrs [dict remove $attrs / ]

The code does modify the original HTML slightly but I don't think this is an isue e.g. 'checked' gets changed to 'checked="checked"'. I haven't tested more complex input fields e.g. ones with onclick or file uploads etc. Ideally it would be great to leave these as-is, but I'm not sure if this is possible?

Another question I have: do you know of any way from within the tag-input proc to pass messages to/from the containing form? My goal here is to remove all hidden input fields from the form, and replace them with a single hidden field whose value will be stored in the session, and which gets submitted in the form.

best wishes
Brian

'checked' gets changed to 'checked="checked"'

to avoid this, handle Boolean attributes separately (as this is necessary also on other places, such as e.g. in the xowiki/tcl/form-field-procs).

... pass messages to/from the containing form
It is possible to overload also "outer" tags, build a stack of such tags with client specific code and query this from the inner tag handlers.

-g

Thanks Gustaf!