Skip Navigation

[Resolved] taxonomy term order and/or conditional statement against current post

This thread is resolved. Here is a description of the problem and solution.

Problem:
What is the difference between "$parent", "$parent_post_type_slug" and "$current_page", and when can they be used-

Additionally, how can I "order" a Hierarchic Taxonomy output?

Solution:
https://toolset.com/forums/topic/taxonomy-post-order-andor-conditional-statement-against-current-post/#post-374839
This Post is very, very detailed and elaborated on every single case.
It is a long post, but there is no short way to explain the usage of above Arguments.

As for "what is the difference:"

$parent

is used on WordPress Native parent relations, or, when the Post type has Page attributes and is hierarchical

$parent_post_type_slug

is used on post relations set up by types

$current_page

is returning the values of the page or post where the View is used on.

Relevant Documentation:
https://toolset.com/documentation/user-guides/displaying-brother-pages/
https://toolset.com/documentation/user-guides/views/

This support ticket is created 8 years, 1 month ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- - 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00 14:00 – 20:00
- - - - - - -

Supporter timezone: Asia/Ho_Chi_Minh (GMT+07:00)

Tagged: 

This topic contains 6 replies, has 2 voices.

Last updated by marcoM-5 8 years ago.

Assisted by: Beda.

Author
Posts
#374171

I need to show taxonomy terms for the current post in a custom order.

On an different view (of a taxonomy type) I was able to get a custom sort of terms using https://wordpress.org/plugins/custom-taxonomy-order-ne/ and choosing Term ID + Ascending for the sort of the view.

However, in this completely different view (post type), there does not seem a way to show a custom order using the same Custom Taxonomy Order NE plugin with

[wpv-post-taxonomy type="mytaxonomy" separator=" " id="$current_page"]

without an orderby option? (((feature request)))

So, then I looked into conditional statements to list the terms individually one at a time as a workaround. I registered has_term() and used

[wpv-conditional if="( has_term('myterm', 'mytaxonomy', null) eq '1' )"] output [/wpv-conditional]

which works, but always returns true since other posts in the loop have the term even if the current post does not(?). My view is limited to 1 result and all fields in the view are clarified with

id="$current_page"

After looking at https://toolset.com/forums/topic/views-if-current-page-if-current-post/ it seems that

[wpv-conditional if="( has_term('myterm', 'mytaxonomy', null) eq '1' ) AND ( '[wpv-post-id]' eq '[wpv-post-id id="$current_page"]' )"] output [/wpv-conditional]

would fix this. However, I cannot get

[wpv-if evaluate=" '[wpv-post-id id="$current_page"]' = '[wpv-post-id]'"] output [/wpv-if]

or

[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id="$current_page"]' )"] output [/wpv-conditional]

to return true on it's own. When I turn on debug, it's only evaluating one other ID against the current ID and apparently stops. I expected it to compare all relevant posts to the current page and return true since the current page exists in the loop. I expected it to work like other conditional statements I'm using successfully in the same view such as

[wpv-conditional if="( '[types field="myfield" id="$current_page"][/types]' ne '' )"] output [/wpv-conditional]

The only problem I'm having with using

[wpv-post-taxonomy type="mytaxonomy" separator=" " id="$current_page"]

is that the terms are not displaying in the desired order as set by Custom Taxonomy Order NE.

So my final questions are:

1) Is there a way to grab the custom order from Custom Taxonomy Order NE? To me, this would be the best, as new terms could be added and reordered without having to update the view.

2) Failing that possibility, how do I successfully conditionally compare against the current page?

#374316

1. The Views ShortCode "wav-post-taxonomy" only has a order option, not a orderly option.
https://toolset.com/documentation/views-shortcodes/#wpv-post-taxonomy

I will add this as a feature request.

2.

[wpv-conditional if="( has_term('test', 'category', null) eq '1' )" ]
 things
[/wpv-conditional]

will output "things" once if there is one post with that Term, twice if two, etc.
No matter how many posts are in the Loop.

3. I don't understand "My view is limited to 1 result and all fields in the view are clarified with

id="$current_page"

