Forum OpenACS Development: Re: Just noticed something strange happening with acs-templating if tags....

Diagnostics FYI, Richard,

I've seen this when the adp tag wasn't recognized by acs-templating ..either due to a badly nested IF or other tag typo/issue.

Testing to see if the IF tag triggers will likely show that it is ignored by acs-templating ie it's rendered as plain content due to some adp tag issue before it.

cheers,

Ok, I've found the reason, but it remains a problem for me!

The conditionals that are coming through to the browser are those that I have nested within a <property> tag.  I've tried to do something like this (simplified as example):

<property name="wikicmds">
  <div id="wikicmds">
    <if @admin_link@ not nil>
      <a href='@admin_link@'>Admin</a>
    </if>
  </div>
</property>

If I modify the above to this for diagnostic purposes:

<property name="wikicmds">TEST</property>
<div id="wikicmds">
  <if @admin_link@ not nil>
    <a href='@admin_link@'>Admin</a>
  </if>
</div>

....then the if statements no longer come through to the browser.

I need to do this in order to get the wikicmds up into the master template, because I want them to be children of an element that is within the master template.  This is to achieve robust and reliable positioning using CSS.

I was not aware of this limitation.  Is this indeed the case, that acs-templating is not designed to evaluate <if> tags that are enclosed within <property> tags?

Logically, I would expect the <if> statements to be evaluated first, to construct the property string to pass up.  I would not expect the conditional to be passed up for evaluation in the variable context of the receiving master template.

Any suggestions for a workaround, or comments on this behaviour would be much appreciated.

Regards
Richard

Richard,

you can try the following: Replace the definition of the property tag in acs-templating/tcl/tag-init.tcl by

template_tag property { chunk params } {

  set name [ns_set iget $params name]

  # quote dollar signs, square bracket and quotes
  regsub -all {[\]\[\"\\$]} $chunk {\\&} quoted_chunk

  template::adp_append_code "set __adp_properties($name) \[ns_adp_parse -string \"$quoted_chunk\"\]"
}
After restarting the server, browse the xowiki instance. The if-tag from the source should be gone, the variables of the if-condition should be resolved in the right context, since ns_adp_parse is delayed until page-view time. Maybe variable scoping needs more fiddling.

You can debug the compiled output via ds/shell:

  • get the full name of the compiled adp-proc: info commands ::template::code::adp::*xowiki*
  • check the body of the compiled template: info body ::template::code::adp::FULLNAME

This change adds an extra level of ADP-parsing for properties. Hope, this helps

-gustaf neumann

Gustaf,

Fantastic, thank you. I am not familiar with the acs-templating code so that is fabulously helpful.

I'll add that and report back.

Regards
R.

The template seems to have been parsed correctly - abridged output from:

info body ::template::code::adp::/web/wikirim/packages/xowiki/www/view-erim

set __adp_properties(wikicmds) [ns_adp_parse -string "
    <div id='wikicmds'>
      <div id='wikicmds-left'>
        <if [ad_quotehtml [lang::util::localize ${index_link}]] not nil>
          <a id='wikicmds-index' href='[ad_quotehtml [lang::util::localize ${index_link}]]' accesskey='i' title='Contents page ...'>
            <span data-icon='&#xe000;' aria-hidden='true'></span>
            &nbsp;
          </a>
        </if>
      </div>
    </div>
  "]

...but nothing is displayed so the conditions must be evaluating to false.  I'm a bit out of my depth with variable scoping in acs-templating!

R.

After a bit more digging I have found that the html contained within the property tags is being treated as a string and having its <, >, " etc. characters substituted by html codes.

For example, if you test with this in the xowiki template:

<property name="wikicmds">||<div id="test">TEST</div>||</property>

...and this in the plain-master.adp:

<if @wikicmds@ not nil>
  CONTENTHERE:@wikicmds@:CONTENTHERE
</if>

The result in the browser source is:

CONTENTHERE:||&lt;div id=&quot;test&quot;&gt;TEST&lt;/div&gt;||:CONTENTHERE

Regards
Richard

Oh, sorry, disregard last post. I had missed out the ;noquote@

R.

Right, the problem is the <if> tags.  If I do this in the xowiki template:

<property name="wikicmds">
  <div id="test">
    TEST
  </div>
</property>

Then I get the expected result in the document source:

<div id="test">TEST</div>

But as soon as I introduce an <if> tag:

<property name="wikicmds">
  <div id="test">
    <if @index_link@ not nil>
      TEST
    </if>
  </div>
</property>

...then what I get is this:

</div>

Yes, that's just a single closing tag without the corresponding opening div tag.

Regards
Richard

Unfortunately, after looking into more details, the problem is not the IF-tag or the variable scoping, but the way how OpenACS handles @-variables. The best, i can offer is the following approach, falling back to tcl + aolserver/NaviServer primitiva:
  <property name="foo">
  ...
  <tcl>
  if {[info exists admin_link]} {
      ns_puts "<a href='$admin_link' accesskey='a' title='Administer this package ...'>Admin</a> ·"
  }
  </tcl>
  <link rel="stylesheet" type="text/css" href="/resources/xowiki/xowiki.css" media="all" >
  ...
This means, instead of using the IF-tag and @-variables, one can use tcl-code and tcl-vars. If this looks feasible for you, i'll post the necessary modifications... This approach requires only a slightly more complex change like the one posted before

-gustaf neumann

Gustaf,

Thank you for the follow-up, and for the suggestion of falling back to the lower level solution.

It occurs to me that whilst you clearly cannot nest <if> tags inside a <property> tag, you can of course put <property> tags inside an <if> tag! 😊

I have therefore re-ordered my template to conditionally populate a property for each of the wikicmds, and to pass these properties separately up to the master template.  The master template will display these if they are not nil and will wrap them in their containing <div>.  This seems to work just fine.

The advantage is that this works without any modification to acs-templating.  The disadvantage is that it requires xowiki specific modification to my plain-master.adp, however this is in a custom theme package anyway, so not really a problem.

Whilst doing this I discovered something else I didn't know, which is that property names cannot contain a hyphen! Is that widely known?

If I pass up and test for <property name="wikicmds_index"> everything works as expected.  However, if I use <property name ="wikicmds-index"> I get an error message inserted into the page which reads:

IF tag nil test uses string not variable for "@wikicmds-index@"

I wonder if that is a feature or a bug?

Regards & many thanks,
Richard

Ok, i read through the lines, that you are happy with your solution. I'll keep the mentioned modification on my development machine, but do not investigate further.

Concerning the property names: I am not aware of any document that defines the valid syntax of the names, but i am not surprised that there are limitations. however, it is not worth to try to lift these.