This question about Topic Markup Language and applications: Answered

Set ViewTemplate based on contents

Hello,

How can I set the View Template based on contents, using an IF-statement?

My website is build up as a dictionary showing different definitions for words (the information is stored in the Form). This all works fine so far, but since there are some words with 4 definitions, the viewtemplate always has all fields 4 times. This slows down the page a lot. That's why I thought that maybe I could say like IF Form #4 is used, THEN use viewtemplate #4. and so on.

I already tried to do this using INCLUDE, but that did not work out, because the viewtemplate uses quotes which break entirely when included. It could solve the problem if I can fix that.

For those interested, here are the links to some relevant pages:

Thanks for your suggestions and other options.

-- Lieven - 27 Aug 2021

You can't: a VIEW_TEMPLATE is a preference setting that has to be known pretty early in the rendering pipeline of Foswiki. Processing marcros is done far later.

The view template itself should have the different conditions to render content differently.

Looking at your view template I have a few remarks:

  • lots of %IFs ... not bad in general but still overwhelming
  • none of your %IFs are indented in a way that they are readable easily. Try adding newlines here and there i.e. before then="..." and else="..."
  • not much template reusage: it directly builds upon TMPL:INCLUDE{"view"}: maybe a middle layer used by all pages on your site should cover the bulk of the non-specific code; you could also use multiple TMPL:INCLUDEs.
  • monolithic TMPL:DEFs: try to componentize them more splitting them into separate TMPL:DEFs in a meaningfull way
  • try not to mix HTML and TMPL:P in the same TMPL:DEF ... if possible; either call sub modules using TMPL:P that then hold the actual HTML, or have it all HTML on the leaf layer of the calling tree that TMPL:DEFs and TMPL:Ps define.

Back to your question, the main part of the page is in "content" ... somehow. I'd have a high-level %IF that calls different submodules for different needs. E.g. a page with 1 definition will call a TMPL:DEF "one-word-def" that has got a single TMPL:P "renderWordDef", a 2 definition page calls a TMPL:DEF "two-word-def" holding two "renderWordDef" etc. You just need to decide on the submodule being called within the same view template.

Just as an idea.

So there actually is not a real need to use different view templates based on some content condition.

Another solution is when 1 def pages, 2 def pages etc all have different data forms. This would directly lead to different view templates based on the data form using AutoTemplatePlugin.

-- MichaelDaum - 27 Aug 2021

While everything Michael says above is correct, I think there are much simpler ways to skin this cat. As a starting place, I'd propose taking the rendering to the topic content out of the view template and simply use an INCLUDE in the template to reference the topic that does most of the rendering. This releases you from the syntactic restrictions of view templates and opens up use of other plugins.

Looking over your code, I see that there's a lot of IF statements simply checking whether a field has a value. I believe FlexFormPlugin would eliminate a lot of this complexity since, by default, it only renders those fields that have content. You've also got a lot of repeating field references with the same name except a different numeral suffix (1-4). Filter plugin could eliminate all of the repeating code. On other pattern I see if different formatting based on the value of a field. I believe this could be simplified but INCLUDING separate sections named after the field value and containing the respective formatting.

If I have time, I'll take a quick shot at offering a draft of the code I have in mind.

-- LynnwoodBrown - 28 Aug 2021

