Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2009-01-02 00:42:55

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

FAQ index example using variable, if_variable, if_different...

edit: final and commented version is here

I was trying to generate an index (by category) for a FAQ list. Each FAQ is an article assigned to a category. (First steps were based on this article on Textbook)
The desired output:

Category1 title

  • faq A
  • faq B
  • faq C

Category1 title

  • faq D
  • faq E

Category1 title

  • faq F
  • faq G
  • faq H
  • faq I

———

I was having a hard time trying to generate clean and valid XHTML because in the many attempts I tried, there were always an unclosed tag, or something duplicated.
Finally, I arrived to this dirty example:

<txp:if_first_article>
  <h3>
    <txp:category1 title="1" />
    <txp:variable name="first_cat" value='<txp:category1 />' />
  </h3>
  <ul>
<txp:else />
  <txp:if_variable name="first_cat" value='<txp:category1 />'>
  <txp:else />
    <txp:if_different>
      </ul>
      <h3>
      <txp:category1 title="1" />
      </h3>
      <ul>
    </txp:if_different>
  </txp:if_variable>
</txp:if_first_article>

<li>
  <a href="#faq_<txp:article_id />">
  <txp:title />
  </a>
</li>

<txp:if_last_article>
</ul>
</txp:if_last_article>

In plain english: if this is the first article, output this chunk (without the ul closing tag) and also create a variable “first_cat” and assign current (first) article’s category1 to it.
Else (if not first article), check if current article’s category1 is equal to the value of “first_cat” variable. If so, then do nothing.
Else (if not equal), check if the category1 is different to the last time this form was rendered. If so (if it different), render the code inside.
Then, there is some code that will be rendered for each article (<li>...</li>).
Finally, when rendering the last article, close the ul.

Looks a little dirty, and may not be bullet proof. But it worked :D
TXP FTW!

Last edited by maniqui (2009-01-17 14:39:04)


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#2 2009-01-02 00:56:06

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: FAQ index example using variable, if_variable, if_different...

BTW, for this to work, you have to use something like this:

<txp:article form="faq_index" limit="999" sort="Category1, Posted" />

The important part is: sort=“Category1, Posted”


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#3 2009-01-02 02:21:55

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: FAQ index example using variable, if_variable, if_different...

Also, to avoid the need to create a miscellaneous category, or to avoid a not-so-cool output if client forgets to assign a category1 to a FAQ, this is a refined version:

<txp:if_article_category number="1">
  <txp:if_first_article>
    <h3>
      <txp:category1 title="1" />
    </h3>
    <txp:variable name="first_cat" value='<txp:category1 />' />
    <ul>
  <txp:else />
    <txp:if_variable name="first_cat" value='<txp:category1 />'>
    <txp:else />
      <txp:if_different>
        </ul>
        <h3>
        <txp:category1 title="1" />
        </h3>
        <ul>
      </txp:if_different>
    </txp:if_variable>
  </txp:if_first_article>
<txp:else />
  <txp:if_different>
    </ul>
    <h3>
      Miscellaneous
    </h3>
    <ul>
  </txp:if_different>
</txp:if_article_category>


<li>
  <a href="#faq_<txp:article_id />">
  <txp:title />
  </a>
</li>

<txp:if_last_article>
</ul>
</txp:if_last_article>

The trick is the if_article_category number="1", that basically tests if the article has a category1 assigned to it. Thanks to Gocom for the tip.

edit: I’ve fixed/added a wrapping if_different to the “Miscellaneous” (no category assigned) chunk to avoid repeating the “Miscellaneous” title on every unassigned FAQ

Last edited by maniqui (2009-01-02 02:45:56)


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#4 2009-01-02 03:03:25

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: FAQ index example using variable, if_variable, if_different...

Final version, using definition lists and including the article body.
Take your time to read the comments and the code. It may be a little hard to follow, but it works!

<!-- 
  First, I'm using txp:article as a container tag, 
  and sorting the list of articles by category1.
  Sorting by category1 is important because 
  then we're going to use txp:if_different to 
  create headings for each category.
-->
<txp:article limit="999" sort="Category1 desc, Posted asc">
        <!-- if current article being "parsed" has a category1 associated with it... -->
        <txp:if_article_category number="1">
          <!-- and if current article is the first article of the list... ->
          <txp:if_first_article>
            <!-- 
              then create a heading using its category1 as content.

              This "first article" case is important, because on following category headings, 
              we will also need to include a </dl> (closing) tag before the heading.
              But we don't want that closing tags before the very first heading.
            -->
            <h3>
              <txp:category1 title="1" />
            </h3>
            <!-- 
              and also, create a variable to store which is the very first category being output 
              (in other words, "remember" the category1 assigned to the first article on the list).

              Once it is assigned, the value of this variable will never change, 
              because it's only assigned if the first article is being "rendered".
             -->
            <txp:variable name="first_cat" value='<txp:category1 />' />
            <dl>
          <txp:else /><!-- if not the first article -->
            <!--
              if the previously created variable matches the category1 of current article
             (an article which may be the first article, or any other article which belongs 
              to the same category as the first article), then *do nothing!*.

              This trick using a variable was necessary to avoid a duplicated 
              output of the heading for the first category being output.
              Why? Because the if_different trick coming after (on the "false" branch of this if_variable)
              would output 
              It sounds complicated, but it works flawlessly :)
            -->
            <txp:if_variable name="first_cat" value='<txp:category1 />'>
              <!-- yeah, nothing happens here... go on! -->
            <txp:else />
              <!-- 
                if the enclosed txp:category1 tag outputs something different to previously iteration output...
                it means that we are now rendering an article (or a range of articles) which belongs to a different category...

                So... we want to close the definition list (</dl>) and create a new heading for this new category being output.
              -->
              <txp:if_different>
                </dl>
                <h3>
                <txp:category1 title="1" />
                </h3>
                <dl>
              </txp:if_different>
            </txp:if_variable>
          </txp:if_first_article>
        <txp:else /><!-- if current article doesn't have any category1 assigned to it, so it's a FAQ that doesn't belong to any particular category, then... -->

          <!-- 
            use this a cool and nasty if_different trick! 

             In this trick, we are "abusing" the if_different magic.
             Inner content will never be different because it's static content, just html + text, no txp dynamic values inside.

             BTW, it's important to understand this: each if_different is "independent" 
             and will output its content the very first time it's "parsed". 
             So, it will only output its content if it's different from the last time it output some content.  
          -->
          <txp:if_different>
            </dl>
            <h3>
            Miscellaneous
            </h3>
            <dl>
          </txp:if_different>
        </txp:if_article_category>

          <!-- 
            here it comes another important part of this snippet:
            this is the only chunk that will be output on every FAQ, really!
            Look at it! It's not wrapped by any conditional!
            It's a first child of the wrapping txp:article at the beginning of the snippet!
          -->
          <dt>
            <a href="<txp:permlink />">
            <txp:title />
            </a>
          </dt>
          <dd><txp:body /></dd>

         <!-- Finally, is this the last article on the list? Then, close the definition list, because this is the end of the road -->

        <txp:if_last_article>
        </dl>
        </txp:if_last_article>
</txp:article>

Finally, combine it with this jQuery trick and enjoy a neat FAQ.

Edit by gaekwad: fixed broken link, thanks Jason D.

Last edited by gaekwad (2020-05-15 07:17:15)


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

Board footer

Powered by FluxBB