WordPress breadcrumbs in search results - php

In WordPress i'm currently using Yoast's SEO Plugin to display breadcrumbs for my pages and posts, which is working fine when visiting a specific page.
Here is the function i'm using to display the breadcrumbs inside of my WordPress templates:
<?php if ( function_exists('yoast_breadcrumb') ) {
yoast_breadcrumb('<p id="breadcrumbs">','</p>');
} ?>
For example when browsing to Team Members which is a child of About Us I get:
Home > About Us > Team Members
However i'd like to be able to display the same breadcrumbs (for the individual pages and posts) inside the search results loop.
So far what displays when searching for Members is:
Your Search Results:
Team Members
Home > Search > Members
Members Area
Home > Search > Members
But I don't want breadcrumbs for the Search Results page, I want them for the individual pages and posts that are displayed as a result of searching for a keyword.
For example Imagine I searched again for Members I would like displayed the below:
Your Search Results:
Team Members
Home > About Us > Team Members
Members Area
Home > Members Area
I'm not fussed if this is or isn't integrated with the SEO plugin, however thus far it's the best solution I found to display breadcrumbs in WordPress!
Also incase abody requires it, here is my search.php file: http://pastebin.com/0qjb2954

Try this. That's my own working snippet that shows breadcrumbs inside search loop.
/*Begin Loop */
<?php
echo '<div class="b-search_result_list__item_breadcrumbs breadcrumbs">';
$current_type = get_post_type();
if ($current_type == 'page') {
$parents = get_post_ancestors(get_the_ID());
if($parents){
for($i=count($parents)-1;$i>=0;$i--){
echo '<span typeof="v:Breadcrumb">';
echo '<a rel="v:url" property="v:title" title="'.get_the_title($parents[$i]).'" href="'.get_permalink($parents[$i]).'">'.get_the_title($parents[$i]).'</a>';
echo '</span>';
}
}else{
echo '<span typeof="v:Breadcrumb">';
echo '<a rel="v:url" property="v:title" title="'.get_bloginfo('name').'" href="'.get_bloginfo('url').'">'.get_bloginfo('name').'</a>';
echo '</span>';
}
echo '<span typeof="v:Breadcrumb">';
echo '<span property="v:title">'.get_the_title().'</span>';
echo '</span>';
}else{
$current_obj = get_post_type_object($current_type);
echo '<span typeof="v:Breadcrumb">';
echo '<a rel="v:url" property="v:title" title="'.get_bloginfo('name').'" href="'.get_bloginfo('url').'">'.get_bloginfo('name').'</a>';
echo '</span>';
echo '<span typeof="v:Breadcrumb">';
echo '<a rel="v:url" property="v:title" title="'.$current_obj->labels->name.'" href="'.get_post_type_archive_link( $current_type ).'">'.$current_obj->labels->name.'</a>';
echo '</span>';
$current_taxonomies = get_object_taxonomies($current_type);
if($current_taxonomies){
$current_terms = get_the_terms(get_the_ID(), $current_taxonomies[0]);
if($current_terms){
$current_term = array_shift($current_terms);
echo '<span typeof="v:Breadcrumb">';
echo '<a rel="v:url" property="v:title" title="'.$current_term->name.'" href="'.get_term_link($current_term).'">'.$current_term->name.'</a>';
echo '</span>';
/*
var_dump($current_obj->labels->name); // Archive name
var_dump(get_post_type_archive_link( $current_type )); // Archive link
var_dump($current_term->name); // Term name
var_dump(get_term_link($current_term)); // Term link
var_dump(get_permalink()); // Post link
*/
}
}
echo '<span typeof="v:Breadcrumb">';
echo '<span property="v:title">'.get_the_title().'</span>';
echo '</span>';
}
echo '</div>';
?>
/*End Loop*/

try adding this line of code above the yoast breadcrumb function in your search.php file:
WPSEO_Breadcrumbs::$instance = NULL;
This would be line 22 I believe, and also make sure to use the Yoast breadcrumb function from your question, not the new breadcrumb() function that's there now.
Please let me know if this works!
Full explanation:
The Yoast plugin breadcrumbs functionality is build on the page load, based on the current page as the child. To make it load the right child and parents, you'd need to reset it before you run the function. There is no built-in reset function, however setting the static $instance to NULL should cause the plugin to re-generate its data based on the current global post object which is set while you're looping.