Ok, below is my (partial) first draft of a topic that could be INCLUDED in your view template to replace most of the rendering you did in the view template. I'll admit, it's got some tricky code in it (which I haven't tested) but my objective was minimizing repetition of code. Let me mention a few things about what's in this example:
  • All the SET macros at the beginning define re-usable format strings. These could have been done via INCLUDEs but since they were mostly short, I decided this would be neater.
  • I use DBCachePlugin rather extensively here because it's ability to expand field values plus extra strings and only if the field has a value. It also allows for expanding more than one field depending on which one has a value. I noticed after I had done this code that you don't have that plugin installed but I wasn't going to go back and redo it. I think it's well worth installing for this and other features.
  • You'll notice I use FilterPlugin to iterate over possible multiple definitions and only expand if multiple definitions exists.
  • Probably the trickiest part of this code is the macro expansion order. This is the part that might take a little trial-and-error to get right.
  • I ran out of steam/time with the definition section. Once you understand what I did, it should be pretty straight forward applying this to the rest of the page layout.

I hope this helps! Feel free to ask additional questions.
%STARTINCLUDE%
%SET{"verbsuffixClass" 
   value="wordtitleaffix"
}%%SET{"nounsuffixClass" 
   value="wordtitleaffix"
}%%SET{"nounClass" 
   value="wordtitlenoun"
}%%SET{"phraseClass" 
   value="wordtitleother"
}%%SET{"prefixClass" 
   value="wordtitleaffix"
}%%SET{"verbClass" 
   value="wordtitleverb"
}%%SET{"adverbialClass" 
   value="wordtitleother"
}%%SET{"conjunctionClass" 
   value="wordtitleother"
}%%SET{"exclamationClass" 
   value="wordtitleother"
}%%SET{"numberClass" 
   value="wordtitleother"
}%%SET{"pronounClass" 
   value="wordtitleother"
}%%SET{"questionClass" 
   value="wordtitleother"
}%%SET{"undefinedClass" 
   value="wordtitleother"
}%%SET{"empty_format" 
   value="<nop>"
}%%SET{"verbsuffix_format"
   value="[[En.Type$expand(suffixtype$dollarindex)"}%VerbSuffixes][Type $expand(suffixtype$dollarindex) verb suffix]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;4.2.$expand(suffixtype$dollarindex)."
}%%SET{"nounsuffix_format"
   value="[[En.Type$expand(suffixtype$dollarindex)"}%NounSuffixes][Type $expand(suffixtype$dollarindex) noun suffix]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;3.3.$expand(suffixtype$dollarindex)."
}%%SET{"adverbialsuffix_format"
   value="[[En.Adverbial][adverbial]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;5.4"
}%%SET{"conjunction_format"
   value="[[En.Conjunction][conjunction]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;5.3."
}%%SET{"exclamation_format"
   value="[[En.Exclamations][exclamation]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;5.5."
}%%SET{"phrase_format"
   value="mixed phrase / idiom"
}%%SET{"noun_format"
   value="[[En.noun][noun]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;3."
}%%SET{"number_format"
   value="[[En.Numbers][number]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;5.2."
}%%SET{"prefix_format"
   value="[[En.Prefix][pronominal prefix]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;4.1."
}%%SET{"pronoun_format"
   value="[[En.Pronoun][pronoun]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;5.1."
}%%SET{"question_format"
   value="[[En.Question][question]], [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;6.4
}%%SET{"verb_format"
   value="[[En.Verb][verb]]$dollarpercntIF{\"'$expand(transitivity$dollarindex)'='adjective'\" 
                then=\" used as [[En.Adjective][adjective]]\"
            }$percnt, [[En.TheKlingonDictionary][TKD]]&nbsp;chapter&nbsp;4$dollarpercntIF{\"'$expand(transitivity$dollarindex)'='adjective'\" 
                then=\".4\'
            }$percnt."
}%%SET{"undefined_format"
   value="<font color=$quot#f00$quot>NOT DEFINED. PLEASE EDIT. ([[Categoryundefined][See list of undefined]])</font>"
}%%SET{"slang_format"
   value=", [[En.Slang][slang]] usage, [[En.KlingonForTheGalacticTraveler][KGT]],&nbsp;chapter&nbsp;5.2."
}%%SET{"regional_format"
   value="<br>This is a <i>regionally</i> used term. See [[En.KlingonForTheGalacticTraveler][KGT]]&nbsp;p.&nbsp;15 about [[En.Dialects][regional variation]]."
}%%SET{"adjective_format"
   value="Quality verbs are [[En.Transitivity][intransitive]] by nature."
}%%SET{"sure-yes_format"
   value="[[En.Transitivity][transitive]] verb: <b>[[Vay-][vay']] [[VI][vI]][[%BASETOPIC%][$expand(Klingon)]].</b> = I $expand(canondefinition$dollarindex) something."
}%%SET{"sure-no_format"
   value="[[En.Transitivity][intransitive]] verb: <b>[[%BASETOPIC%][$expand(Klingon)]] [[Vay-][vay']].</b> = Somebody/something $expand(canondefinition$dollarindex)s."
}%%SET{"maybe-yes_format"
   value="Probably [[En.Transitivity][transitive]] (not confirmed)"
}%%SET{"maybe-no_format"
   value="Probably [[En.Transitivity][intransitive]] (not confirmed)"
}%%SET{"general_format"
   value="plural:&nbsp;<b>$expand(Klingon)mey</b>"
}%%SET{"body_format"
   value="plural:&nbsp;<b>$expand(Klingon)Du'</b> ([[En.BodyParts][body parts]])"
}%%SET{"no_format"
   value="plural:&nbsp;This word is probably not countable."
}%%SET{"mass_format"
   value="This is a mass noun, so it has no plural."
}%%SET{"name_format"
   value="This word is a name so does not have a plural form."
}%%SET{"language_format"
   value="This is the singular form of an [[En.InherentPlural][inherently plural]] noun."
}%%SET{"inherent-singular_format"
   value="plural:&nbsp;<b>$expand(Klingon)pu'</b> (beings [[En.CapableOfLanguage][capable of language]])"
}%%SET{"inherent-plural_format"
   value="This is an [[En.InherentPlural][inherently plural]] form."
}%%SET{"part_format"
   value="<br>This $dollarexpand(wordtype1) is made of the parts <b>[[$dollarexpand(part1)]]</b>$dollarexpand('&nbsp;and <b>[[' + part2 + ']]</b>')$dollarexpand('&nbsp;and <b>[[' + part3 + ']]</b>')"
}%\
<div id="wordheader"><div id="klingontitle">
<span class="audiobutton" onclick="wabreH()"><audio id="QIchwab" src="%PUBURL%/Main/PronunciationFiles/%BASETOPIC%.mp3" type="audio/mp3">
Your browser does not support HTML5 audio.</audio>S</span>
<script> 
var wab = document.getElementById("QIchwab"); 
function wabreH() {wab.play();} 
</script>%FORMFIELD{"Klingon"}%</div>
%DBQUERY{topic="%SOURCE%"
   format="<div id='dckl-phonetic'>[&nbsp;<span class='klingon-ipa'>$expand(pIqaD or IPA)</span>&nbsp;] / "
         +"<span class='klingon-phonetic'>$expand(IPA or pIqaD)</span>&nbsp;]</div>)"
         +"<div class='dckl-piqad'><span class='dckl-piqad-label'>Klingon letters:<br></span>"
         +"<span class='dckl-piqad-letters'>$epand(pIqaD)</span></div>"
         +"<div class='dckl-piqad'><span class='dckl-piqad-label'>Handwritten:<br></span>"
         +"<span class='dckl-piqad-hand'>$expand(pIqaD)</span></div></div><br>"
         +"$percentFORMATLIST{\"%FORMATLIST{"1, 2, 3, 4" format="$expand(canondefinition$1)" separator=", "}%\" "
               +"split=\", \" "
               +"hideempty=\"on\" "
               +"separator=\"$n $n\" "
               +"format=\"$dollarpercntIF{\\"$dollarcount > 1\\" then=\\"$dollarindex.&nbsp;\\"}$dollarpercnt\""
                  +"$1&nbsp;$expand('(' + slang$dollarindex +')') "
                  +"$dollarn$dollarn<dd>$dollarpercnt$expand(wordtype$dollarindex)_format$dollarpercnt"
                  +"$dollarpercnt$expand(slang$dollarindex or 'empty')_format$dollarpercnt"
                  +"$dollarpercntIF{\\"'$expand(wordtype$dollarindex)'='verb'\\" "
                     +"then=\\"</dd>$dollarn<dd> $dollardollarpercnt$expand(transitivity$dollarindex)_format$dollardollarpercnt\\" "
                  +"}$dollarpercnt "
                  +"$dollarpercntIF{\\"'$expand(wordtype$dollarindex)'='noun'\\" "
                     +"then=\\"$dollarn$dollardollarpercnt$expand(plural$dollarindex)_format$dollardollarpercnt\\" "
                  +"}$dollarpercnt "
                  +"$dollarpercntIF{\\"'$dollarindex'='1' and $expand(part$dollarindex)'!=''\\" "
                     +"then=\\"$dollardollarpercntpart_format$dollardollarpercnt\\" "
                  +"}$dollarpercnt "
         +"}$percnt"
}%
%STOPINCLUDE%

