Textpattern CMS support forum
You are not logged in. Register | Login | Help
- Topics: Active | Unanswered
#157 2013-01-16 22:25:54
Re: etc_query: all things Textpattern
Version 1.2.3: added context attribute, to be able to send cookies and other headers when retrieving data from url.
Few internal processing tweaks now turn etc_query
into a handy txp:if
tag:
<txp:etc_query query="'{?posted}'='{?modified}' and {?comments_count}=0">
This boring article has never been modified nor commented.
<txp:else />
This is an interesting article.
</txp:etc_query>
Online
#158 2013-01-21 15:32:08
Re: etc_query: all things Textpattern
I’ve done some advanced stuff with this a few months ago.
On Saturday night, I wanted to do something really simple but for some reason, my mind was totally blocked. I read the plugin help and also did some RTFM on Xpath, but I was so blocked that I didn’t even try anything. Just abandoned the task and find a simple way to solve the task by using some built-in tags.
But of course, the failure sensation remained, so I’m here to ask how to solve it :)
Given this simple HTML:
<div>
<a href="/link1">
<span>Some text</span>
</a>
</div>
<div>
<a href="/link2">
<span>Some text</span>
</a>
</div>
<div>
<a href="/link3">
<span>Some text</span>
</a>
</div>
How do I simple remove the wrapping link while keeping the span and its content? Or, in other words, how do I get, from previous input, the following output?
<div>
<span>Some text</span>
</div>
<div>
<span>Some text</span>
</div>
<div>
<span>Some text</span>
</div>
Offline
#159 2013-01-21 15:40:00
Re: etc_query: all things Textpattern
You mean, the following didn’t work?
<txp:etc_query data="your stuff but mind the quotes" replace="div/a&={node()}" />
Edit: or even replace="div={a/node()}"
Last edited by etc (2013-01-21 15:41:55)
Online
#160 2013-01-21 21:13:43
Re: etc_query: all things Textpattern
Hi Oleg.
Thanks for the prompt reply.
It’s not that anything I tried didn’t work. It’s that I couldn’t even come up with something to try.
I can confirm that your 2 suggestions would have worked.
Offline
#161 2013-01-21 21:48:26
Online
#162 2013-01-23 15:28:29
Online
#163 2013-01-24 12:15:53
Re: etc_query: all things Textpattern
Hi Oleg. Great improvements.
I’ve some quick & dirty feedback.
—
On XPath patterns section.
The tags
{?}
and{#}
represent the context node’s value and name respectively.
Could you put an example on the usage of these two?
Also, what is {?}
on a non-XPath context?
For example, on the JSON range example, you put on the contained statement:
{{$*{?}}}
Care to explain each “level” (there are 3 levels) of nested {}
?
—
On Variable patterns section:
function_pattern
concept is not totally clear, imo. Is it just for casting vars? Is it a PHP concept?
—
On JSON ranges section
You call ranges as “JSON ranges”.
I googled it but couldn’t find any reference to “JSON ranges”. Are these ranges somehow related to JSON at all? (If not, I’d suggest dropping the “JSON” part and use something like markup="range"
).
—
On Replace section
I know that I should do better than “just complain” but I think this section is a bit messy. I think some organization with headings and more explained examples could help.
On this example:
For example,
replace="//script|//
*[starts-with(name(),‘on’)]”@
The pipe (|
): is it part of the xpath expression or is something provided for etc_query? (ie. a separator of some kind)
The value will be parsed into XML tree, unless xpath is followed by ?
I know that if you append the ?
is that the xpath value gets escaped (ie. it’s printed literally). But it’s not clear on that sentence.
The tokens xpath~=xpath and xpath/=xpath will move the left-hand node, inserting it before the right-hand one, or appending as its child respectively. For example, //a1/=.. will move every first link to the end of its parent node.
An example of before/after markup could be really helpful to understand this functionality.
A token xpath@@attr1=val1@attr2=val2… will set the attributes attr1,attr2,… of matched elements to the respective values. You can use the shortcuts ., ?, +, ^, $, &, ~ and / as attributes too.
Not clear what these shortcuts are or do. Are they pure XPath? Or some etc_query markup?
—
General questions:
What happens with the scope on nested etc_query
? Are outer vars stepped over by inner vars?
{#row}
and {#rows}
. Is it a concept that apply to anything in etc_query (like any loop iteration) or is it valid only on DB queries?
I answer this one myself: it seems {#row}
and {#rows}
applies to any iteration over data, not only DB queries.
—
Oleg, I understand that the plugin help shouldn’t be an complete XPath reference, but I think it’s also assuming a level of understanding of many XPath concepts that are hard to grasp.
I’d suggest to adding a minimal XPath reference and/or links to resources.
Here are some I found useful and that I think etc_query users will benefit from having them at the end of plugin’s help. Of course, if you know of any other good resource that I’ve missed, I’d suggest to add it.
XPath tutorial at zvon.org
zvon.org/comp/r/tut-XPath_1.html
XPath reference at zvon.org
zvon.org/comp/r/ref-XPath_1.html
XPath test lab at zvon.org
zvon.org/comp/tests/r/test-xlab.html
XPath tutorial at tizag.gom
www.tizag.com/xmlTutorial/xpathtutorial.php
Offline
#164 2013-01-24 13:16:37
Re: etc_query: all things Textpattern
Huge thanks for your help, Julián, I start to answer some questions here, and will modify the help a little later if you find the answers satisfactory.
On *Variable patterns* section:
@function_pattern@ concept is not totally clear, imo. Is it just for casting vars? Is it a PHP concept?
No, it’s a pure etc_query
invention, somewhat inspired by jQuery syntax. The general structure is func1(arg1|arg2|...).func2(...)...
, where func1
etc are php functions, and arg1
etc are their arguments (without quotes), separated by argsep (|
by default). They are executed in the ltr order, and the output of func1
can be passed as argument to func2
using $
sign. For example, strtoupper( Hello, word! ).trim($)
(or shorter strtoupper( Hello, word! ).trim
) is parsed as trim(strtoupper('Hello, word!'))
.
Function patterns are recognized in two ways:
- included in
{$...}
token, e.g.<txp:etc_query>{$strtoupper( Hello, word! ).trim}</txp:etc_query>
will outputHELLO, WORD!
. - in
{?variable|default|function}
token. For example,{?body||strip_tags($|<p>).trim}
in article context will produce article’s trimmedBody_html
with all butp
tags stripped out. Note that the pipe|
symbols is used for two different purposes here, but I lack imagination. :)
These tokens can be used in every etc_query
attribute that is in specials list, as well as in replace and inside the container.
On JSON ranges section
You call ranges as “JSON ranges”.
I googled it but couldn’t find any reference to “JSON ranges”. Are these ranges somehow related to JSON at all? (If not, I’d suggest dropping the “JSON” part and use something likemarkup="range"
).
Another etc_query
invention, they shouldn’t be called JSON, you are right. I don’t think markup="range"
is necessary, since they have no other use and are recognized as such anyway unless you explicitly set @markup=“raw”@ some markup.
To be continued…
Last edited by etc (2013-01-24 13:18:51)
Online
#165 2013-01-24 14:15:38
Re: etc_query: all things Textpattern
On XPath patterns section.
The tags
{?}
and{#}
represent the context node’s value and name respectively.Could you put an example on the usage of these two?
{#row}
and{#rows}
. Is it a concept that apply to anything in etc_query (like any loop iteration) or is it valid only on DB queries?I answer this one myself: it seems
{#row}
and{#rows}
applies to any iteration over data, not only DB queries.Also, what is
{?}
on a non-XPath context?
Typically, etc_query
retrieves from data the node list specified by query. For example,
<txp:etc_query data="<p><span>one</span> and <b>two</b> and <span>three</span></p>" query="//span" />
will (internally) result in two-nodes list: <span>one</span>
and <span>two</span>
. As said, {?}
and {#}
represent the current node’s value and name. Now, when etc_query
iterates through this list to produce its output
<txp:etc_query data="<p><span>one</span> and <b>two</b> and <span>three</span></p>" query="//span" wraptag="ul" break="li">
{#} {?} : {#row} of {#rows}
</txp:etc:query>
we get
- span one : 1 of 2
- span three : 2 of 2
It’s exactly what happens in non XML context too, we are just iterating through some array or object:
<txp:etc_query data='["one", "two", "three"]' break=", ">
{#row} : {?}
</txp:etc_query>
gives 1 : one, 2 : two, 3 : three
.
This is a little different in attribute context. For example,
<txp:etc_query data="<p class='par'>blah</p>" query="p" replace="@@class=new {?}" />
will output <p class='new par'>blah</p>
, and not <p class='new blah'>blah</p>
.
For example, on the JSON range example, you put on the contained statement: {{$*{?}}}
Care to explain each “level” (there are 3 levels) of nested
{}
?General questions:
What happens with the scope on nested
etc_query
? Are outer vars stepped over by inner vars?
Roughly, each etc_query
call removes one {}
pair, still processing its interior. So, what happens in
<txp:etc_query data="[1..9]" break="tr" wraptag="table">
<txp:etc_query data="[1..9]" break="td">
{{$*{?}}}
</txp:etc_query>
</txp:etc_query>
The outer etc_query
iterates through [1..9]
, producing (internally) the following array:
<txp:etc_query data="[1..9]" break="td">{$*1}</txp:etc_query>
<txp:etc_query data="[1..9]" break="td">{$*2}</txp:etc_query>
...
<txp:etc_query data="[1..9]" break="td">{$*9}</txp:etc_query>
Now each inner etc_query
iterates through [1..9]
, multiplying each value by n
given in {$*n}
function pattern and wrapping the result in td
:
<td>1*1</td><td>2*1</td>...<td>9*1</td>
<td>1*2</td><td>2*2</td>...<td>9*2</td>
...
<td>1*9</td><td>2*9</td>...<td>9*9</td>
The products are evaluated, I leave them here just for clarity. Finally, each row is wrapped in tr
and then table
by the outer etc_query
.
Last edited by etc (2013-01-24 14:17:15)
Online
#166 2013-01-25 16:14:46
Re: etc_query: all things Textpattern
maniqui wrote:
I’d suggest to adding a minimal XPath reference and/or links to resources.
I’ve made a quick etc_query
XPath sandbox, and will add your links to the help. Thanks!
Online
#167 2013-01-27 23:03:46
- progre55
- Member
- Registered: 2006-05-02
- Posts: 668
Re: etc_query: all things Textpattern
etc:
Hello and hope all is well. I am in the process of trying to use etc_query to paginate article_custom — but I have run into a bit of a stumbling block. I can get the navigation to show but it does not work. My article_custom looks like this:
<txp:article_custom form="landingPage" sort="Posted desc" category="news" limit="2" />
I think my first issue is that from your instructions it is looking at all active articles — my second issue is that even though it shows the navigation — when clicked you get a 404 error because it is not maintaining the same page url — in this case it is www.xyzsite.com/news —- on yours it appears to tack on a page2 and in some cases a #
Any assistance/guidance would be greatly appreciated.
progre55
Offline
#168 2013-01-28 09:01:07
Re: etc_query: all things Textpattern
Hello
progre55 wrote:
I think my first issue is that from your instructions it is looking at all active articles
Yes, you have to modify it like
<txp:etc_query name="numPages"
data="SELECT CEILING(count(*)/2) AS numPages FROM textpattern WHERE Status=4 AND (Category1='news' OR Category2='news')" />
and maybe even more if you have future or expired articles.
my second issue is that even though it shows the navigation — when clicked you get a 404 error because it is not maintaining the same page url — in this case it is www.xyzsite.com/news —- on yours it appears to tack on a page2 and in some cases a #
Sorry, I was not clear on this point, <txp:permlink />
will not work in list mode. If you need this pagination only on www.xyzsite.com/news
pages, put it like this
<txp:etc_query name="navbar" data="[1..{?numPages|1|intval}]">
<a href="www.xyzsite.com/news/?page={#row}">Page {#row}</a>
</txp:etc_query>
Hope it helps.
Online