Building upon Yavor's answer I found a way. Been banging my head about it for hours. You can place the backup and restore otuside of the loop though. Here it is:
global $wp_query;
//backup
$old_singular_value = $wp_query->is_singular;
//change
$wp_query->is_singular = true;
//reset
WPSEO_Breadcrumbs::$instance = NULL;
//breadcrumbs
if (function_exists('yoast_breadcrumb')){
yoast_breadcrumb('<p id="breadcrumbs">','</p>');
}
//restore
$wp_query->is_singular = $old_singular_value;
It fakes the query to make it singular so the newly-refreshed breadcrumbs thinks that this is not the search page but a single post or page or whatever you are displaying as your search results.

Using a plugin to generate breadcrumbs is not really necessary. Here's a simple PHP function you can add to your functions.php file:
function breadcrumbs() {
global $post;
echo "<ul id='breadcrumbs'>";
if (!is_home()) {
echo '<li>Home</li>';
if (is_category() || is_single()) {
echo "<li>" . the_category(' </li><li> ');
if (is_single()) {
echo "</li><li>" . the_title() . "</li>";
}
} elseif (is_page()) {
if($post->post_parent){
foreach ( get_post_ancestors( $post->ID ) as $ancestor ) {
echo '<li>' . get_the_title($ancestor) . '</li>' . get_the_title();
}
} else {
echo "<li>" . get_the_title() . "</li>";
}
}
} elseif (is_tag()) {
single_tag_title();
} elseif (is_day()) {
echo "<li>Archive for " . the_time('F jS, Y') . "</li>";
} elseif (is_month()) {
echo "<li>Archive for " . the_time('F, Y') . "</li>";
} elseif (is_year()) {
echo "<li>Archive for " . the_time('Y') . "</li>";
} elseif (is_author()) {
echo "<li>Author Archive</li>";
} elseif (isset($_GET['paged']) && !empty($_GET['paged'])) {
echo "<li>Blog Archives</li>";
} elseif (is_search()) {
echo "<li>Search Results for" . the_search_query() . "</li>";
}
echo "</ul>";
}
along with some CSS to style it, customize as you desire
#breadcrumbs {
list-style:none;
margin:5px 0;
overflow:hidden;
}
#breadcrumbs li{
float:left;
}
#breadcrumbs li+li:before {
content: '| ';
padding:0 4px;
}
You can then implement those breadcrumbs on any page you like, including your searchpage.php file or whichever file you use to display search results with this call
<?php breadcrumbs(); ?>

The search pages have a conditional function that can be used. You could always apply that to loading the breadcrumbs. Here is an example:
if ( ! is_search() ) {
if ( function_exists('yoast_breadcrumb') ) {
yoast_breadcrumb('<p id="breadcrumbs">','</p>');
}
}
It depends where you are loading the breadcrumbs as well, but this should typically work unless your theme is very unique.

Related

Wordpress - PHP : Hide subcategories when no subcategory