-- LynnwoodBrown - 28 Aug 2021

Lynnwood said: I'd propose taking the rendering to the topic content out of the view template and simply use an INCLUDE in the template to reference the topic that does most of the rendering. This releases you from the syntactic restrictions of view templates and opens up use of other plugins.

Lynnwood, there are no syntactic restrictions when putting this code into a proper view template, none which I know of. Using explicitly having to put an %INCLUDE in each of the topics is actually an anti-pattern as it

  • (a) creates redundancy and
  • (b) mixes programming code maintained by wiki app developers with real net content that wiki authors happen to see: these two aren't necessarily the same group of people.

View templates as well as edit templates are highly unterused in all of Foswiki. However they are key for large scale wiki applications where you strive to reducing redundancy created by %INCLUDEs and other repeating macros all over the site.

-- MichaelDaum - 30 Aug 2021

First, thanks a lot to Lynnwood. This looks very interesting,I'll hae a closer look at that later, as I need some time to understand. A note to Michael: Actually, I really use different DataForms for each kind of def. It seems like this is the best solution to start with; As the next step, I'll make Lynnwood's suggestions.

This is so great, thanks a lot.

-- Lieven - 30 Aug 2021

Had a short chat with MichaelDaum this morning and wanted to clarify a couple of things:
  • I was not suggesting putting an INCLUDE in each topic. Rather I was suggesting putting a single INCLUDE in the view template that pointed to a separate topic which contain all the above code.
  • Michael pointed out that all the code I offered probably could just be in the view template. I like keeping my view templates as simple as possible, but that's probably reflects my limited understanding of them. I've had trouble getting template macros and other macros to expand properly together.
  • The main benefit of the code I was offering is to eliminate the need for multiple view templates with largely duplicated code.