That is a Parent Selector ID or "Specific Post ID" (which it isn't in your case)

How can the current Post in loop ever be equal to the parent Post ID?

4. Is there a way to grab the custom order from Custom Taxonomy Order NE? To me, this would be the best, as new terms could be added and reordered without having to update the view.

No, not with the Toolset GUI and ShortCodes.
It requires a new ShortCode.

5. Failing that possibility, how do I successfully conditionally compare against the current page?

What do you want to compare exactly?

From your code, you compare Parent Post ID with current in Loop Post ID, which will never return true.

I might misunderstand, please could you provide me the additional Infos?

Thank you for your patience.

#374432
screenshot-views-settings.png

Thank you for your reply. I have attached a screenshot of the view settings, so you may see that the view is limited to one item.

The view is being displayed on product pages, and I want to show information for the current product using the view. Everything is working as desired using code such as

<div class="product-image">[wpv-post-featured-image size="full" id="$current_page"]</div>
<h2 class="product-title">[wpv-post-title id="$current_page"]</h2>
<h3 class="product-headline">[types field="headline" id="$current_page"][/types]</h3>
<div class="product-description">[types field="description" id="$current_page"][/types]</div>
[wpv-conditional if="( '[types field="sale-info" id="$current_page"][/types]' ne '' )"]<div class="on-sale">[types field="sale-info" id="$current_page"][/types]</div>[/wpv-conditional]

According to https://toolset.com/documentation/user-guides/displaying-fields-of-parent-pages/ a parent selector would be $parent. It states that “when you insert a View into a page, you might need to get some data from that page. To do so, you can set $current_page as the id attribute value” which is working as expected for me in the view, as in the example code above.

[wpv-conditional if="( has_term('test', 'category', null) eq '1' )" ]
 things
[/wpv-conditional]

only displays once, because the view only returns one result. But, I want it to return the result for the current page. That is what led me to https://toolset.com/forums/topic/views-if-current-page-if-current-post/. I would like to use it with has_term() so I may conditionally list the current post’s terms one at a time, in the desired order. I was expecting the code would look something like

[wpv-conditional if="( has_term('myterm1', 'mytaxonomy', null) eq '1' ) AND ( '[wpv-post-id]' eq '[wpv-post-id id="$current_page"]' )"] This post has MyTerm1. [/wpv-conditional] 
[wpv-conditional if="( has_term('myterm3', 'mytaxonomy', null) eq '1' ) AND ( '[wpv-post-id]' eq '[wpv-post-id id="$current_page"]' )"] This post has MyTerm3. [/wpv-conditional]
[wpv-conditional if="( has_term('myterm2', 'mytaxonomy', null) eq '1' ) AND ( '[wpv-post-id]' eq '[wpv-post-id id="$current_page"]' )"] This post has MyTerm2. [/wpv-conditional]

I expect the above would check for the current page in the loop AND check if that same record has the term and IF TRUE, display my markup. However, I’m not having luck conditionally comparing against the current post ID.

What I’m looking for is some way of displaying the terms that belong to the current page in a specific order.

#374555

This is correct, but $parent and $current_page ONLY work for WordPress native PAGES. Not Posts.

On any other content you use (for parents set by types) $parent_post_slug
Current post data is displayed by simply not pass any ID.

Featured image for the current Post (either in Loop or Content template or directly yon post) is:
[wpv-post-featured-image]

You display things for current product.
This is not a native PAGE.
It's a POST.

Also you return by the View the FIRST POST in loop, not the Current Viewed Post.

To display ONLY the post that the View is inserted on, you would need to use a Views Query Filter:
Include only posts with IDs set by the View shortcode attribute "ids" eg. [wpv-view name="view-name" ids="1"]

Then, when you insert the View in the Post (or content template) you pass the ids=value here with ids=[wpv-post-id]

But, usually you will not need a View too display infos about the Current Post.
You can do that with a Content Template.

Please let me know if that helps.

#374653

Wait, what?! I have not read anything in the documentation yet that said I could/should NOT use $current_page with a post/CPT.

For example, under #5 on https://toolset.com/documentation/user-guides/displaying-brother-pages/ states “This attribute tells Views to use the ID of the currently displaying page or a post and lets us check if an item in the View loop is the currently displayed one.” https://toolset.com/documentation/user-guides/views/ states that in views “Post types covers the standard WordPress posts and pages, as well as custom post types.” If I am truly not supposed to be using $current_page with a CPT then the documentation definitely needs explicit clarification on this, as so many examples in the documentation tutorials seem to be using CPTs themselves.

If I cannot/should not be using $current_page with a posts type view of any content other than native WP pages, this means I cannot use the WP Views widget to display information outside of the content area for a CPT. Even if it allowed setting the filter attribute (or I used a text block widget instead with the shortcode) such a thing (ids=“1”) would require a separate widget for every product. This would create a maintenance nightmare!

It would also mean I cannot/should not use views dynamically in conjunction with Beaver Builder, which allows wp-views insertion (also no filter declarations option) but does not allow insertion of the content templates. The ability to use Beaver Builder was expressly requested by the client. Custom fields are displayed by a number of views in a consistent manner, while the client can create per-product accordions of features and add images and other text in visual manner in between the different sections containing the views. It has been working beautifully so far. I set up all the views and created a BB template and the client successfully created the pages for all the products themselves. Everyone has been very happy, with the exception of the order of the terms output by [wpv-post-taxonomy].

[wpv-view name="view-name" ids=“1”] does work as you describe in an HTML block inside Beaver Builder, but this means the client cannot use a BB template without fiddling with code and finding the ID of the product to set the correct ID for every single product every single time they add one. This activity would have to be repeated in a half dozen views utilized in the BB template. If the client needs/requested a visual builder in the first place, you might guess how appealing this would be to them.

I’m just at a loss that you are saying that I can ONLY USE CONTENT TEMPLATES in conjunction with a CPT to show information related to the current CPT. This is erases the dynamic power of using $current_page that make wp-views such an amazing tool. It severely limits what can be done with CPTs, and I’m having a hard time believing it to be true based on all the things I have done with views + CPTs thus far that are working as expected per the documentation itself. On 40+ products (CPT) to date, the view I am describing (and a half dozen total views like it, just for this CPT) are displaying the current information for the current CPT. The views are not returning the first post of the loop, but the current post of the loop. It’s working just as I expected it to based on my reading of the existing documentation.

In my original reference point for solving the term order problem myself, https://toolset.com/forums/topic/views-if-current-page-if-current-post/, the original question asked “I want to create classes in my Unordered list depending on current post / page.” The answer did not clarify that the answer was ONLY for native WP pages (not posts, not CPTs). I really do not understand.

#374839
Bildschirmfoto 2016-03-11 um 13.28.26.png

OK, I see there is confusion, and I apologize, having generated and alimented this confusion-

I am sorry for the following Looooong Post and that is why you can, if you want, skip to the part "Solution".
But I suggest to read the first part to, it could help for future development.

1) Preliminaries
$parent and $current_page will work only on WordPress native Pages - that was my statement, and it is not accurate enough.
- It does not work on WordPress native Posts (at least, not fine, see below)
- It does not work on Custom Post Types unless those have this settings in Types > Custom Posts > Edit:
Page Attributes
> Menu order and page parent (only available for hierarchical posts).
> Hierarchical must be true

