So this is a zany thing that I'm attempting to do, but what I am trying to achieve is querying out some info in WordPress with categories. If a post comes back with a parent category, then echo that out with the child category with a | seperator. If no parent category then just echo out the category.
Here's what I'm trying so far:
<?php
$categories = get_the_category();
$catName = $categories[0]->name;
$catParent = get_cat_name($categories[0]->category_parent);
if($catParent) {
$fullCat = $catParent '|' $catName;
} else {
$fullCat = $catName;
echo $fullCat;
?>
I know this is incorrect, but basically, I'm trying to wrap my head around how to accomplish this. I'm not sure how to combine two variables to use one and then add the separator within the two.
Was also wondering if maybe a ternary operator might be better here too? That was more of thought than anything and probably not that necessary to make this work correctly.
You're wanting to check if $catParent is empty so you can use the empty() function to do that check for you. Quick edit...you need periods (.) in between things you are concatenating.
Link to the docs.
if(empty($catParent)) {
$fullCat = $catParent . '|' . $catName;
} else {
$fullCat = $catName;
}
You must use '.' to concat.
Example:
$fullCat = $catParent. ' | '. $catName;
You can use . (Concatenation) operator to achieve this. Look at the code below.
<?php
$categories = get_the_category();
$catName = $categories[0]->name;
$catParent = get_cat_name($categories[0]->category_parent);
if($catParent) {
$fullCat = $catParent . '|' . $catName;
} else {
$fullCat = $catName;
echo $fullCat;
?>
Related
Can anyone help me create a shortcode such as the one below by using a foreach loop?
The purpose of this shortcode is to generate a playlist, and uses opening and closing tags:
[zoomsounds id="favorites_playlist"] [/zoomsounds]
In between those tags, each song that is to be added to the playlist gets its own shortcode, like this:
[zoomsounds_player config="favorites-playlist" source="'.$source.'" type="detect" songname="'.$title.'" init_player="off" play_target="footer"]
So let's say a user has 2 songs in their playlist, the entire shortcode would look something like this:
[zoomsounds id="favorites_playlist"][zoomsounds_player config="favorites-playlist" source="http://www.test.com/sound/brobob.mp3" type="detect" songname="Song 1" init_player="off" play_target="footer"][zoomsounds_player config="favorites-playlist" source="http://www.test.com/sound/brobob2.mp3" type="detect" songname="Song 2" init_player="off" play_target="footer"][/zoomsounds]
As you can see, each song's shortcode comes one after another, enclosed in the start/close tags.
The easiest way I thought I could do this was to use a foreach loop to generate each song's shortcode. Here is the simple function I wrote.
function streamFavoritesPlaylist() {
$favs[] = get_user_favorites();
echo do_shortcode('[zoomsounds id="favorites_playlist"]');
foreach ($favs[0] as $fav) {
$title = get_the_title($fav);
$post = get_post($fav);
$post_slug = $post->post_name;
$source = '.../mp3/'.$post_slug.'.mp3';
$song_name = get_the_title($fav);
echo do_shortcode('[zoomsounds_player config="favorites-playlist" source="'.$source.'" type="detect" songname="'.$title.'" init_player="off" play_target="footer"]');
}
echo do_shortcode('[/zoomsounds]');
}
And this is the result that I get.
Clearly this is the wrong way to go about doing something like this. Not to mention, the closing tag did not take, and instead has been displayed in text. Perhaps this is why the entire thing is not working?
I should mention that by using the entire shortcode on it's own works fine. It's only when I try to build the shortcode in this manner does it not work.
How would you suggest I go about accomplishing something like this? Thanks a lot.
UPDATE:
Thanks for everyone's input. This is what I came up with, which is similar to what #DACrosby posted, and #TheManiac suggested.
function streamFavoritesPlaylist() {
$favs[] = get_user_favorites();
$shortcode_full = "";
foreach ($favs[0] as $fav) {
$title = get_the_title($fav);
$post = get_post($fav);
$post_slug = $post->post_name;
$source = '.../mp3/'.$post_slug.'.mp3';
$song_name = get_the_title($fav);
$shortcode = '[zoomsounds_player config="favorites-playlist" source="'.$source.'" type="detect" songname="'.$title.'" init_player="off" play_target="footer"]';
$shortcode_full .= $shortcode;
}
return '[zoomsounds id="favorites_playlist"]'.$shortcode_full.'[/zoomsounds]';
}
And where I actually need the shortcode generated, I am using:
<?php echo do_shortcode(streamFavoritesPlaylist()); ?>
It's working perfectly. Thanks again, community.
It's probably not working because [/zoomsounds] isn't a shortcode - it's the closing tag of one. So running the first [zoomsounds ...] and the closing [/zoomsounds] separately doesn't work as expected. Like TheManiac mentioned in a comment, try building the string first then having just one do_shortcode
function streamFavoritesPlaylist() {
$favs[] = get_user_favorites();
$str = '[zoomsounds id="favorites_playlist"]';
foreach ($favs[0] as $fav) {
$title = get_the_title($fav);
$post = get_post($fav);
$post_slug = $post->post_name;
$source = '.../mp3/'.$post_slug.'.mp3';
$song_name = get_the_title($fav);
$str .= '[zoomsounds_player config="favorites-playlist"'
. ' source="'.$source.'" type="detect"'
. ' songname="'.$title.'" init_player="off"'
. ' play_target="footer"]';
}
$str .= '[/zoomsounds]';
echo do_shortcode( $str );
}
Just took your sample code with a simple for loop to print out the result, and it works.
It seems to be some of the string values contains special characters (e.g.: / ' "")
You could check the string values or use some sample code below to test the method.
echo do_shortcode('[zoomsounds id="favorites_playlist"]');
for($i = 0; $i < 5; $i++){
$title = "FAV ".$i;
$post = "FAV ".$i;
$post_slug = "FAV ".$i;
$source = "FAV ".$i;
$song_name = "FAV ".$i;
echo do_shortcode('[zoomsounds_player config="favorites-playlist" source="'.$source.'" type="detect" songname="'.$title.'" init_player="off" play_target="footer"]');
}
echo do_shortcode('[/zoomsounds]');
And the print out:
results
Hope this would help.
This script displays the categories of a post, but excludes the ones that the user doesn't want to show:
function exclude_post_categories($excl='', $spacer=' ') {
$categories = get_the_category($post->ID);
if (!empty($categories)) {
$exclude = $excl;
$exclude = explode(",", $exclude);
$thecount = count(get_the_category()) - count($exclude);
foreach ($categories as $cat) {
$html = '';
if (!in_array($cat->cat_ID, $exclude)) {
$html .= '<a href="' . get_category_link($cat->cat_ID) . '" ';
$html .= 'title="' . $cat->cat_name . '">' . $cat->cat_name . '</a>';
if ($thecount > 1) {
$html .= $spacer;
}
$thecount--;
echo $html;
}
}
}
}
The fuctions is triggered like this.
<?php exclude_post_categories('5', ', ');
So if a post has the categories: 1,2,3,4,5 than only 1,2,3,4 are echoed.
The script works great for the posts that have the category that is excluded (5).
The problem lies with the posts that don't have that category.
So if a post has the categories: 1,2,3,4 that those are echoed but with less commas than needed: 1,2,34
$thecount variable is always calculated wrong for the posts that don't have the category that has to be excluded.
Try something like this:
$existing = get_the_category();
$newcategories = array_udiff($existing,$exclude,function($e,$x) {
return $e->cat_ID != $x;
});
$as_links = array_map(function($c) {
return '<a href="'.get_category_link($c->cat_ID).'" '
.'title="'.$cat->cat_name.'">'.$cat->cat_name.'</a>';
},$newcategories);
echo implode($spacer, $as_links);
This will first strip out categories whose IDs are in the $exclude array, then convert each category to a category link, before outputting them with the separator.
EDIT: Slightly mis-read the question. This expects $exclude to be an array. Put the following line at the start:
if( !is_array($exclude)) $exclude = array($exclude);
To make it support single-value inputs as well - this way you can either specify one or many categories to exclude.
Found a better solution to the problem here: http://css-tricks.com/snippets/wordpress/the_category-excludes/#comment-1583708
function exclude_post_categories($exclude="",$spacer=" ",$id=false){
//allow for specifiying id in case we
//want to use the function to bring in
//another pages categories
if(!$id){
$id = get_the_ID();
}
//get the categories
$categories = get_the_category($id);
//split the exclude string into an array
$exclude = explode(",",$exclude);
//define array for storing results
$result = array();
//loop the cats
foreach($categories as $cat){
if(!in_array($cat->cat_ID,$exclude)){
$result[] = "$cat->name";
}
}
//add the spacer
$result = implode($spacer,$result);
//print out the result
echo $result;
}
I'm am working on a Wordpress custom template and I'm filtering post by their classes.
Since Wordpress displays a LOT of unnecessary classes when I put <?php post_class(); ?> in a page, ( here is what it gives me class="post-54 post type-post status-publish format-standard hentry category-3d category-web" )
I'm trying to simplify that by echoing only the categories that relate to the post.
EDIT: This is what calls the post in my page <?php query_posts( 'showposts=99' ); ?>
Then this piece of code
<li class="<?php if ( in_category('category-3d')) { echo "3d"; }
if ( in_category('category-animation')) { echo "animation"; }
if ( in_category('category-motion')) { echo "motion"; }
if ( in_category('category-shortfilm')) { echo "shortfilm"; }?>"></li>
give me this <li class="motion"></li> if my post is in the "motion" category.
The problem is that if my post is in several categories, only the first is echoed... How can I tell WP to echo ALL the names of the categories my post is affected to, while adding a space between them?
Since I am a beginner in php syntax, I'm still learning how to get such a simple thing working in a clean and effective way (i.e. without writing 16 lines of code !)...
Can someone help me on this one?
SECOND EDIT:
Ok I'm still trying to figure out why, but today, my piece of code (above) is working and echoes all my listed classes, but without space between them... So to make my classes work, I'm adding a space at the end of the echo part like this { echo "3d "; }. But I feel like it's a dirty way to make things work...
How to add a space between each class tag in the proper way? I'm aiming for something like this foreach $categories as $cat { echo $cat . " "; } but where $categories and $cat would refer to each "if" statement.
I'm not familiar with WP but if you get your categories with some function like get_categories() then you can use implode to make a string from all categories.
<?php $categories = get_categories(); ?>
<?php $categories = implode(' ', $categories); ?>
<li class="<?php echo $categories; ?>">...</li>
Could you provide what is returning get_categories()?
EDIT:
function get_class_attr() {
$classes = get_post_class();
$classes = substr($classes, 7, -1);
$arr = array();
$arr = explode(' ', $classes);
$classes = 'class="';
foreach($arr as $class_name) {
if(strpos($class_name, 'category-') !== false) {
$classes .= substr($class_name, 9).' ';
}
}
$classes = substr_replace($classes, '"', -1, 1);
echo $classes;
}
get_class_attr(); // output: class="3d web"
Also note that 3d is not a valid class name, you can use something like movie3d or film3d.
Alternative way is to create your class value a little bit earlier and then echo it:
<?php
$classes = array();
if ( in_category('category-3d')) { $classes[] = "3d"; }
if ( in_category('category-animation')) { $classes[] = "animation"; }
if ( in_category('category-motion')) { $classes[] = "motion"; }
if ( in_category('category-shortfilm')) { $classes[] = "shortfilm";}
if(count($classes)) {
$classes = implode(' ', $classes);
} else {
$classes = '';
}
?>
<li class="<?php $classes ?>"></li>
As of the code you've posted, it should add all the categories if the product is in all the four specified ones. You could add the space between the quotes after each echo, e.g.: echo ' motion'.
I would use another approach, adding really all categories, without the need to check them by name:
<li class="<?php echo implode( ' ', get_categories() ); ?>"> … </li>
See: http://codex.wordpress.org/Function_Reference/get_categories on how to filter the output of the function get_categories().
I would suggest instead you use this function from the Wordpress API - something you should read a lot of.
Something like this should work:
<?php $categories = get_categories(); ?>
<li class="<?php foreach ($categories as $cat) {
echo $cat . " ";
}?>"> -- Your li text --
</li>
I am currently designing a website which uses this: <li class="current">.
I have gotten a script to detect when it's on said page to output the right class, however, when on the gallery.php?dir=thedir page, it fails to output the class!
Here's what I have so far, which is not working...
$ispage = preg_match_all('gallery.php/\[(.+?)\]/s');
I would appreciate any information somebody could give me :).
Full code:
<?php
$ispage = preg_match_all('gallery.php/\[(.+?)\]/s');
$currentpage = $_SERVER['REQUEST_URI'];
if ($ispage==$currentpage) {
echo '<li class="current">';
} else {
echo '<li>';
}
?>Photos</li>
Can't you use $_SERVER['SCRIPT_NAME'] or $_SERVER['PHP_SELF'] or $_SERVER['REQUEST_URI'] along with php function strpos($haystack, $findme)? It should make your life easy.
http://php.net/manual/en/function.strpos.php
It seems like $_SERVER['PHP_SELF'] is the one you need, it return the relative filename, without params.
Have a look here : http://www.php.net/manual/en/reserved.variables.server.php
If I understood your question you are trying to access query string values
Try echo $_GET['dir'];
EDIT
Tried this?
$ispage = '/'.basename($_SERVER['PHP_SELF']).'?'.($_SERVER['QUERY_STRING']);
$curepage = $_SERVER['REQUEST_URI'];
I think you need to define an array of links to solve your problem
so that
$curpage = $_SERVER['REQUEST_URI'];
$links = array('/gallery.php?dir=thedir', '/home.php?dir=anotherdir');
foreach($links as $link) {
$class = '';
if($link == $curpage) {
$class = 'class="current"';
echo '<li '.$class.'>';
.... rest of the code ....
}
}
<?php
$currentpage = $_SERVER['REQUEST_URI'];;
preg_match('/[^.]+\.[^.]+$/', $currentpage, $matches);
if ($matches[0] == "/gallery.php?dir=thedir") {
echo '<li class="current">';
} else {
echo '<li>';
}
?>Photos</li>
if a URL is something like: www.site.com/page.php?q=foo
then this
$currentpage = basename(__FILE__);
will just give you page.php
In addition, if you call it this way:
$currentpage = basename(__FILE__,".php");
will give you page
I'm pretty sure preg_match_all returns an int. If this is full code it won't be working at all. And yes, use something like $_SERVER['PHP_SELF']. Also you should think about using some better url to avoid this.
I'm working on a wordpress theme and I'm trying to call the parent category's name to pull the appropriate page template.
I can get the call function to echo the correct name, but when I try to nest it the function doesn't run. I saw that I needed to use { } since I was already inside php but it still isn't working right. Can someone straighten me out?
This gives the correct output:
<?php $category = get_the_category();
$parent = get_cat_name($category[0]->category_parent);
if (!empty($parent)) {
echo '' . $parent;
} else {
echo '' . $category[0]->cat_name;
}
?>
. . . so I created a category_parent.php file with that in it.
This is what I'm trying to nest it in:
<?php get_template_part( ' ' ); ?>
Like this:
1.
<?php get_template_part( '<?php get_template_part( 'category_parent' ); ?>' ); ?>
or this
2.
<?php get_template_part( '{get_template_part( 'category_parent' ); }' ); ?>
Neither one works.
I really don't know if this is what you want as I did not try to make sense of what you are doing. However, generally speaking, you do this:
<?php get_template_part( get_template_part( 'category_parent' ) ); ?>
Edit:
I looked up what get_template_part() does in WP, and I think Felix Kling's answer is what you need. There is a big difference between sending something to the screen and assigning it to a variable.
<?php
echo 'filename';
?>
If you include that file, you will see filename in the browser. PHP knows nothing about it. (Okay, it could if you made use of output buffering functions, but that's besides the point...)
However if you do something like:
<?php
$x = 'filename';
?>
You can now use it in your function:
<?php
get_template_part($x);
?>
So what Felix is telling you to do is to put the logic that you currently have into a function. In this example:
<?php
function foo()
{
return 'filename';
}
get_template_part(foo());
?>
Now whatever value foo() returns will be sent to your get_template_part().
Taking your code:
$category = get_the_category();
$parent = get_cat_name($category[0]->category_parent);
if (!empty($parent)) {
$name = $parent;
} else {
$name = $category[0]->cat_name;
}
get_template_part($name);
You could take Felix's answer and put it into a file called category_parent.php, and then use it like:
require_once 'category_parent.php'
get_template_part(getName());
Honestly I am not so familiar with Wordpress, but it seems to me, you could do:
function getName() {
$category = get_the_category();
$parent = get_cat_name($category[0]->category_parent);
if (!empty($parent)) {
return '' . $parent;
} else {
return '' . $category[0]->cat_name;
}
}
get_template_part(getName());
konforce is correct about the syntax and, like konforce, I have no idea what you are trying to do. You do not need to use { } because your are not trying to dynamically name a variable and you certainly don't need to escape to php using <?php ?>, as (1) you are already in php and (2) it will stop interpreting PHP and assume html the second it hits the first '?>'.
There is no special syntax for nesting functions. Simply:
get_template_part(get_template_part('category_parent'));
is the syntax, but I have no idea what the function is or does, so I have no idea if that will work.
To debug, why don't you try this:
$parent = get_template_part('category_parent');
echo 'parent: ' . $parent . '<br />';
$result = get_template_part($parent);
echo 'result: ' . $result . '<br />';
When using variables in php strings, you will need to use double quotes ("). I assume option 2 should work then.