This multipurpose Textpattern plugin can import and transform data from various sources: websites, xml or json feeds, databases, global variables and – most importantly – from chunks of html code, like the output of txp tags. It can also perform arithmetic or other calculations over imported data.
Contents
- Let us do some arithmetic.
- An alternative way
- So, what are these fancy {braces}?
- What is behind the scene?
- The typical job for etc_query.
- What else?
Let us do some arithmetic.
Our first example is a mere “two times two”: 2x2=<txp:etc_query query="2*2" />
will produce 2×2=4, pretty trivial, I know. But we can do it with other data, e.g. some url variable:
<txp:etc_query globals="_GET" query="2*{?factor|2|intval}" />
Now, if you append &factor=3
to the address bar string (feel free to test it), etc_query
will retrieve and sanitize its value by casting it to integer, then multiply it by 2: 2×2=4. If factor
is not set, it will be assigned a default value (2 here).
Any global variable (e.g. txp variable
or thisarticle
) can be retrieved in this manner, it suffices to modify the globals
list. By default, globals
seeks for variables in txp universe, like variable
, pretext
and so on. You can also assign the <txp:etc_query />
output to some <txp:variable />
by setting its name
attribute. For example, to advance the value of <txp:variable name="some_var" />
by 1, call
<txp:etc_query name="some_var" query="{?some_var}+1" />
An alternative way
The calculations can also be done using etc_query
as container:
<txp:etc_query globals="_GET" data="{?factor|2|intval}">
2x{?}={2*{?}}
</txp:etc_query>
or
<txp:etc_query globals="_GET" data="{?factor|2|intval}">
2x{?}={$*2}
</txp:etc_query>
both result in 2×2=4. The second form is internally different from the first one, and sometimes faster. Moreover, we can replace {$*2}
therein by any PHP function, such as {$sqrt}
: √2=1.4142135623731
So, what are these fancy {braces}?
They have special meaning inside etc_query
, depending on the first symbol. As you have probably guessed, {?var}
will retrieve the field var
from the globals
list of variables. We can optionally assign it a default value and pass it through some sanitizer functions, as above. A noticeable exception is {?}
, which represents the value of the context data.
A {$func}
pattern will call the PHP function func
or some internal etc_query
function, like in {$*2}
. Functions can be passed arguments and chained, if necessary.
There are other kinds of special patterns, but the most important ones are plain {expressions}
, like {2*2}
. They will be evaluated by PHP DOMXPath functions, which leads us behind the scene.
What is behind the scene?
The core of etc_query
is XPath language. It is used to evaluate query
and other attributes. If you are acquainted with CSS or jQuery DOM traversal, there will be no difficulty in learning XPath.
First of all, XPath understands basic arithmetic, as well as some (limited) collection of functions, like count(...)
, substring(...)
or starts-with(...)
. We can extend this collection with virtually any PHP function by setting functions
attribute of etc_query
:
<txp:etc_query functions="pow,sqrt" query="pow(sqrt(3),2)" /> = 3.0000000000001
But most importantly, XPath can be used for addressing parts of XML/HTML documents. The matched nodes can then be retrieved and transformed by etc_query
, and that’s what it was made for.
The typical job for etc_query.
Sometimes, you are not quite happy with the output of hard-coded Textpattern tags. For example, we could benefit from HTML5 placeholder
and required
attributes in, say, the name input of comment_form
. This can be done by replacing <txp:comment_name_input />
in comment_form
with
<txp:etc_query data='<txp:comment_name_input />'
query="input[@id='name']"
replace="@@required=required@placeholder=Required" />
which tells etc_query
to extract the input
tag with id='name'
from <txp:comment_name_input />
, and replace its attributes as desired. You can see (and comment) the result in the comment form below.
Another typical example is the table of contents at the beginning of this page, which is obtained with
<txp:etc_query data="{?body}" query="//h4"
break="li" wraptag="ol"
label="Contents" labeltag="h4" html_id="contents">
<a href="#{@id?}">{?}</a>
</txp:etc_query>
What else?
You can use etc_query
to query databases, like this:
<txp:etc_query data="SELECT * FROM txp_users" wraptag="ul" break="li">
{RealName?} was here on {last_access?}.
</txp:etc_query>
or to import RSS/XML/JSON feeds:
<txp:etc_query url="http://api.openweathermap.org/data/2.5/forecast/daily?q=Paris,fr&units=metric&cnt=5&appid=your_api_id"
markup="json" query="list/*">
<img src="http://openweathermap.org/img/w/{weather/0/icon?}.png" />
{temp/day?}°C
</txp:etc_query>
Weather in Paris, FR
2024-12-06
9.84°C2024-12-07
9.42°C2024-12-08
6.61°C2024-12-09
5.94°C2024-12-10
4.03°C
… or even parts of webpages (hope they don’t mind):
<txp:etc_query
url="https://xkcd.com/"
query="id('comic')/img">
<img{@src} loading="lazy" />
</txp:etc_query>
or iterate over arrays/ranges (can you guess what are the double braces for?):
<txp:etc_query data="[1..9:2]" break="tr" wraptag="table">
<txp:etc_query data="[1,2,3,5,7,9,11,13,17]" break="td">
{{$*{?}}}
</txp:etc_query>
</txp:etc_query>
1 | 2 | 3 | 5 | 7 | 9 | 11 | 13 | 17 |
3 | 6 | 9 | 15 | 21 | 27 | 33 | 39 | 51 |
5 | 10 | 15 | 25 | 35 | 45 | 55 | 65 | 85 |
7 | 14 | 21 | 35 | 49 | 63 | 77 | 91 | 119 |
9 | 18 | 27 | 45 | 63 | 81 | 99 | 117 | 153 |
or… but I feel that this article is getting too long. So, just download and install the plugin, read the included help, or get it on TXP Forum thread.
File(s)
- File: etc_query.txt [60.72 kB] (4256 downloads, ~29 per month)