2) The $parent and $current_page used in a View, which queries WP Native Pages.
You have 3 pages:
A Child Page
A Parent (of above Child) Page
A Dummy Page not parent or child to none of above
The View loop holds:

<wpv-loop>
  <p>Parent: [wpv-post-title id='$parent']</p>
  <p>Current: [wpv-post-title id='$current_page']</p>
</wpv-loop>
All the settings of the View are default.

This will output on the front end:
[php]
Parent: Debug Dummy
Current: Child Page
Parent: Parent Page
Current: Child Page

This is becasue you have 3 Pages, and the View by defautl deos not include the Current Page in the query results
It outputs therefore the Loop 2 times.

Since the "Debug Dummy" page has no parent set, it will fallback to the queried Page and simply output that page instead.

You woudl use a HTML conditional check to exclude this page (checking if parent exist)

Now if you limit this View to outoutoutput only ONE page(item) in the Limit and Offset settings, it will simply output the FIRST item in the loop, according to your Ordering / Offset and Query options.

So if those are default, it will output the Page with the latest Post date, and of course the $current_page. That all.

It will not output the parent of the $current_page, if the $current_page is not the NEWEST page in loop.

If you want to display content related to the parent of the current page you need to query/return this current page, and call it's parent.

Simply delimiting the View to output only one item will not be the right approach.
You could use a Content Template or insert the shortcodes directly to the Page.

3) Now, does this work on Posts(native)?
Not fine!
The same View loop code, with the same basic view settings(defaults) and again the same setup of Posts, will output:

Parent: Dummy post
Current: Child Post
Parent: Parent Post
Current: Child Post

This is because it still does not query (by default) the current page (and here I admit, the wording in View settings is wrong and confusing and I reported this)

So it loops over all posts (3 in our case here) and for each, it outputs waht we have in loop.