-- LynnwoodBrown - 30 Aug 2021

Looking back at your site Lieven, I'm curious about something. Do you actually have different data forms you're using depending on how many definitions a word has? If so, the above code would eliminate that. You'd only need a single data form that can accommodate up to 4 definitions (equivalent I think to your Word_4_DefinitionsForm). Only those definitions with values would get rendered.

-- LynnwoodBrown - 30 Aug 2021

I picked up on Michael's comments about expansion of macros in templates and I do see another approach to the view template that addresses your initial question. I offer this here mostly for benefit of others who find this topic and are working with view templates. There are other aspects of your specific application that my above code addresses - in particular needing different formatting based on a fields value. But I'd like to offer the following sample VIEW_TEMPLATE code that would include a separate template for each time a repeating field has a value (isn't empty). For example, in the context of your example application, it would test if canondefinition1 thru canondefinition4 fields have values and if so, call a second template to render each one while passing along the field number.

Keep in mind, this is a very striped down example only to demonstrate the methods. I only included a couple of the numbered fields and this doesn't address your requirement to use different formatting of some fields based on the value of other fields.

%TMPL:DEF{"content"}% 
%FORMATLIST{"1, 2, 3, 4"
    format="$percntIF{\"%WEB%/%TOPIC%'/canondefinition$1 != ''\" then=\"$dollarpercntTMPL:P{\\"definition\\" NUMBER=\\"$1\\"}$dollarpercnt\"}$percnt"
    separator=""
}%
%TMPL:END%
%TMPL:DEF{"definition"}% 
%RENDERFORDISPLAY{"%WEB%.%TOPIC%"
   fields="canondefinition%NUMBER%, slang%NUMBER%, source%NUMBER%"
}%
%TMPL:END%

-- LynnwoodBrown - 30 Aug 2021
 

QuestionForm edit

Subject Topic Markup Language and applications
Extension
Version Foswiki 1.1.9
Status Answered
Related Topics
Topic revision: r8 - 30 Aug 2021, LynnwoodBrown
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy