is_page() is not executed - php

I am making infinite scroll page. I created a page template where posts of certain category are loaded. Everything works fine with a single page and single category.
But I have three pages with this page template and each page should load articles from a specific category. I am using the is_page() if elseif block to determine on which page visitor is. But is_page() is not executed.
Here is the loop:
$cat = '';
if(is_page(703)){
$cat = 4;
} elseif (is_page(706)) {
$cat = 21;
}
$args = array(
'cat' => $cat,
'paged' => $paged
);
$infinite_news_query = new WP_Query($args);
if ( $infinite_news_query -> have_posts() ) : while ( $infinite_news_query -> have_posts() ) : $infinite_news_query -> the_post();
<?php endwhile; ?>
<?php else : ?>
<?php endif; ?>
<?php wp_reset_postdata();
?>
This code displays all the posts, regardless of category, and $cat is empty inside the loop.
What am I doing wrong?
Thanks!

Change the following:
$cat = '';
if(is_page(703)){
$cat = 4;
} elseif (is_page(706)) {
$cat = 21;
}
to:
if(is_page('703')){
$cat = 4;
} else { if(is_page('706')) {
$cat = 21;
}
Also removing $cat = '';

Look at it like this, at first you have the variable $cat set to empty value, respectively, to false , zero or 0.
Then you set a loop, with only two states, leaving out a default value.
So, what is going to happen, when your page ID is changed?
You get all the posts displayed.
In other words, I do not see anything bad in the code. I would rather recommend you to use is_page('slug') than with id.

Related

WordPress: Function for loading a specific page with shortcode

I have this structure of pages in WordPress:
Materials //parent
-> Plastic //children
-> Metal //children
-> ...
I want to include content from my file grid-fasads.php with shortcode exactly where I need to.
I have this code in a product.php where I use a shortcode:
$fasads = get_field('fasad_type');
foreach ($fasads as $f) {
echo do_shortcode('[grid-fasad]');
}
I wrote this function in functions.php:
function get_fasads($atts, $content = null ) {
$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query( array( 'post_type' => 'page' ) );
// get a specific page ID
$materials = get_page( 4702 );
// filter for choosing a children pages of 'materials'
$materials_children = get_page_children( $materials->ID, $all_wp_pages );
foreach ( $materials_children as $children ) {
$page = $children->ID;
echo $page;
}
// It's ok. The pages IDs are shown.
// After that I have this:
$recent = new WP_Query( "page_id = " . $page );
while( $recent->have_posts() ) : $recent->the_post();
require( '/fasads/grid-fasads.php' );
the_content();
endwhile;
}
add_shortcode( 'grid-fasad','get_fasads' );
I understand that the problem is ( "page_id = " . $page). I need to include a .php file's content for each children pages of 'Materials' page. Tried to insert last part of code into a loop, but failed every time.
Here is a fragment from
I also tried this loop:
foreach ($materials_children as $children) {
$page = $children->ID;
$recent = new WP_Query("page_id=".$page);
while ($recent->have_posts()) : $recent->the_post();
require('/fasads/grid-fasads.php');
the_content();
endwhile;
print_r(array_count_values((array)$page));
}
But as a result it shows a duplicates of values. Something is wrong.
Please, help.
I've solved this problem.
Here is a function:
function get_pallette() {
$my_wp_query = new WP_Query();
$all_wp_pages = $my_wp_query->query(array('post_type' => 'page'));
// get a specific page ID
$materials = get_page_by_title('Materials');
$materials_children = get_page_children( $materials->ID, $all_wp_pages );
if (isset ($materials_children)) :
foreach ($materials_children as $children) {
$page = $children->ID;
}
$fasads = get_field('fasad_type');
if (isset ($fasads)) :
foreach ($fasads as $f) {
$p = get_page_by_title( $f );
if (!empty ($p)) :
echo do_shortcode("[grid-fasad page=\"$p->ID\"]");
else :
//do something;
endif;
}
else :
//do something;;
endif;
endif;
//do something;
}
And here is another function for a generating shortcode:
function get_fasads($atts, $content = null ){
$atts = shortcode_atts(
array(
'page' => 0
), $atts, 'grid-fasad');
$recent = new WP_Query('page_id='. $atts['page']);
$path = $_SERVER['DOCUMENT_ROOT'].'/wp-content/themes/theme/fasads/grid-fasads.php';
while ($recent->have_posts()) : $recent->the_post();
require $path;
endwhile;
}
add_shortcode('grid-fasad','get_fasads');
A good's page fragment:
<?php if ( have_posts() ) while ( have_posts() ) : the_post(); global $_product; $_product = new jigoshop_product( $post->ID ); ?>
<div id="post-<?php $id_page ?>" <?php post_class(); ?>>
<div class="summary">
<?php do_action('jigoshop_after_single_product_summary', $post, $_product); ?>
...
<?php get_pallette(); ?>
</div>
<?php endwhile; ?>
Maybe it's not an elegant decision, but it works.
There is only 1 problem still: after execution function get_pallette() the page loose it's own ID, because I'm using "new WP_Query" with a new IDs of page's children. And if this function goes before action "jigoshop_after_single_product_summary" (as I want to), it cannot load a content of an actual good's page.

Hide tab if no posts are found in loop

So I have a customised wordpress search page that groups the result into the custom post type header.
This works but it still shows the post type if there are no posts in it.
What can I do to check to see if the section has posts, and if not, hide the section.
Note: if( !empty ( $hasposts ) ) currently returns FULL for each check as the post types have posts, but they are not part of the search results.
<?php
if( have_posts() ){
//Define post types:
$types = array('post', 'promo_offers', 'product_manuals', 'support_posts','product');
foreach( $types as $type ){
// RETURN EMPTY IF THE RESLUTS FOR THE POST TYPE IS EMPTY
$hasposts = have_posts($type);
if( !empty ( $hasposts ) ) { echo '<div>FULL!</div>';} else {echo '<div>EMPTY!</div>';}
//BELOW CODE WORKS AS INTENDED
echo 'your container opens here for ' . $type;
echo '<ul>';
while( have_posts() ){
the_post();
if( $type == get_post_type() ){
echo '<li>';
the_title();
echo '</li>';
}
}
echo '</ul>';
rewind_posts();
echo 'your container closes here for ' . $type;
}
}
?>
So my understanding is that have_posts() doesn't take parameters, and actually I'm curious about what happens when you call
$hasposts = have_posts($type);
Your function is looping through all posts multiple times, but only displaying those posts that have the type of $type. The point is that have_posts() returns true every time because it's referring to all posts, not just of the specified type.
So I think that what you need is to make a separate query for each type, like so:
foreach( $types as $type ) {
query_posts("post_type=$type");
while (have_posts() ) {
//now this should only happen if the specific type has posts in it...
}
}

Sort search results by meta_key value

I really need help with this. Below is a code of my wp page template for search results search.php and everything works just fine. Now, the website is about public events so it's very important that search results are displayed by event date. I've created a custom field called "date" and I'd like to display the results by "date" field value.
I spent a whole week to find a solution but unfortunately I couldn't. Please, help me :)
Here is a code:
<?php
global $query_string;
$query_args = explode("&", $query_string);
$search_query = array();
if( strlen($query_string) > 0 ) {
foreach($query_args as $key => $string) {
$query_split = explode("=", $string);
$search_query[$query_split[0]] = urldecode($query_split[1]);
}
}
$search = new WP_Query($search_query);
?>
<?php if ($search->have_posts()) : while ($search->have_posts() ) : $search->the_post(); ?>
<!-- loop goes here -->
<?php endwhile; else: ?>
<?php endif; ?>
Thank you!!!!
I'd try something else:
In your functions.php or my-plugin.php
add_filter( 'pre_get_posts', 'customize_search_page' );
function customize_search_page($query){
if(!is_admin() && $query->is_search && $query->is_main_query()){
$query->query_vars['meta_key'] = 'your_meta_key';
$query->query_vars['orderby'] = 'meta_value';
$query->query_vars['order'] = 'DESC';
}
return $query;
}
I did not tested it but the pre_get_posts filter will be called before the loop. If it's the right query (search and main) I changed the orderby to an order by meta value.

Get next_post_link which is Sticky?

I am trying to get the link of next Sticky post with it's title using:
<h2><?php next_post_link('%link') ?></h2>
I have tried passing TRUE argument but that only filters the taxonomy not Sticky Posts.
There is no option in next_post_link to just get sticky post (correct me if i am wrong) . You need custom navigation here. First you need to get all sticky post in array and then make next posts links :
// get all sticky posts
$sticky = get_option('sticky_posts');
// if there are any
if (!empty($sticky)) {
// newest IDs first, optional
rsort($sticky);
$args = array(
'post__in' => $sticky
);
$postlist = get_posts();
$posts = array();
$query = new WP_Query($args);
while ($query->have_posts()) {
$query->the_post();
$posts[] = get_the_ID();
}
//wp_reset_postdata(); uncomment this, if this is a nested loop
$current = array_search($post->ID, $posts);
$prevID = $posts[$current-1];
$nextID = $posts[$current+1];
// Link for previous post
if (!empty($prevID)) {
echo '<div>Prev</div>';
}
// Link for next post
if (!empty($nextID)) {
echo '<div>Next</div>';
}
}

Category_slug of category children wordpress

I have a category "Decouverte" witch has three subcategories : "actualité", "vidéo" and "coup de coeur".
When I sort the posts according to their subcategories, everything works except for the category "video"; the category_slug displays "decouverte".
On my dashboard, I see this :
The subcategory "Video" is displayed last, maybe it's why it doesn't work ?
My code :
$categories = get_the_category();
$category_slug = $categories[0]->slug;
echo $category_slug;
if ( $category_slug == 'actualite' ) { ?>
<div class="picto_home icone_actualite"></div><?php
}
elseif ( $category_slug == 'video' ) { ?>
<div class="picto_home icone_video"></div><?php
}
elseif ( $category_slug == 'coupdecoeur' ) { ?>
<div class="picto_home icone_coupdecoeur"></div><?php
}
else { echo "Doesn't work"; } ?>
And the website : http://www.overso.me/ It's on the right block
Problem source
It's because you have got two categories applied to all posts.
Categories in each post are sotrted alphabetically.
In your case you take $category_slug = $categories[0]->slug;, which means:
Take first category slug name from categories array
For each post it is:
$categories[0] = Decouverte, $categories[1] = Video because D < V
$categories[0] = Actualite, $categories[1] = Decouverte because A < D
$categories[0] = Coup de coeur, $categories[1] = Decouverte because C < D
How to make it work as you want
Ok so here is my approach for your problem.
Before checking for $categories[0]->slug, lets check is $categories[0] object a PARENT category. You can do this by checking:
$categories = get_the_category();
// Remove parent category object from array if it's on first place
if($categories[0]->parent == 0){
unset($categories[0]);
$categories = array_values($categories);
}
As you see if $categories[0] is a parent category (if($categories[0]->parent == 0)), then remove this result from array $categories - unset($categories[0]).
Now you can just reset indexing of this array to starting from 0, by calling $categories = array_values($categories).
From now, you can easly call $categories[0]->slug, because there is no parent category on first place for sure.
Full code:
$categories = get_the_category();
// Remove parent category object from array if it's on first place
if($categories[0]->parent == 0){
unset($categories[0]);
$categories = array_values($categories);
}
$category_slug = $categories[0]->slug;
if ( $category_slug == 'child-1' ) {
echo "1111";
}
elseif ( $category_slug == 'child-2' ) {
echo "2222";
}
elseif ( $category_slug == 'child-3' ) {
echo "3333";
}
else { echo "Doesn't work"; }
Of course change if statements logic to your data.
More general solution for future reference
Ok, here is some general solution I wrote.
If you need to get only subcategories for any post, for any number of categories applied to the post, and no matter on which place parent category will be in the categories array, you should try this.
First, add this function to your functions.php file (or to your plugin file).
function du_get_post_subcategories( $post_id ){
$categories = get_the_category( $post_id );
$i = 0;
foreach ($categories as $category) {
if($category->parent == 0){
unset($categories[$i]);
}
$i++;
}
$categories = array_values($categories);
return $categories;
}
And then inside your loop you can call
$subcategories = du_get_post_subcategories( $post->ID );
If you have post ID, you can call this outside the loop as well
$subcategories = du_get_post_subcategories( $your_post_id );
This function will return all subcategories in the same format as get_the_category() function.
If you provide array with only one, parent category. Function will return an empty array.

Categories