Textpattern CMS support forum

You are not logged in. Register | Login | Help

#291 2016-04-05 06:28:14

lazlo
Member
Registered: 2004-02-24
Posts: 102

Re: etc_query: all things Textpattern

etc wrote #298486:

Hi Oleg

I think I have to ask this question a different way.

I wanted to have a menu link:
http://kl.rs/authors/?alpha (which would do the A-Z based on Title)
http://kl.rs/authors/?alphaLN (which would do the A-Z based on Contributor_Full_Name_Reversed)

I can’t seem to create an If “?alpha” do this or If “?alphaLN” do that statement with adi_gps.
I think I misunderstood how adi_gps works, and it does not do what I had hoped.
adi_gps can do If “?alpha=B” do this or If “?alpha=C” do that, just fine but that doesn’t help me.

Is there a simpler way (most likely?) for me to accomplish this?
I approaching the menu link method incorrectly altogether?
Any insight would be appreciated.

Last edited by lazlo (2016-04-05 06:28:59)

Offline

#292 2016-04-05 07:41:20

etc
Developer
Registered: 2010-11-11
Posts: 3,170
Website

Re: etc_query: all things Textpattern

Ah, I misunderstood it, sorry. If you want to keep to empty http://kl.rs/authors/?alpha format, neither ect_query nor adi_gps will detect ?alpha switch, but you can do it php-way:

<txp:variable name="alphaset" value='<txp:php>echo isset($_GET["alpha"]);</txp:php>' />
<txp:if_variable name="alphaset" value="1">
... alphalist construction ...
<txp:else />
... something else ...
</txp:if_variable>

And if you don’t want to output A-articles by default, replace {?alpha|A} with {?alpha} in the alphalist construction. Same thing with alphaLN. Does it help?


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

Offline

#293 2016-04-05 23:17:51

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

Re: etc_query: all things Textpattern

Great plugin.
XPath is hard, but it brings great possibilities. One is to let the clients to manage add some simple markup (ie. via Textile) and convert it into “complex” HTML transparently.

Here is a tip:
suppose you have a website built with Bootstrap. The markup for a navbar that include dropdowns can be usually done with nested uls and some extra classes. Your client asks to have fine-control over the items shown on the navbar. Those items could be links to sections or links to articles, or links to categories, or links to wherever they want to.
But, then, you would prefer not to give them access to forms and page templates, nor to tinker with complex HTML structures.
You could use mck_snippet to create a Textile snippet were your client could easily add/remove/edit navbar items.But the problem are usually the extra classes needed on each ul, li and a elements that make the navbar. Yes, you could have them all on Textile too, but the Textile markup could become rapidly unmanageable/unreadable for someone non-tech-savvy.

So, mck_snippet alone won’t do it. That’s when etc_query gets into scene.

For this tip to work we need mck_snippet, etc_query and rah_function (optional, if you want current navbar item highlighted with class .active).

Let’s begin simple.

// "news_menu" snippet (managed via mck_snippet) using Textile.

* "News":/news
** "Blog":/blog
** "Videos":/videos
** "Photos":/photos 

As you know, that Textile code will output a simple ul/li/a structure. Nothing fancy.
Now we need to add all the needed classes to create the markup used by Bootstrap on navbars with dropdown.

 // Somewhere (usually at the top) on your page template.