Since Post (native) Views can not call a $parent (or do you see a hierarchical parent setting in Post edit screens?) it will fall back for the first Shortcode to the next available post.

id='$current_page' on the other hand will return the current post, but since the View queries all posts, it will output it for all posts in the loop.

Again, just delimiting the View to output ONE post only will NOT return (query) the CURRENT but the by Orderby/Offset/ Query settings chosen Post (latest Post date DESC as example)

Again here, to display correctly data about current Posts you use a Content template or insert it to the Post directly (usually, please don't misunderstand. this is NOT the only way)

4) Now for Custom Posts by default above will be valid exactly the same.
ONLY if those Custom Posts have specific settings as explained on top of this, yes, too loooong post :D, it will work as for the situation with pages.

Again here, same Views default settings and same Loop, will output:

Parent: Dummy CPT
Current: Child CPT
Parent: Parent CPT
Current: Child CPT

This because you again do not query the current post by default and so it will output any post for the items in loop where no parent is found, and the parent where it is found, as we do not chek if the parent exists.

Then, for $current_page it will return the post/page where this view is insert.

And again here, just delimiting the View to output ONE post only will just output ONE post (first returned in query set by Orderby/Offset/Query settings)

So this should be clear, to display information about the Current page you usually use a Content Template or direct in post/page, as the View, delimited to one post, will query ONE post and this will be the FIRST post in the Orderby Settings/Offset/Query.

$current_page will output the current page / post info but if this is used in the Loop it will do this as many times as a post is returned.

You can display only info about Current post if you delimit the View to one Post, and insert ONLY the $current_page info.

But $parent will ALWAYS query the post returned in the Loop and NEVER about current page if the loop item is not accidentally the current page.

Also, the practically same effect/result and way less query expensive is achieved with a Content Template for the Post / page or directly in the Post /page

=======================================================================================
PRELIMINARIES TO THE SOLUTION TO YOUR REAL PROBLEM HERE
=======================================================================================

To return on topic.

This will display the term about current (in loop!!) post/page:
(Sorry I use native category with 2 terms: "test" and "parent")

[wpv-conditional if="( has_term('test', 'category', null) eq '1' )"] 
  output
