I have a view that displays a grid of up to 18 content items (CPTs) for particular location. If a particular location doesn't have 18 items (lets say they have only 10), I want the 11th item to be static and contain a link (for a user to add their content). If the particular location already has 18 items, that last, static item doesn't need to be displayed.
I'll need to provide access, so my next reply should be private. You'll need to see what I'm referring to.
Hello and thank you for contacting the Toolset support.
Your next reply will be private to let you share credentials safely. ** Make a database backup before sharing credentials. **
Hello and my apologies for the late reply.
You can use conditionals inside of your wpv-index shortcodes with the wpv-found-count or wpv-items-count and probably wpv-loop-index.
As you are already using index=pad and index=pad-last, the easiest way I could come up with your current view is by generating multiple elements for purchasing the ad spot and removing all except the first one with a custom Javascript code. I updated your view with the following code:
[wpv-item index=pad]
[wpv-conditional if="( '[wpv-found-count]' lt '18' )" evaluate="false"]
<div class="col-md-2"></div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-found-count]' lt '18' )"]
<div class="col-md-2 add-button"><h4>Button here</h4></div>
[/wpv-conditional]
[wpv-item index=pad-last]
[wpv-conditional if="( '[wpv-found-count]' lt '18' )" evaluate="false"]
<div class="col-md-2"></div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-found-count]' lt '18' )"]
<div class="col-md-2 add-button"><h4>Button here</h4></div>
[/wpv-conditional]
</div>
Then I added this Javascript code to the view to remove the ad spots except the first one. Notice how I used the class "add-button".
jQuery(function($){
$('.add-button').not(':first').remove();
})
You can have a different solution without using index=pad. But by using index=1 or 2, 3, 4, 5, and 6. And using a conditional on the wpv-loop-index with the possible values. For example when index=2, the conditional will only apply if wpv-found-count equals 2, 8, or 14(index+n*6).
I hope this gives you an idea. Let me know your feedback.
Thanks, Jamal. I saw the adjusted view after I posted the follow-up.
This isn't really the solution I was looking for. I can see the static item on Los Angeles, California, but there are three instead of one (I removed the "button" code and added my Elementor template). hidden link
Locations with NO ads don't show anything (not even the static item). hidden link
So, I wasn't able to see the jquery code, so I added it to the view. It does remove the last two instances of the static item, leaving only one (the way I want it to). I just need to get that same static item ([elementor-template id="867"]) to display when there are NO ads (no items found).
I added the following code to the view and it removes the additional ad spot elements:
jQuery(function($){
$('.add-button').not(':first').remove();
})
Without Javascript code, the only way I think of requires to use a number on the index and dropping index=pad and index=pad-last.
Then inside each index, we can use a similar condition, one evaluated to true, and the second to false. The condition this time should be on the wpv-loop-index on its possible values. For example for index=1:
[wpv-item index=pad]
[wpv-conditional if="( ('[wpv-loop-index]' eq '1') OR ('[wpv-loop-index]' eq '7') OR ('[wpv-loop-index]' eq '13') )" evaluate="false"]
the content template
[/wpv-conditional]
[wpv-conditional if="( ('[wpv-loop-index]' eq '1') OR ('[wpv-loop-index]' eq '7') OR ('[wpv-loop-index]' eq '13') )"]
the ad spot content template
[/wpv-conditional]
I hope this makes sense. Let me know if you have any questions about it and I can fix the view again.
I've added a few more ads to Los Angeles, California (for a total of 6 ads). The static item fails to show on the next row (position 7 of 18 or position 1 of row 2).
I also can't understand why the static template doesn't show for cities with no ads (no-items-found). I can get a text string to display, but not the Elementor template.
I also can't understand why the static template doesn't show for cities with no ads (no-items-found). I can get a text string to display, but not the Elementor template.
This is probably an expected behavior from Elementor templates! If no post is passed to the template, nothing is rendered. Because the "Place ad" template type is page, I assume that Elementor expects to have a page or at least a custom post(page is a custom post type), but nothing is passed to it. I searched online on how to display static content designed with Elementor, but I could not find any. Or maybe this is another bug/issue. We can focus on it after finding a way for the general use case.
For the general use case, I discussed an option with the team and it may be a good lead, we can inject a default post into the view results when the view has less than 18 elements, and with only one condition on the default post id, we can show one of the Elementor templates. Example code can be found here https://toolset.com/documentation/programmer-reference/views-filters/#wpv_filter_query_post_process
None of us has tested this, so I wonder if you can allow me to take a copy of your website and check it locally, or if you can provide FTP access and let me check it? In that case, just update the previous credentials with FTP access or add them to your next reply.
The site is not a production site. I have a fairly recent backup. Do whatever you need to do (as long as I'm able to see what you did).
Jamal,
At the bottom of this page (https://toolset.com/documentation/user-guides/using-toolset-with-elementor-page-builder/create-templates-for-custom-post-types-with-elementor-and-toolset/), it says the following:
"Also, do not insert an Elementor Template into a View’s Loop Item or Content Template. If you need to use an Elementor Template in the Views Loop, add it directly within the wpv-loop tags. At the same time, make sure that the posts in the Views Loop are not using Content Template for styling."
I honestly can't make out what that means. I'm not using a Content Template. That much I know.
Please add the following code to your theme's functions.php file, hopefully, it will inject a default post into the view results. Replace the id of the default post (id 1, with the id of a draft promo post). Then check if it works.
add_filter( 'wpv_filter_query_post_process', 'jts_inject_draft_promo', 10, 3 );
function jts_inject_draft_promo( $query, $view_settings, $view_id ) {
// replace this with the default/draft promo post idate
$default_promo_id = 123;
if ( $view_id == 784 ) {
if ( $query_post_count < 18 ) {
$default_promo = get_post( $default_promo_id );
$query->found_post[] = $default_promo;
$query->found_count = $query->found_count + 1;
}
}
return $query;
}
After that, there will be no need to handle different index, just enough to wrap your columns in a row and one condition on the post id:
[wpv-conditional if="( '[wpv-post-id]' eq '123' )" evaluate="false" ]
<div class="col-md-2">
[elementor-template id="278"]
</div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-found-count]' lt '18' )" ]
<div class="col-md-2">
[elementor-template id="867"]
</div>
[/wpv-conditional]
To test this, myself, on your server, I need FTP access, this will allow me to check the debug.log file and to be able to recover in case of an error in code. I simply can't write any line of code on your server without having FTP access.
Jamal,
We must have both solved this, at the same time, in different ways! 🙂
It occurred to me to make a Default Promo post type, with the default ad info, and include it in the view, sorted last, by post type.
The code was erroneous, my mistake 🙂
I tested with the view that I have created previously this morning and the following code has successfully injected the default/draft post into both views:
add_filter( 'wpv_filter_query_post_process', 'jts_inject_draft_promo', 10, 3 );
function jts_inject_draft_promo( $query, $view_settings, $view_id ) {
// replace this with the default/draft promo post idate
$default_promo_id = 924;
$views_ids = array(784, 918);
if ( in_array( $view_id, $views_ids ) ) {
if ( $query->found_posts < 18 ) {
$default_promo = get_post( $default_promo_id );
$query->posts[] = $default_promo;
$query->found_posts = $query->found_posts + 1;
$query->post_count = $query->found_posts + 1;
}
}
return $query;
}
Then, I updated my view (#ID 918) with the following code, because it needs the columns to be wrapped inside a <div class="row">
<wpv-loop wrap="6" pad="true">
[wpv-item index=1]
<div class="row ">
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" evaluate="false" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="278"]</div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="867"]</div>
[/wpv-conditional]
[wpv-item index=last]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" evaluate="false" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="278"]</div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="867"]</div>
[/wpv-conditional]
</div>
[wpv-item index=other]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" evaluate="false" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="278"]</div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="867"]</div>
[/wpv-conditional]
[wpv-item index=6]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" evaluate="false" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="278"]</div>
[/wpv-conditional]
[wpv-conditional if="( '[wpv-post-id]' eq '924' )" ]
<div class="col-md-2">[wpv-post-id] [elementor-template id="867"]</div>
[/wpv-conditional]
</div>
</wpv-loop>
I'll let you do the same for your view, and then remove my view from the content template.
"Also, do not insert an Elementor Template into a View’s Loop Item or Content Template. If you need to use an Elementor Template in the Views Loop, add it directly within the wpv-loop tags. At the same time, make sure that the posts in the Views Loop are not using Content Template for styling."
This means that we have to put the Elementor template shortcode directly inside the loop and that it won't work on other places or inside a content template.