Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#193 2013-09-26 17:34:22

mrdale
Member
From: Walla Walla
Registered: 2004-11-19
Posts: 2,215
Website

Re: etc_query: all things Textpattern

Awesome! Did the trick, now I need to do the following. gonna give it a shot myself, just posting here for reference.

The dataset

<div class="display_archive">
  <div class="campaign">09/19/2013 - <a href="#" title="Item 1" target="_blank">Item 1</a></div>
  <div class="campaign">09/12/2013 - <a href="#" title="Item 2" target="_blank">Item 2</a></div>
</div>

In theory (etc check my logic)

  1. match div.campaign /display_archive/campaign/
  2. extract the date from instances of the date /display_archive/campaign/text() into a variable
  3. remove the “ – “ in the variable
  4. use <txp:if_different> to insert an h4 for the month name when it is different from the preceding (converting 1-12 to month names)
  5. echo .campaign

Now for the Implementation

Offline

#194 2013-09-26 18:39:04

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: etc_query: all things Textpattern

For some weird good reason, <> get encoded when importing JSON to XML. This seems to work:

<txp:etc_query data="{?some_script||trim.preg_replace(/^document\.write\(|\);$/i,,$).json_decode}"
	argsep="," wraptag="div" class="display_archive" functions="strtotime,date"
	query="//div[@class='campaign']"
>
	<txp:if_different><h4>{date('m', strtotime(translate(text(), ' -', '')))}</h4></txp:if_different>
	{.}
</txp:etc_query>

Edit: added date functions.

Last edited by etc (2013-09-27 10:26:34)

Offline

#195 2013-09-26 21:21:57

mrdale
Member
From: Walla Walla
Registered: 2004-11-19
Posts: 2,215
Website

Re: etc_query: all things Textpattern

This is awesome! Thanks… trying very hard to grok this her’s my line by line.

<txp:etc_query data="{?some_script||trim.preg_replace(/^document\.write\(|\);$/i,,$).json_decode}"

{get data from the variable|no default value|transformation chain}

get the variable and apply a transformation chain to it and use that for data (through php functions?)

  1. trim: trims whitespace from start and end of the following
  2. preg_replace: matches the two parts of the unwanted text searching case-insensitive
  3. json_decode decodes the output into an array (why do I need this?)

argsep="," wraptag="div" class="display_archive" functions="strtotime,date" query="//div[@class='campaign']"

  1. argsep: separates the arguments of which part with a comma?
  2. wraptag: and class are txp behaviors
  3. functions: allow the following php functions to be used inside this tag
  4. query: limit the output of this tag to all divs who’s class is “campaign”

<txp:if_different><h4>{date('F', strtotime(translate(text(), ' -', '')))}</h4></txp:if_different>

  1. if_different: behaves as it should ony showing unique values for the inner text returned from the query (inner text of “div.campaign”)
  2. date: returns the date “Month Name” (F) of the enclosed string (make sure to use the code for date not strftime)
  3. strtotime: transforms the text “mm-dd-yyyy” to a timestamp for the enclosed string
  4. translate: this is an Xpath function to do a quick find and replace for unanted text on text()

{.}

Now just return all of the items that are output by the tag’s query from the dataset, rinse, repeat.

Last edited by mrdale (2013-09-27 15:30:09)

Offline

#196 2013-09-27 21:20:36

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: etc_query: all things Textpattern

Nice job, Mr. Dale! I’ve got only few comments to add:

<txp:etc_query data="{?some_script||trim.preg_replace(/^document\.write\(|\);$/i,,$).json_decode}"
get the variable and apply a transformation chain to it and use that for data (through php functions?)

Exactly! Actually, the variable could be transformed with pax_grep/rah_replace/rah_function or mere txp:php as well, and then passed as data to etc_query.

json_decode decodes the output into an array (why do I need this?)

You get not an array, but a plain string here, with \" and \/ unescaped. Same result can be achieved with str_replace, but the argument of document.write seems JSON-encoded, so json_decode should do the job fine.

argsep: separates the arguments of which part with a comma?

functions arguments, like in preg_replace(/^document\.write\(|\);$/i,,$). The default argsep is | (pipe), but here we need it in regexp pattern.

functions: allow the following php functions to be used inside this tag

Yes, XPath 1.0 used in PHP DOM has a very limited collection of functions (translate is one of them), but one can complete it with php (string) functions.

query: limit the output of this tag to all divs who’s class is “campaign”

It rather creates a list of nodes you want to use as landmarks, over which etc_query will iterate. The {xpath}’s inside etc_query will be relative to these landmarks ({.} is the node itself, {text()} is the text immediately inside it, and so on). This does not really limit the output, you can display the nodes parent with {..}, for example.

Offline

#197 2013-11-13 11:47:19

gfdesign
Member
From: Argentina
Registered: 2009-04-20
Posts: 401

Re: etc_query: all things Textpattern

Hi Oleg.

Thanks so much for your plugin and explanation about alphabetic list that you put in your site.
I’ve tried to use it in my site but for any reason I can’t. When I put the code, and click on any letter, the articles display but the alphabetic list doesn’t. What could be the problem?

Other questions is, how you would do it if you’d have to do an alphabetic list of professionals separated by professions such us architects, engineers, carpenters. I created a section called “professionals” and each profession has its own category. So, when I want to load a new professional, I create a new article and I assign to the corresponding category. But I wouldn’t know how to use your code for this request. Any idea?

