WordPress: Function for loading a specific page with shortcode - php

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.

Related

Get the current post category name inside while loop

I created a custom post type "stm_media_gallery"
And three category inside this custom post type.
I want to display category name associated with each post.
<?php $gallery_query = new WP_Query( array('post_type' =>
'stm_media_gallery', 'posts_per_page' => -1) );
if( $gallery_query->have_posts() ) :
while( $gallery_query->have_posts() ) : $gallery_query->the_post(); ?>
--Display post name and its category name
<?php endif; ?>
<?php endwhile; ?>
You just need to put following code inside loop :
<div>
<?php
foreach((get_the_category()) as $category){
echo $category->name."<br>";
echo category_description($category);
}
?>
</div>
Update in existing code
<?php $gallery_query = new WP_Query(
array('post_type' => 'stm_media_gallery',
'posts_per_page' => -1) );
if( $gallery_query->have_posts() ) :
while( $gallery_query->have_posts() ) : $gallery_query->the_post();
$gallery_category = get_the_category( get_the_ID() );
the_title( '<h3>', '</h3>' );
echo "<br>";
<?php foreach ( $gallery_category as $key => $value) { echo $value->category_nicename; } ?>
<?php endif; ?>
<?php endwhile; ?>
You can use the pre-made WordPress function the_category( $separator, $parents, $post_id ) to print the post categories as links.
Further information on the WordPress Codex: Function Reference: the_category
Edit: Print only the names:
$categories = get_the_category();
if ( ! empty( $categories ) ) {
echo esc_html( $categories->name );
}
Put this inside While Loop
global $post;
$postcat = get_the_category( $post->ID );

Add a class to the body - PHP Wordpress

I am trying to add a class to the body in a WordPress theme so that when there are no posts on a page it will not show the search bar. I have in my functions.php right now this to look for one certain page, and if there are no posts.
<?php
add_filter( 'body_class', 'custom_class' );
function custom_class( $classes ) {
if(strpos($_SERVER['REQUEST_URI'], 'agent') !== false ){
$classes[] = 'noSearchBar';
}
if(!have_posts() ){
$classes[] = 'noSearchBar';
}
return $classes;
}
?>
Which works for most of the pages, but on some pages it is using a different template so instead of calling the posts with have_posts like this:
<?php
global $wp_query;
if ( have_posts() ) :
while ( have_posts() ) : the_post();
get_template_part('template-parts/property-for-listing');
endwhile;
wp_reset_postdata();
else:
?>
<h4><?php esc_html_e('Sorry No Results Found', 'houzez') ?></h4>
<?php
endif;
?>
Its is bringing it up like this:
<?php
global $wp_query, $paged;
if(!$fave_prop_no){
$posts_per_page = 9;
} else {
$posts_per_page = $fave_prop_no;
}
$latest_listing_args = array(
'post_type' => 'property',
'posts_per_page' => $posts_per_page,
'paged' => $paged,
'post_status' => 'publish'
);
$latest_listing_args = apply_filters( 'houzez_property_filter', $latest_listing_args );
$latest_listing_args = houzez_prop_sort ( $latest_listing_args );
$wp_query = new WP_Query( $latest_listing_args );
if ( $wp_query->have_posts() ) :
while ( $wp_query->have_posts() ) : $wp_query->the_post();
get_template_part('template-parts/property-for-listing');
endwhile;
else:
get_template_part('template-parts/property', 'none');
endif;
?>
Which is making my function not work. There is only 1 line of code in the template-parts/property-none and its just saying the same thing the other files are. So I'm not sure why the other template would not add the body class.
You can do like this example,
<?php
add_filter( 'body_class', 'custom_class' );
function custom_class( $classes ) {
if ( is_single('post') ) {
$classes[] = 'SearchBar';
}else{
$classes[] = 'noSearchBar';
}
return $classes;
}
?>
The following example will work for single post page. For more conditions.visit
Hope this will helps you.

Display all posts whose IDs are passed through url