Before I start, I'm asking for your help because I have very basic html and css skills, and absolutely no php knowledge !
I wanted to display the subcategories on category.php template, below the caterogy title and description. I found a code on stackoverflow which works perfectly (to which I added a div class) :
<div class="sub-cat-inline"><?php
// if the page visitor views is a category page
if (is_category())
{
$cur_cat = get_query_var('cat');
if ($cur_cat)
{
$new_cats = wp_list_categories('echo=false&child_of=' . $cur_cat . '&depth=1&title_li=&hide_empty=0');
echo '<ul>' . $new_cats . '</ul>';
}
}
?>
</div>
However, when charging a page of a category or subcategory not containing any subcategory, there is this text being displayed : "No category".
In the php code above, is it possible to hide any text when there is no subcategory ? Thanks a lot
If anyone interested, below is the basic css used to style the div :
.sub-cat-inline li {
width: 100%;
display: inline;
padding: 10px;
}
.sub-cat-inline {
text-align: center;
}
You can use the hide_if_empty parameter to exclude from the list those categories that don't have posts attached to them:
<?php
<div class="sub-cat-inline"><?php
// if the page visitor views is a category page
if (is_category())
{
$cur_cat = get_query_var('cat');
if ($cur_cat)
{
$new_cats = wp_list_categories('echo=false&child_of=' . $cur_cat . '&depth=1&title_li=&hide_empty=1');
echo '<ul>' . $new_cats . '</ul>';
}
}
?>
</div>
Also, if no categories are found the wp_list_categories() function will return a 'No categories' text (as you already noticed).
To change what the function returns when no categories are found, you can use the show_option_none parameter:
<?php
<div class="sub-cat-inline"><?php
// if the page visitor views is a category page
if (is_category())
{
$cur_cat = get_query_var('cat');
if ($cur_cat)
{
$new_cats = wp_list_categories('echo=false&child_of=' . $cur_cat . '&depth=1&title_li=&hide_empty=1&show_option_none= ');
echo '<ul>' . $new_cats . '</ul>';
}
}
?>
</div>
You can just use it like this:
<div class="sub-cat-inline"><?php
// if the page visitor views is a category page
if (is_category())
{
$cur_cat = get_query_var('cat');
if ($cur_cat)
{
$new_cats = wp_list_categories('echo=false&child_of=' . $cur_cat . '&depth=1&title_li=&hide_empty=0');
if(!empty($new_cats)){
echo '<ul>' . $new_cats . '</ul>';
}
}
}
?>
</div>
There is a workaround using css, as the "No category" text is linked to a css property by default : cat-item-none
Using display: none; hides that text, but I'm sure there is a way to prevent that text from being displayed with the php code, right ?
I tried changing the value hide_empty=0 to hide_empty=1 but it doesn't do anything... Any idea ?
<div class="sub-cat-inline"><?php
// if the page visitor views is a category page
if (is_category())
{
$cur_cat = get_query_var('cat');
if ($cur_cat)
{
$new_cats = wp_list_categories('echo=false&child_of=' . $cur_cat . '&depth=1&title_li=&hide_empty=0');
echo '<ul>' . $new_cats . '</ul>';
}
}
?>
</div>

wrapping Wordpress text content in div

I have an Wordpress site using bootstrap framework. I have content (written in the admin posts panel) which contains images and text. I am trying to wrap the text content in row and col-md-10 tags (and leaving the images alone)
It is brought into my single.php page
<?php the_content(); ?>
I have tried playing around with preg_replace to the effect of
<?php
$content = preg_replace('/<row>(.*?)<\/row>/', '', get_the_content());
$content = wpautop($content);
echo $content;
?>
Try this piece of code. You will have to put it in your functions.php. What it does is that it searches for all the images and then wraps the content in divs leaving images intact. I have tested it. And it is working fine even if you have no images.
function sr_wrap_content_in_div( $content )
{
$contents = explode("<img", $content);
foreach($contents as $content)
{
$before_tag = strstr($content, '/>', true);
$after_tag = strstr($content, '/>');
if( $before_tag == '' && $after_tag == '' )
{
echo '<div class="row"><div class="col-md-10">'; // change it later if you need to
echo $content;
echo '</div></div>';
} else if( $after_tag == '/> ' )
{
echo '<img';
echo $before_tag;
echo '/>';
} else
{
echo '<img';
echo $before_tag;
echo '/>';
echo '<div class="row"><div class="col-md-10">'; // change here too.
echo substr($after_tag, 2);
echo '</div></div>';
}
}
}
add_filter( 'the_content', 'sr_wrap_content_in_div' );

Wordpress if condition is or has_tag

I'm trying to make an if condition if there's a tag then echo it if not just show the archive title.
$title_before = '<h1 class="archive_header">';
$title_after = '</h1>';
if(is_tag('tag_description')){
echo '<div class="archive_desc">';
echo tag_description();
echo '</div>';
echo '<div class="archive_border"></div>';
} else {
woo_archive_title( $title_before, $title_after );
}
I tried the code above and the tag description is not showing, though I'm not entirely sure if is_tag covers tag_description.
The is_tag function checks if a tag archive page is being displayed.
Is that what you want?
Found my way now, I wanted !empty. So if there is no tag/archive description it only shows the title, then if exist it shows both.
$tag_description = tag_description();
woo_archive_title( $title_before, $title_after );
if(!empty($tag_description)){
echo '<div class="archive_desc">' .$tag_description. '</div>';
echo '<div class="archive_border"></div>';
} else {
//
}
Now I need to do the styling.

Displaying HTML based on the selection