Thanks again in advance.
Regards
Fernando

Offline

#198 2013-11-13 12:18:38

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: etc_query: all things Textpattern

Hi Fernando,

gfdesign wrote:

When I put the code, and click on any letter, the articles display but the alphabetic list doesn’t. What could be the problem?

That’s a bit strange, the only explanation I can see right now is that you use another wraptag instead of nav. If so, you should replace {//nav} with {//your_tag} inside the second etc_query. Otherwise, mind providing an url (if it’s online)?

Other questions is, how you would do it if you’d have to do an alphabetic list of professionals separated by professions such us architects, engineers, carpenters. I created a section called “professionals” and each profession has its own category. So, when I want to load a new professional, I create a new article and I assign to the corresponding category. But I wouldn’t know how to use your code for this request. Any idea?

Are you looking for

Architects: A - B - ... - Z
Engineers: A - C - ... - X

or

A: Architects - Engineers
B: Engineers

Both must be doable, let me think about it.
Regards

Offline

#199 2013-11-13 19:54:35

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: etc_query: all things Textpattern

Version 1.2.9: just fixes a stupid typo introduced in a recent cleanup. Apologies, and many thanks to Fernando for the report.

Offline

#200 2014-01-14 08:02:48

photonomad
Member
Registered: 2005-09-10
Posts: 290
Website

Re: etc_query: all things Textpattern

Might there be a way/shortcut to get etc_query to automatically store each node from items in a JSON document as a textpattern variables when using etc_query as a container tag? I have couple of date/timestamps that need formatting and other nodes that need to have the html escaped, etc. My programming knowledge is limited to where I can’t figure out how to wrap a {node?} in an smd_wrap tag or other plugin tags without first defining the nodes as txp:variables and this seems to slow the whole thing down a bit. Thanks in advance for any hints or tips!

Offline

#201 2014-01-14 08:36:38

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: etc_query: all things Textpattern

photonomad wrote #278126:

Might there be a way/shortcut to get etc_query to automatically store each node from items in a JSON document as a textpattern variables when using etc_query as a container tag?

No, mainly because nodes (e.g. {//a}) are generally lists, so storing them in txp variables (that are strings) is problematic.

I have couple of date/timestamps that need formatting and other nodes that need to have the html escaped, etc. My programming knowledge is limited to where I can’t figure out how to wrap a {node?} in an smd_wrap tag or other plugin tags without first defining the nodes as txp:variables and this seems to slow the whole thing down a bit.

You can do most of formatting with etc_query itself, using php or txp functions. For example, to transform a {timestamp?} into year, call {$strftime(%Y|{timestamp?})}, to escape it call {$txpspecialchars({timestamp?})}, and so on. If you need to inject {node?} as attribute of some <txp:tag />, that’s a mere <txp:tag attr="{node?}" />, or <txp:tag attr="{$txpspecialchars({node?})}" />.

If your treatment is really complex, you can (at least in theory) save the imported JSON object with save attribute of etc_query and reuse it later, without etc_query parsing the object again. An example of what you are doing would help me.

Offline

#202 2014-01-14 09:17:36

photonomad
Member
Registered: 2005-09-10
Posts: 290
Website

Re: etc_query: all things Textpattern

Oleg, Thank you for your reply! I see what you mean by the list/string difference. Makes sense. And, thank you so much for the helpful formatting/function examples!

I am working on a community calendar that consists of multiple Google calendars.* I created a Yahoo Pipe that grabs all the feeds and combines them into a json document. A static public example of the output is here: http://www.outcentral.org/comcaltestfeed.json

The pipe itself takes a while to run. My etc_query code runs slowly because I’ve got a ton of variables and lots of if/else tests for the output. I am using aks_cache (60 minutes) to try to help improve load time. I have to get some sleep right now, but will work on improving my code tomorrow with the tips you provided.

And, here is a link to a test/preview of the end result:
http://www.outcentral.org/comcal-test

  • I imagine there may be a way to combine, loop and sort data from multiple feeds with etc_query, but the solution is most definitely currently over my head. I also realize that there is probably a way to do most of this with the Google Calendar API. Once again: beyond my current Google API knowledge.

Last edited by photonomad (2014-01-14 15:35:24)

Offline

#203 2014-01-14 09:24:18

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: etc_query: all things Textpattern

Challenging, I like it. Good night, and see you tomorrow, I’ll take a look at it meanwhile.

Offline

#204 2014-01-15 04:56:40

photonomad
Member
Registered: 2005-09-10
Posts: 290
Website

Re: etc_query: all things Textpattern

Thank you so much for your help, Oleg.

One thing that I’m stuck on at the moment is whether it is possible to use {$?(if|then|else} or another method to test if the start time minutes = 00. If {$?(if|then|else} is only used to check for emptiness, should I just define a <txp:variable name=“startminutes” value=”{$date(i,{start?})}” /> and then use <txp:if_variable name=“startminutes” value=“00”> to test?

etc_query is so powerful and you make it seem so easy! I wish I could fully understand all of the shortcuts and possibilities.

Last edited by photonomad (2014-01-15 05:47:02)

Offline

Board footer

Powered by FluxBB