<txp:hide>
 First, we create a variable that contains the full page URL (ie. http://www.example.com/news) for the page currently viewed.
 This is only necessary if you want to have the navbar item for the current URL to be marked with an class="active". 
 It will also add the class the top parent item (News, in this example).
</txp:hide>

<txp:variable name="full_page_url"><txp:rah_function call="rtrim" string="/"><txp:site_url /></txp:rah_function><txp:page_url /></txp:variable>

<txp:hide>
 Here, we take the full_page_url variable we just created and parse it to extract any query string that it may have.
</txp:hide>

<txp:php>
global $variable;
// This returns the URL path (/some-section/ or /some-section/some-article)
// without any query string and stores it in a txp:variable named "url_path"
$variable['url_path'] = parse_url($variable['full_page_url'], PHP_URL_PATH);
</txp:php>

<txp:hide>
 This is a variable I create to keep etc_query code cleaner. It just adds a clickable triangle (▼) 
 next to the parent item (News, in this example) to trigger the dropdown. 
 This is an adaptation I did to the BS navbar, as I wanted the parent item 
 to be a clickable link, so I added this separately.
</txp:hide>

<txp:variable name="dropdown-toggle"><a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">▼</a></txp:variable>
// Somewhere inside your navbar template.

<txp:hide>
 Finally, we process our mck_snippet through etc_query.
</txp:hide>

<txp:etc_query
  data='<txp:mck_snippet title="'news_menu" />'
  query='ul/child::li'              
  replace='
    .@@class=nav-item dropdown;
      ./a@@class=nav-link;
      <txp:if_individual_article>
      ./a[starts-with(@href, "/<txp:section />")]/ancestor::li@@class={concat(@class," active")};;
      </txp:if_individual_article>
      ./a$=<txp:variable name="dropdown-toggle" />;
        //ul@@class=dropdown-menu;
        .//li@@class=dropdown-item;
          //a[@href="<txp:variable name="url_path" />"]/ancestor::li@@class={concat(@class," active")};
    '
   />

Yes, the code make look a bit complex at first (and it certainly is, as XPath is a bit complex by itself). But that etc_query snippet has all the necessary replacements to create the desired markup.
The output will be the following, when visiting the Blog section.

<li class="nav-item dropdown active">
  <a href="/news" class="nav-link">News</a>
  <a class="dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">▼</a>
  <ul class="dropdown-menu">
    <li class="dropdown-item active"><a href="/blog">Blog</a></li>
    <li class="dropdown-item"><a href="/videos">Videos</a></li>
    <li class="dropdown-item"><a href="/photos">Photos</a></li>
  </ul>
</li>

So, as you can see, you go from simple Textile markup that your clients can easily type (with minimal risk of typos or erros) to a complex HTML markup.

You may have noticed that there is no <ul> element wrapping the output. That’s because I left that out (via the query='ul/child::li' attribute on @etc_query). That way, you can decide were to put that snippet on your navbar.
See next post with a new tip that will help you better understand what I mean.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#294 2016-04-05 23:18:37

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

Re: etc_query: all things Textpattern

See previous post to understand what we are doing on this post.

So now you have a way to let your clients manage their navbars, without the need for them to put a finger on the templates (risking breaking all your work ;) nor writing complex Textile/HTML.

Following the previous example, you want to let your client manage a few parts of the navbar. Let’s say the News subnavbar, the Product subnavbar and the About subnavbar
But repeating the above etc_query code for each sub-part of the menu you want to create is a bit non-DRY.
Let’s fix that with the help of <txp:output_form> and <txp:yield />.

// Your navbar code (in a form or in a page template).

<ul class="navbar">

  <txp:output_form form="dropdown-generator">
    <txp:mck_snippet title="about_menu" />
  </txp:output_form>

  <txp:output_form form="dropdown-generator">
    <txp:mck_snippet title="product_menu" />
  </txp:output_form>

  <txp:output_form form="dropdown-generator">
    <txp:mck_snippet title="news_menu" />
  </txp:output_form>

   <!-- Some hardcoded item that you don't want the client to touch. -->
   <li class="nav-item"><a href="#">Lorem ipsum</a></li> 

</ul><!-- .navbar -->

As you can see, we call the same form (dropdown-generator), passing a different mck_snippet to each call. That mck_snippet is the <txp:yield /> that you will see on the next snippet. Yes, it’s like calling the same function a few times, passing a different parameter each time.

// Our "dropdown-generator" form

<txp:etc_query
  data='<txp:yield />'
  query='ul/child::li'              
  replace='
    .@@class=nav-item dropdown;
      ./a@@class=nav-link;
      <txp:if_individual_article>
      ./a[starts-with(@href, "/<txp:section />")]/ancestor::li@@class={concat(@class," active")};;
      </txp:if_individual_article>
      ./a$=<txp:variable name="dropdown-toggle" />;
        //ul@@class=dropdown-menu;
        .//li@@class=dropdown-item;
          //a[@href="<txp:variable name="url_path" />"]/ancestor::li@@class={concat(@class," active")};
    '
   />

That’s all. We “abstracted” the etc_query snippet, making it reusable. DRY FTW.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#295 2016-04-06 02:00:56

jstubbs
Moderator
From: Hong Kong
Registered: 2004-12-13
Posts: 2,394
Website

Re: etc_query: all things Textpattern

This looks like a great idea for a Textpattern Tip, Julián!

Offline

#296 2017-06-02 19:28:30

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

Re: etc_query: all things Textpattern

Dear etc_query and XPath wizards. I have a bug in my ect_query template, causing it to return nothing when I want it to return something. Here are the details.

Can anyone here offer any guidance?

Last edited by johnstephens (2017-06-02 19:29:01)

Offline

#297 2017-06-05 21:20:32

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

Re: etc_query: all things Textpattern

I found a solution [posted here].

I expected that using etc_query for search-and-replace would behave like a regular expression, and the original text would return even when it doesn’t contain the search pattern. I could not figure out how to do that with etc_query by itself, but I do know how to use Textpattern’s if_variable tag.

Offline

#298 2017-06-14 16:25:20

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

Re: etc_query: all things Textpattern

How can I avoid having my self-closing XHML-tags transformed into unclosed tags?

I’ve noticed that etc_query converts self-closing tags like <br /> and <img src='…' /> in my data into unclosed tags, and I don’t know how to fix it.

I’m using the latest stable versions of Textpattern (4.6.2) and etc_query (1.3.3), and I’ve tested this on different installations, and even disabled all other plugins.

Here’s a simple page template I used to test it:

<txp:variable name="content">

<div>
  <h1>Hello world</h1>

  <style>h1 { font-family: Helvetica; }</style>

  <img src='nonexst' />

  <p>Hello, <br />this is world</p>
</div>

</txp:variable>

<txp:etc_query data='<txp:variable name="content" />' replace="//@style" />

Despite making sure the br and img elements are properly closed in the data, etc_query transforms it them into unclosed tags, like this:

<div>
  <h1>Hello world</h1>

  <style>h1 { font-family: Helvetica; }</style>
<img src="nonexst"><p>Hello, <br>this is world</p>
</div>

This might be no problem if I was just sending content to the browser, but this site requires strict XHTML markup for output in other formats.

Is there any way to nudge etc_query to return my content without stripping the / from self-closing tags?

Offline

#299 2017-06-15 07:37:17

etc
Developer
Registered: 2010-11-11
Posts: 3,170
Website

Re: etc_query: all things Textpattern

Hi @johnstephens and sorry, I was absent for a moment. Have you tried to call etc_query with markup="xml" attribute? But then the source must be XML-valid too.


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

Offline

#300 2017-06-15 12:07:05

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

Re: etc_query: all things Textpattern

etc wrote #305970:

Hi @johnstephens and sorry, I was absent for a moment. Have you tried to call etc_query with markup="xml" attribute? But then the source must be XML-valid too.

Thank you, @etc. I somehow missed this. It appears to solve the problem! I’ll do some more testing later today.

Thank you so much!

Offline

Board footer

Powered by FluxBB