Textpattern CMS support forum

You are not logged in. Register | Login | Help

#301 2017-06-22 20:01:45

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 963
Website

Re: etc_query: all things Textpattern

Hi, @etc!

This appeared to work at first, but I ran into another snag.

Calling etc_query with markup="xml" breaks the search-and-replace thing I’m doing.

As explained here, I need to parse my content for span elements with the class ‘fnt’, replace those elements in the content with footnote markers, and add their content to an endnotes variable placed later in the document.

When I call that tag without a markup attribute, etc_query reads it as HTML (I guess). It finds all my //span[@class=‘fnt’] elements, replaces them with footnote markers, populates the endnotes variable, and outputs all the content with the target pattern replaced with the appropriate replacement—but it removes the / from self-closing XHTML elements.

<txp:etc_query
  data='<div><txp:yield /></div>'
  globals="variable"
  query="//span[@class='fnt']"
  replace='&=<sup><a href="#endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>" id="marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>">{$+({?endnote_no}|{#row})}</a></sup>'
  specials="replace,content"
  >

  <txp:variable name="endnotes">

    <txp:variable name="endnotes"/>

    <li id='endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>{text()} <a href='#marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>^</a></li>

  </txp:variable>

  {$=({#row}|{#rows}).?({//body/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}

</txp:etc_query>

But when I add markup="xml" to the tag, the output is drastically different. It still finds all my //span[@class=‘fnt’] elements, and it still populates my endnotes variable. But instead of returning my content with the target pattern replaced with replacements, it displays nothing.

<txp:etc_query
  data='<div><txp:yield /></div>'
  globals="variable"
  markup="xml"
  query="//span[@class='fnt']"
  replace='&=<sup><a href="#endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>" id="marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>">{$+({?endnote_no}|{#row})}</a></sup>'
  specials="replace,content"
  >

  <txp:variable name="endnotes">

    <txp:variable name="endnotes"/>

    <li id='endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>{text()} <a href='#marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>'>^</a></li>

  </txp:variable>

  {$=({#row}|{#rows}).?({//body/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}

</txp:etc_query>

Is there a way to get it to do the search-and-replace I want, and display the content with replacements, without turning my self-closing XHTML tags into unclosed HTML tags?

Thank you in advance for any guidance you can offer!

Last edited by johnstephens (2017-06-22 20:03:12)

Offline

#302 2017-06-22 21:03:14

etc
Developer
Registered: 2010-11-11
Posts: 2,182
Website

Re: etc_query: all things Textpattern

Hi John,

I think that’s because there is no <body /> in XML-imported document (in HTML it is created automatically). Try to replace {//body/node()} with {div/node()} or simply {div} or {/}, some of them should work.

Hope it helps.

Edit: btw, if you call etc_query with debug="h" attribute, it will display the data as it sees it.


etc_[ query | search | pagination | date | tree | cache ]

Offline

#303 2017-06-22 21:23:13

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 963
Website

Re: etc_query: all things Textpattern

I can’t thank you enough, @etc! At first brush, {div/node()} appears to work. I have to hit it with a battery of tests before declaring victory, though. I’ll keep the debug attribute in mind!

Offline

#304 2017-07-14 21:22:48

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 963
Website

Re: etc_query: all things Textpattern

Dear @etc,

It seems I’m determined to find out everything that can possibly go wrong when parsing XHTML with etc_query.

Here is the tag:

<txp:etc_query
    data='<div><txp:yield /></div>'
    globals="variable"
    markup="xml"
    query="//span[@class='fnt']"
    replace='&=<sup><a href="#endnote_{$+({?endnote_no}|{#row})}x<txp:article_id/>" id="marker_{$+({?endnote_no}|{#row})}x<txp:article_id/>">{$+({?endnote_no}|{#row})}</a></sup>'
    specials="replace,content"
    >
    {$=({#row}|{#rows}).?({//div/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}
</txp:etc_query>

Here is the content before it is consumed by etc_query:

<p>Lorem ipsum</p>

<div class="figure right col_25">
<img id="figure1" src="http://example.com/images/559.jpg" alt="" />
<p class="figcaption2"><strong>Figure 1</strong>. An image, of some kind</p>
</div>


<p>Dolor sit amet</p>

And this is what etc_query returns:

<p>Lorem ipsum</p><div class="figure right col_25"><img id="figure1" src="http://example.com/images/559.jpg" alt=""/><p class="figcaption2"><strong>Figure 1</strong>. An image, of some kind</p></div><img id="figure1" src="http://example.com/images/559.jpg" alt=""/><p class="figcaption2"><strong>Figure 1</strong>. An image, of some kind</p><p>Dolor sit amet</p>

For some reason, etc_query appears to be duplicating the image caption paragraph, and appending the duplicate markup directly after the containing div. The affected markup does not contain either the query pattern or the replacement pattern, and I can’t tell what’s going on.

Do you have any suggestions how I might identify the root of the problem?

Thank you!

Last edited by johnstephens (2017-07-14 21:28:03)

Offline

#305 2017-07-14 21:34:00

etc
Developer
Registered: 2010-11-11
Posts: 2,182
Website

Re: etc_query: all things Textpattern

Hi John, no worries. Do you happen to call //div/node() yes, I think that was it. This matches all div tags, you should replace it with /div/node() (or simply div/node()?) to match only the root div. Tell me if it helps?


etc_[ query | search | pagination | date | tree | cache ]

Offline

#306 2017-07-14 21:52:35

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 963
Website

Re: etc_query: all things Textpattern

Since I accidentally solved it, I wanted to post the solution here for posterity—or at least for myself if I ever face a similar problem:

It seems like //div/node() was duplicating every single div in the data, not just the wrapping div:

{$=({#row}|{#rows}).?({//div/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}

Replacing that with /div/node() seems to resolve the issue:

{$=({#row}|{#rows}).?({/div/node()}<txp:variable name="endnote_no" value="{$+({?endnote_no}|{#row})}" />)}

Offline

#307 2017-07-14 21:53:15

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 963
Website

Re: etc_query: all things Textpattern

etc wrote #306277:

Hi John, no worries. Do you happen to call //div/node() yes, I think that was it. This matches all div tags, you should replace it with /div/node() (or simply div/node()?) to match only the root div. Tell me if it helps?

Ha, yes! It looks like I stumbled over this while you were writing. Thank you!

Offline

#308 2017-07-14 21:54:13

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 963
Website

Re: etc_query: all things Textpattern

P.S. I did try div/node(), and that returned nothing—neither the root div nor any nesting divs. But /div/node() worked.

Offline

Board footer

Powered by FluxBB