I'm doing this PHP tutorial on OOP and I'm trying to incorporate the procedural code from the essential training into it, to see if I actually learned anything beyond the basics, and I got stuck, big time.
So, I have these two functions inside the class I named Blog:
public function navigation($selected_subject, $selected_page) {
$output = "<ul class=\"subjects\" id=\"accordion\">";
$subject_set = $this->get_all_subjects($public);
while ($subject = mysqli_fetch_array($subject_set)) {
$output .= "<li";
if ($subject["id"] == $selected_subject['id']) { $output .= " class=\"blogselected\""; }
$output .= ">{$subject["menu_name"]}</li>";
$page_set = $this->get_pages_for_subject($subject["id"], $public);
$output .= "<ul class=\"pages\">";
while ($page = mysqli_fetch_array($page_set)) {
$output .= "<li";
if ($page['id'] == $selected_page['id'] ) { $output .= " class=\"blogselected\""; }
$output .= "><a href=\"../public/blog_index.php?page=" . urlencode($page["id"]) .
"\">{$page["menu_name"]}</a></li>";
}
$output .= "</ul>";
}
$output .= "</ul>";
return $output;
}
public function blog_page($selected_page){
if ($selected_page) {
echo "<h2>" . $selected_page['menu_name'] . "</h2>";
echo "<div class=\"page-content\">";
echo $selected_page['content'];
echo "</div>";
} else {
echo "<h2>Welcome to Widget Corp</h2>";
}
}
and this piece of code on the index page:
<?php
$blog = new Blog;
global $selected_page;
global $selected_subject;
?>
<div class="blog">
<div class="blogpost">
<?php echo $blog->blog_page($selected_page); ?>
</div>
<div class="blognav">
<?php echo $blog->navigation($selected_subject, $selected_page); ?>
</div>
</div>
The code partially works. The navigation with subjects and sub-pages gets displayed fine, when the links are clicked the id "?page=1" is passed to the url, but the problem is that the code is not adding a class "blogselected" to the active links, and it also does not display the content when the links are clicked. The only thing that gets displayed in the content area is the h2 "Welcome to Widget Corp" from else condition in the second function, so I believe the variables $selected_subject and $selected_page might be causing the problem, but I just can't figure it out on my own. I spent countless hours trying to solve this and I'm on the brink of giving up completely. What exactly am I missing here?

$post->post_parent behaves different on page then in functions.php

I created/modified a function to display breadcrumbs on pages on WordPress. The modified version makes use of #post->post_parent to get the parent of a page in order to have a full breadcrumb trail (home > page 1 > page 2 > page 3 vs. home > page 3)
The code executes perfectly on page (ie. home > page 1 > page 2 > page 3). But when I place it into a function and call it form the functions.php page it cannot detect if the page has a parent using $post->post_parent (ie. page 3 vs. home > page 3).
Could this be because the on page code is executed in the_loop but the function is somehow outside of it?
On page code:
if (!is_home()) {
echo "<ul id='breadcrumb'>";
echo '<li><a href="';
echo get_option('home');
echo '">HOME';
echo "</a></li>";
if (is_category() || is_single()) {
the_category('title_li=');
if (is_single()) {
the_title('<li>', '</li>');
echo "</ul>";
}
} elseif (is_page()) {
if(!$post->post_parent){
//echo "No Parent";
}
else{
echo '<li>'. wp_list_pages('include='.$post->post_parent.'&title_li=' ).'</li>';
}
the_title('<li>', '</li>');
echo "</ul>";
}
}
Function code:
function the_breadcrumb() {
if (!is_home()) {
echo "<ul id='breadcrumb'>";
echo '<li><a href="';
echo get_option('home');
echo '">HOME';
echo "</a></li>";
if (is_category() || is_single()) {
the_category('title_li=');
if (is_single()) {
the_title('<li>', '</li>');
echo "</ul>";
}
} elseif (is_page()) {
if(!$post->post_parent){
//echo "No Parent";
}
else{
echo '<li>'. wp_list_pages('include='.$post->post_parent.'&title_li=' ).'</li>';
}
the_title('<li>', '</li>');
echo "</ul>";
}
}
}
There is nothing inherently different about this code except that it is now wrapped in a function. The fact that it doesn't display the parent pages is frustrating. I don't want to have to include this code on every page template I create.
Help & Suggestions will be greatly appreciated!
$post ist not defined in your function. Try to give $post as parameter to the function:
function the_breadcrumb($post) {
Or, define
global $post;
at the top of the function.
function fname()
{
global $post;
code...
}

Categories