[/wpv-conditional

This will display the term of current post or page where the view is insert

[wpv-post-taxonomy type='category' format='name' id='$current_page']

This displays parent term ONLY if the CURRENT in LOOP post has a parent, and remember the settings must be specific for the post type.

[wpv-post-taxonomy type='category' format='name' id='$parent']

And again, current post in loop is always determined by:
Orderby and Limit/offset, Query Filter

So if you use has_term in a HTML condition, this will check the post IN LOOP and evaluate.

If the View is set to NOT query the current post then the current post will NEVER be returned in the Query.

So the Latest Post by date (which will be your first item and only one (if delimited by limit and offset) will always be another, not current viewed post.

That means, this:

[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"]
  output
[/wpv-conditional]

will never return true, unless you query the correct post which has to be the current post.

This means, $current_page has to be the same post as you return by View Query, Limit and Offset, + "display current page".

Resuming (yes, we are getting there, no worries 🙂 ):

[wpv-conditional if="( has_term('test', 'category', null) eq '1' ) AND ( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"] 
  output 
[/wpv-conditional]

Will ONLY return "output" if:
- The current post in Loop is also the current page/post (where view is used on), and this will only happen, if the Views Queries return the (current) post / page.
- And this is alsmost impossible as it depends on orderby, offset and query settings.
- IF the both posts match, it does return output, no doubt, I tested this.

But as soon you publish a new post, and have the view set to oderby post date DESC and one item only, this fails.

=======================================================================================
SOLUTION
=======================================================================================
To try to solve this, do return No Limit of posts in the Orderby and Offset

Also, the current post must be returned by the view.
(Uncheck the view setting "Don't include current page in query result")

Then, this evaluation will return only ONE item (since there is only one match):

[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"] 
  output
[/wpv-conditional]

After, INSIDE that conditional, you re-evaluate the term:

[wpv-conditional if="( has_term('test', 'category', null) eq '1' )"]
  output 
[/wpv-conditional]

So the final condition looks like:

[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"]
  [wpv-conditional if="( has_term('test', 'category', null) eq '1' )"]
    output 
  [/wpv-conditional]
[/wpv-conditional]

This should according my tests, return "output" only if:

- The page/post where this View is used on matches the current View loop Post/Page, and that post/page has term "test".

- Every subsequent check for taxonomy term MUST be inside the first evalaution, so as example to order your terms (I have "test" and "parent" term) you need this:

[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"]
  [wpv-conditional if="( has_term('parent', 'category', null) eq '1' )"]
                output parent term here 
  [/wpv-conditional]
  [wpv-conditional if="( has_term('test', 'category', null) eq '1' )"]
                output  test term here
  [/wpv-conditional]
[/wpv-conditional]

IF I got it all right, we are done.

Please let me know if this helps to achieve your goal

And please excuse the long post, I just want that all is clear.

#377699

My apologies, I had fallen ill. I really, truly appreciate the long explanation. It is obvious to me now that the best practice for what I am trying to use wp-views to do here (showing content related to the current post/CPT outside the native WP content area) is that I should wrap the output of my entire loop in

[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"] All the things I want to show about the current CPT here. [/wpv-conditional]

Using the example of “what was working” about the view I cited earlier (and wrapping it in the wpv-loop portion of the view so others who may read this in the future have no confusion), this:

<wpv-loop>
<div class="product-image">[wpv-post-featured-image size="full" id="$current_page"]</div>
<h2 class="product-title">[wpv-post-title id="$current_page"]</h2>
<h3 class="product-headline">[types field="headline" id="$current_page"][/types]</h3>
<div class="product-description">[types field="description" id="$current_page"][/types]</div>
[wpv-conditional if="( '[types field="sale-info" id="$current_page"][/types]' ne '' )"]<div class="on-sale">[types field="sale-info" id="$current_page"][/types]</div>[/wpv-conditional]
</wpv-loop>

Should really look like this (with no query item limits, of course):

<wpv-loop>
[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"]
<div class="product-image">[wpv-post-featured-image size="full"]</div>
<h2 class="product-title">[wpv-post-title]</h2>
<h3 class="product-headline">[types field="headline"][/types]</h3>
<div class="product-description">[types field="description"][/types]</div>
[wpv-conditional if="( '[types field="sale-info"][/types]' ne '' )"]<div class="on-sale">[types field="sale-info"][/types]</div>[/wpv-conditional]
[/wpv-conditional]
</wpv-loop>

It makes perfect, logical sense that a view set to return only one result would only return the first result, and the behavior of HOW it was returning the information related to the current post is now totally apparent to me (in a facepalm “of course!” sort of way), so I very much appreciate you taking the time to explain what is obvious if you have your head into it right.

I do have a content template for the same product CPT that I’m using these views for, as a fallback for if there’s ever an instance the BeaverBuilder “page builder” is not fired up (so to speak) by the client to fill out all the per-item customizations to the page. This way all the essential information is displayed in a manner that echoes the format of the views sections I created for the BeaverBuilder templates. Expanding on the theme of this topic, the code from my second code snippet above would be simplified to:

<wpv-loop>
[wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"]
[wpv-post-body view_template="Content Template for this section of info"]
[/wpv-conditional]
</wpv-loop>

And all these sections/content templates could/should be collected into the “master” content template for the CPT that displays as the fallback for the native WP content area when BeaverBuilder isn’t engaged, which really simplifies the codebase and maintenance. It’s not that I haven’t been using nested content templates or content templates inside views, but I just want this workflow to be perfectly clear for anyone seeking to replicate.

You know, I hadn’t come across the [wpv-conditional if="( '[wpv-post-id]' eq '[wpv-post-id id='$current_page']' )"] in the documentation/tutorials but only in the forum after I hit this roadblock with the taxonomy orderby (still a feature request, thank you!). I think this would make an excellent addition to the documentation/tutorial section. While it might be more an unusual case to be using views in conjunction with BeaverBuilder, the desire to highlight certain fields or relationships to the current page in a sidebar or other widgetized area probably comes up more frequently. I wonder how many people have done what I did with the $current_page on the fields in their view, and limiting the view to 1 item to “solve” the problem of the repeating fields. Especially considering with the “loop wizard” you’re going to have people who are not well steeped in programming/query logic getting comfortable tinkering and making the same fallacy as I did.

I’m not sure why it didn’t all become clear to me once I got onto the fact that I needed to conditionally check against the current page in the first place for the terms. Again, I’m quite grateful for your patient explanation that allowed me to catch on to my logic mistake much further back in the development process.

I have verified that the workflow I’ve laid out above and your “the solution” with has_term() works. Again, thank you!

This ticket is now closed. If you're a WPML client and need related help, please open a new support ticket.