I want to get all the posts in wordpress whose ids are passed in parameter like
http://localhost/wordpres/?pid=181,109,5,1
My front-page.php have following code
<?php while (have_posts()) : the_post(); ?>
<?php
if ('posts' == get_option('show_on_front')) {
get_template_part('content', 'posts');
} else {
get_template_part('content', 'page');
}
// If comments are open or we have at least one comment, load up the comment template
if (comments_open() || '0' != get_comments_number()) :
comments_template();
endif;
?>
<?php endwhile;} // end of the loop. ?>
And I have tried query_posts('p=181'); with http://localhost/wordpres/?pid=109 for single post; it works fine.
But I can't sort out how to give query_posts multiple post ids which are passed through url. Need help.
You can try this code existing above code to solve your problem.
<?php
$all_posts = sanitize_text_field($_GET['pid']);
if(!empty($all_posts)){
$all_posts = explode(',', $all_posts);
}else{
$all_posts = array();
}
$args = array(
'post_type' => 'post',
'post__in' => $all_posts
);
$the_query = new WP_Query( $args );
// The Loop
if ( $the_query->have_posts() ) {
echo '<ul>';
while ( $the_query->have_posts() ) {
$the_query->the_post();
get_template_part('content', 'posts');
if (comments_open() || '0' != get_comments_number()) :
comments_template();
endif;
}
echo '</ul>';
/* Restore original Post Data */
wp_reset_postdata();
} else {
echo "no posts found";
}
?>
I did it by using following code
$thePostIdArray = explode(',', $_GET['pid']);
$args = array(
'post__in' => $thePostIdArray
);
query_posts($args);?>
<?php while (have_posts()) : the_post(); ?>
<?php
if ('posts' == get_option('show_on_front')) {
get_template_part('content', 'posts');
} else {
get_template_part('content', 'page');
}

Include custom post type in Wordpress loop

