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

This example has been captured using Xowiki's view-default.adp template.

Studying the source in a browser, the oacs templating <if> tags are coming through into the DOM and can be browsed using the development tools.

The following markup in the adp template:

<if @new_link@ not nil>
  <a id="revisions" title="Show revisions of this page ..." accesskey="r" href="/erim/?m=revisions">Show revisions of this page ...</a>
</if>

arrives in the DOM as:

<if nil="" not="" ?m="revisions" xowiki="">
  <a id="revisions" title="Show revisions of this page ..." accesskey="r" href="/erim/?m=revisions">Show revisions of this page ...</a>
</if>

I thought that the idea was that these tags were evaluated by acs-templating to determine page contents.  I thought the idea was that none of this logic should come through to the browser's DOM.

Did I misunderstand or has something gone squiffy somewhere?

Regards
Richard

Are you sure that code is being recognized/executed by acs-templating?
Hmm, a very sound suggestion. It certainly looks that way, but everything seems to work normally, it is only in evidence when you study the DOM.

R.

What exactly you mean by studying the DOM? Do you see the "IF", when you load in page into the browser and look into the source?

-g

Yes.  From source:

<div id='wikicmds'>
  <if /xowiki/ not nil>
    <a href="/xowiki/" accesskey='i' title='Go to the start of this package ...'>Index</a>
  </if>
...
etc.
...
</div>

When viewed as I initially saw it, using the Firebug html viewer in Firefox, it has clearly been further mangled.  I suspect this is because Firebug is trying to make some sense of it:

<div id="wikicmds">
  <if nil="" not="" xowiki="">
    <a title="Go to the start of this package ..." accesskey='i' href="/xowiki/">Index</a>
  </if>
...
etc.
...
</div>

In both cases, the <if> tags are clearly present in the source received by the browser.

Regards
Richard

just double checked the HTML source of a xowiki default configuration with two actual installations, I see no IF-Tags in the generated HTML source. So it looks as something local to your configuration...

-gustaf neumann

hmm, never seen this ... and double checked with all recent versions, everything looks fine to me. to ease communication, can you check the problem in a small instance with a the acs-head version of acs-core and xotcl-core + xowiki?
Ok, I'll do that and report back. I have never seen/noticed this before either.

I wonder if it could be a consequence of me creating a custom theme, and not quite getting the set-up quite right. This is the first time I have done it, so I may have messed it up.

R.

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.

..due to some *silent* adp tag issue..
Benjamin, Gustaf,

Thank you both very much. I'll hunt down my error. I have been working on the templates so could easily have messed something up.

Sorry for the false alarm!

Regards
Richard

Simplest solution is to generate the HTML you want to embed in the property in your Tcl script and just insert that variable reference containing the HTML into the property tag.

SInce the template is only parsed once, you can parse the if tags then the outer property tags. Its all parsed into one tcl script.

You could modify the property tag tcl to accept code within (such as the multiple tag etc.) but it seems overly complicated. Just evaluate what you need in the tcl script and generate the HTML there.

Dave,

Thanks for the reply. Yes, I was hoping to avoid hacking away at the tcl scripts with abandon like I used to!

😊

R.