Sorry, I think I read every post about this but cant get it to work.
I have a Wordpress custom post typ called "external" and I would like to show both the post from "external" aswell as my normal standard posts at the same time on my homepage.
This is my loop:
<?php
get_header();
if ( get_query_var('paged') ) { $paged = get_query_var('paged'); }
elseif ( get_query_var('page') ) { $paged = get_query_var('page'); }
else { $paged = 1; }?>
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(''); ?>>
<?php the_content(); ?>
</div>
<?php endwhile; wp_reset_postdata(); endif; ?>
How can I include the "external" posts in this code?
The theme then uses blocks to display content on the startpage, here is block8.php with a post query.
function block_eight_ajax_query($atts='') {
$args = array (
$is_ajax = 0;
if($atts==''){
$is_ajax=1;
$atts=$_GET;
if($atts['global_query']){
unset($atts['no_found_rows']);
unset($atts['suppress_filters']);
unset($atts['cache_results']);
unset($atts['update_post_term_cache']);
unset($atts['update_post_meta_cache']);
unset($atts['nopaging']);
}
}
$atts['is_ajax'] = $is_ajax;
$query = null;
$query = new WP_Query( $atts );
$html = '';
if ( $query->have_posts() ) {
ob_start();
$i = 1;
while ( $query->have_posts() ):
$query->the_post();
$atts['video'] = rd_field( 'abomb_post_video' );
$atts['extern'] = rd_field( 'extern' );
$atts['audio'] = rd_field( 'abomb_post_audio' );
$atts['gallery'] = rd_field( 'abomb_post_gallery' );
$atts['counter'] = $i;
block_grid_content($atts);
if ($atts['column'] == 'grid-12') { $divide = 1; }
else if ($atts['column'] == 'grid-3') { $divide = 4; }
else if ($atts['column'] == 'grid-4') { $divide = 3; }
else { $divide = 2; }
if ($i%$divide==0 && $divide!=1) {
echo '<div class="clear"></div>';
}
$i++;
endwhile;
if ($atts['nav'] == 'numbered') {
echo '<div class="grid-12">';
rd_pagination($query->max_num_pages);
echo '</div>';
}
wp_reset_postdata();
$html = ob_get_clean();
if($is_ajax==1){
echo $html;
exit();
}
return $html;
}
else{
if($is_ajax==1){
echo '-11';
exit();
}
return '';
}
}
Update: I added this code to functions:
add_action( 'pre_get_posts', 'add_my_post_types_to_query' );
function add_my_post_types_to_query( $query ) {
if ( $query->is_home() && $query->is_main_query() )
$query->set( 'post_type', array( 'post', 'extern' ) );
return $query;
}
Now I can see the posts in for exampel the search result but I need the Query in Block8.php to fetch them aswell.
I Thanks!
To include a custom post type in the regular loop (ie. posts page) just add the following code to index.php before if ( have_posts() ) :
$args = array(
'post_type' => array('post', 'custom_post_type'),
'post_status' => 'publish',
);
$new_post_loop = new WP_Query( $args );
then modify the following two lines:
if ( have_posts() ) : change it to if ( $new_post_loop -> have_posts() ) :
and
while ( have_posts() ) : the_post(); to while ( $new_post_loop -> have_posts() ) : $new_post_loop -> the_post();
This solution avoids the problem of having the custom post type listed in the all posts screen on the backend, which #David.J's answer produces ;)
Add this to your functions.php file.
/**
* #param WP_Query $query
* #return WP_Query
*/
function add_my_custom_post_type( $query ) {
if ($query->is_main_query())
$query->set( 'post_type', array( 'post', 'external' ) );
return $query;
}
add_action( 'pre_get_posts', 'add_my_custom_post_type' );
Ref & duplicate: https://wordpress.stackexchange.com/questions/27104/how-to-display-regular-posts-custom-post-types-that-fall-under-a-category-usin
function add_my_custom_post_type( $query ) {
if ( ! is_admin() && $query->is_main_query() ) {
if ($query->is_main_query()) {
$query->set( 'post_type', array( 'post', 'some_custom_post_type_name' ) );
}
return $query;
}
}
add_action( 'pre_get_posts', 'add_my_custom_post_type' );
This is the correct way to write the code so as not to break the dashboard queries.

Can't get most recent post from categories

I'm trying to get a category and loop through its sub categories getting one post from each of those sub-categories. Below is my code:
<?
$homepage_cat = get_category_by_slug( 'home-page-slider' );
$id = $homepage_cat->cat_ID;
print($id);
$sub_cat = get_categories('hide_empty=0&child_of=' . $id);
print_r($sub_cat);
foreach ($sub_cat as $key => $cat)
{
echo $cat->term_id;
query_posts('cat=' . $cat->term_id);
if ( have_posts() )
{ echo '<h1> HELL YEAH </h1>';
while ( have_posts() )
{
echo '<h1>' get_the_title(); '</h1>';
} // end while
} // end if
} //end foreach
?>
The code is not returing any posts as HELL YEAH is not being echoed. Can anyone suggest a solution?
Use get_posts() not query_posts, it is better for these kinds of situations.
$args = array('posts_per_page' => 1, 'category' => $cat->term_id);
$posts = get_posts($args);
foreach($posts as $post) : setup_postdata( $post ) ?>
<h1><?php get_the_title(); ?></h1>
<?php endforeach; ?>
There are quite a few problems here
First of all, never use query_posts to construct custom queries. It breaks the main query, is unreliable and outright fails in most cases in pagination
Secondly, you have to reset your postdata after every custom query
Thirdly, never use short tags. Always use full tag ie <?php and not just <?
Lastly, you are missing the_post() which should return post objects
Your query should look something like this
<?php
$homepage_cat = get_category_by_slug( 'home-page-slider' );
$id = $homepage_cat->cat_ID;
print($id);
$sub_cat = get_categories('posts_per_page=1&hide_empty=0&child_of=' . $id);
print_r($sub_cat);
foreach ($sub_cat as $key => $cat)
{
echo $cat->cat_ID;
$q = new WP_Query('cat=' . $cat->cat_ID);
if ( $q->have_posts() )
{ echo '<h1> HELL YEAH </h1>';
while ( $q->have_posts() )
{
$q->the_post();
echo '<h1>' get_the_title(); '</h1>';
} // end while
} // end if
wp_reset_postdata();
} //end foreach
?>
Replace this
$post_args = array(
'showposts' => 1,
'cat' => $cat->term_id
);
with this.
$post_args = array(
'posts_per_page' => 1,
'category' => $cat->term_id
);
I hope it'll work.

Categories