Ok, this is really bugging me! I wrote a function (well, modified a very similar one from the wordpress codex) which lists all child pages and the parent page whenever the page has children or is a child. That bit works fine, but what I want to do now is have it look in a custom field (add-to-nav) which has the path to another page to add to the end of the list. It checks the page and parent for that custom field.
It seems to be echoing all the right details but for some reason won't add the page to the list. Would really appreciate any help!
function add_sec_nav_w_extras(){
global $post;
global $wpdb;
$key = 'add-to-nav';
$addition = get_post_meta($post->ID, $key, TRUE);
if($addition == '') {$addition = get_post_meta($post->post_parent, $key, TRUE);}
if($addition != '') {
$addition_page = get_page_by_path($addition);
}
echo("Addition page: ".$addition_page->post_title."<br/>Addition ID: ".$addition_page->ID."<br/>Current: ".$post->ID."<br/>Parent: ".$post->post_parent);
?><section id="secondnav_w_parent" class="fix"><ul><?php
if($post->post_parent != "0") { // If post has parent, list that parent and all its children
wp_list_pages( array('title_li'=>'','include'=>$post->post_parent) );
wp_list_pages( array('title_li'=>'','depth'=>1,'child_of'=>$post->post_parent) );
if($addition_page != ''){
wp_list_pages( array('title_li'=>'','include'=>$addition_page->ID) );
}
}
else if(get_pages('child_of='.$post->ID)) { // If post is a parent, list itself and all children
wp_list_pages( array('title_li'=>'','include'=>$post->ID) );
wp_list_pages( array('title_li'=>'','depth'=>1,'child_of'=>$post->ID) );
if($addition_page != ''){
wp_list_pages( array('title_li'=>'','include'=>$addition_page->ID) );
}
}
?></ul></section><?php
}
EDIT:
Ok, so now I know why it's not showing up... I told it not to! I'm using the exclude pages plugin so that the page doesn't show up in the primary nav, and that apparently affects anything that uses wp_list_pages. So now I need to find a way to force it in there... Any thoughts?
EDIT2:
Have now disables the exclude pages plugin and using a custom menu for the primary nav. Bit of a pain but I guess not too bad. If anyone's got a better suggestion let me know!
Related
I am creating my own plugin in Wordpress. With register_post_type I can view my own posts. I also created a post status with register_post_status. When I go to the summary page I can see all posts and filter on the status.
The "problem": When I go to the summary page, I can see all posts and the filters. The "All" status is always selected on default, but I want to select my custom status on default. Is this possible? Or change the URL in the menu to post_status=&post_type= ? I am talking about the admin side.
Hope someone can help me, because I can't figure it out.
I have fixed it with this code - it changes the url in the menu:
add_action( 'admin_menu', 'wpse_admin_menu', 100 );
function wpse_admin_menu()
{
global $menu, $submenu;
$parent = 'parent';
if( !isset($submenu[$parent]) )
return;
foreach( $submenu[$parent] as $k => $d ){
if( $d[0] == 'name' )
{
$submenu[$parent][$k][2] = 'edit.php?post_status=status&post_type=type';
break;
}
}
}
I am creating a site using WordPress using a theme which has this PHP at the top of each page and I am confused as to what it does.
<?php
global $post;
global $wp_query;
if ( $post->post_parent != 0 ) {
$thePostID = $post->post_parent;
} else {
$thePostID = $wp_query->post->ID;
};
?>
I was just wondering if anyone could explain exactly what this does? I think it checks to see if the post_parent id is 0 which isn’t allowed in WordPress and sets the post id to the post_parent but I’m not 100% sure.
I think it checks to see if the post_parent id is 0 which isn’t allowed in WordPress
The $post->post_parent is allowed to be 0. If the value is 0, it simply means that the page is a top level page.
A page that has a $post->post_parent other than 0, is a child of another page.
For example, take this page structure as an example:
id page_title post_parent
1 Home 0
2 About 0
3 Staff 2
4 History 2
5 Contact 0
The resulting page/menu structure would be:
Home
About
Staff
History
Contact
The code in question:
if ($post->post_parent != 0) {
$thePostID = $post->post_parent;
} else {
$thePostID = $wp_query->post->ID;
}
I'm not sure why your theme might have the code, but a possible reason might be to get a menu related to the current page. If you're viewing the top level page (i.e. $post->post_parent == 0), then it would show all child pages, or if you're viewing a sub page, the menu might show all sibling pages.
A sample menu generated using this method
Add this to your functions.php file so it's accessible throughout the theme.
/**
* Get top parent for the current page
*
* If the page is the highest level page, it will return its own ID, or
* if the page has parent(s) it will get the highest level page ID.
*
* #return integer
*/
function get_top_parent_page_id() {
global $post;
$ancestors = $post->ancestors;
// Check if the page is a child page (any level)
if ($ancestors) {
// Get the ID of top-level page from the tree
return end($ancestors);
} else {
// The page is the top level, so use its own ID
return $post->ID;
}
}
Add this code to your theme where you want to display a menu. You will need to customise it to suit your particular needs, but it gives you an example of why someone might use the code you asked about.
// Get the highest level page ID
$top_page_id = get_top_parent_page_id();
// Display basic menu for child or sibling pages
$args = array(
'depth' => 1,
'title_li' => FALSE,
'sort_column' => 'menu_order, post_title',
'child_of' => $top_page_id
);
echo wp_list_pages($args);
So as far as i see, this snippet does the following:
Loads the global post object.
Loads the global query object.
Checks (or tries to check) if the current post has a parent filter (?).
If it has, it sets the variable $thePostID to the id of the post_parent parameter of the current post object.
If it hasnt, it sets the post id in the wp_query to the id of the current post.
All together, this seems very unnecessary, bad performing and strange Oo.
Does ist work actually? ^^
I would advise you on using another theme if possible ;-)
I would like to add a new column in the back-end table for Product Categories. This column will contain a link "view category" and will link all to the www.domain.com/category/category-name page.
I looked into the Wordpress docs and this is the code I came up with... but it doesn't work!
function product_cat_cpt_columns($columns) {
$new_columns = array(
'Link' => "Link to page"
);
return array_merge($columns, $new_columns);
}
add_filter('manage_product_cat_posts_custom_columns' , 'product_cat_cpt_columns');
Any idea how I would do this? I really appreciate your help!
I found it suprisingly hard to find a solution for such a trivial task and I'm very thankful to Helgatheviking for her answer that pointed me to the right direction. Her answer didn't quite work for me, because it would allow only the same value for all the column values, so I decided to post an improved version here.
The problem was with the second function, because it didn't provide a way to add field's value that is corresponding to the current category. I've dug through Woocommerce's source (there you could search for "product_cat_column" to go through relevant parts and see how it's made) and found out that this filter accepts 3 paramaters, not 1. That allows for a specific value per row, not the same value for all rows, as it is in Helgatheviking's answer.
Another drawback was that it would put the value to the thumbnail's column, because that is what Woocommerce use this filter for, actually.
So here's my code:
function add_custom_column($columns) {
$columns['foo'] = 'FOO';
$columns['link'] = 'Link to page';
return $columns;
}
add_filter('manage_edit-product_cat_columns', 'add_custom_column');
function category_custom_column_value( $columns, $column, $term_id ) {
if ($column == 'FOO') {
$foo = get_term_meta( $term_id, 'foo', true );
return $foo;
}elseif ($column == 'link') {
$category = get_term_by( 'id', $term_id, 'product_cat' );
$category_link = get_term_link( $category->slug, 'product_cat' );
return '' . $category_link . '';
}
}
add_filter('manage_product_cat_custom_column', 'category_custom_column_value', 10, 3);
As you can see, the first function stays the same, but the second now checks for the column name and returns the content depending on this name. You can get any category meta this way and do it for as many columns as you'd like.
Pulling from this answer you can add columns to the Edit Tags screen with the following code:
function add_post_tag_columns($columns){
$columns['foo'] = 'Foo';
return $columns;
}
add_filter('manage_edit-product_cat_columns', 'add_post_tag_columns');
function add_post_tag_column_content($content){
$content .= 'Bar';
return $content;
}
add_filter('manage_product_cat_custom_column', 'add_post_tag_column_content');
Is it possible to check if a page is a parent or if it's a child page?
I have my pages set up like this:
-- Parent
---- Child page 1
---- Child page 2
etc.
I want to show a certain menu if it's a parent page and a different menu if it's on the child page.
I know I can do something like below but I want to make it a bit more dynamic without including specific page ID's.
<?php
if ($post->post_parent == '100') { // if current page is child of page with page ID 100
// show image X
}
?>
You can test if the post is a subpage like this:
*(from http://codex.wordpress.org/Conditional_Tags)*
<?php
global $post; // if outside the loop
if ( is_page() && $post->post_parent ) {
// This is a subpage
} else {
// This is not a subpage
}
?>
Put this function in the functions.php file of your theme.
function is_page_child($pid) {// $pid = The ID of the page we're looking for pages underneath
global $post; // load details about this page
$anc = get_post_ancestors( $post->ID );
foreach($anc as $ancestor) {
if(is_page() && $ancestor == $pid) {
return true;
}
}
if(is_page()&&(is_page($pid)))
return true; // we're at the page or at a sub page
else
return false; // we're elsewhere
};
Then you can use it:
<?php
if(is_page_child(100)) {
// show image X
}
?>
I know this is an old question but I was searching for this same question and couldn't find a clear and simple answer until I came up with this one. My answer doesn't answer his explanation but it answers the main question which is what I was looking for.
This checks whether a page is a child or a parent and allows you to show, for example a sidebar menu, only on pages that are either a child or a parent and not on pages that do not have a parent nor children.
<?php
global $post;
$children = get_pages( array( 'child_of' => $post->ID ) );
if ( is_page() && ($post->post_parent || count( $children ) > 0 )) :
?>
For Wordpress, you can simply check:
<?php
if (wp_get_post_parent_id(get_the_ID())) {
echo "I am a child page";
}
?>
You can use the get_pages() function. it takes an associative array as an argument. you can give that array 'child_of' => get_the_ID() to get the children of the current page, and if it hasn't any children the whole get_pages() function will return false, otherwise it will return a value that evaluates to true, which can be assigned to a variable to use as a conditional in an if statement.
$iAmParent = get_pages(array('child_of' => get_the_ID()));
I run a multiple author website. I want to restrict a few tags from being selected by my authors.
The only options that I found so far was techniques to replace the free tag text field with a list (similar to the category list). This is not a solution for me as I will need my authors to be able to create new tags.
Surely there must be a way to restrict specific tags from non-admins? Do you know how? Any brainstorming or proper solutions are welcome.
I think the ideal solution would be to conditionally filter the taxonomy query used in post_tags_meta_box as it ajaxes its suggestions, and maybe even providing some error-handling if someone tried to manually type the tag you don't want them to use, but I'm not aware of a filter that could aid in pulling that off.
Expanding on Giordano's suggestion and referencing this other question, you could use something like this in functions.php
add_action('save_post', 'remove_tags_function', 10, 1); //whenever a post is saved, run the below function
function remove_tags_function( $post_id ){
if(!current_user_can('manage_options')){ // if the logged in user cannot manage options (only admin can)
$post_tags = wp_get_post_terms( $post_id, 'post_tag', array( 'fields'=>'names' ) ); //grab all assigned post tags
$pos = array_search( 'tag-to-be-deleted', $post_tags ); //check for the prohibited tag
if( false !== $pos ) { //if found
unset( $post_tags[$pos] ); //unset the tag
wp_set_post_terms ($post_id, $post_tags, 'post_tag'); //override the posts tags with all prior tags, excluding the tag we just unset
}
}//end if. If the current user CAN manage options, the above lines will be skipped, and the tag will remain
}
Non-admin users will still be able to type in and add tag-to-be-deleted, but it will not stick to the post. Once saved, the tag will be stripped. If the user is really dedicated, they could spell it differently, or, as you saw, change the capitalization, but whatever they do it wont technically be the same tag, and you will be able to keep it pure for whatever theme purpose you need. I can't imagine a situation in which a user without admin capabilities could add the forbidden tag, but I know better than to never say never.
If you want to allow certain non-admin users to assign the forbidden tag to a post, you'll have to revise the parameter passed into line 4 if(!current_user_can('...'){. For information on other capabilities you can pass to this conditional statement, check the Wordpress documentation of Roles & Capabilities. It's much easier to check for a capability than a role, so pick a logical capability that is restricted to the levels of user that you wish to be exempt from the tag deletion.
You could probably create a simple plugin that deletes the specified tags from the post when saved if the author is not you.
You can call your function when the post is saved with add_action('save_post', 'remove_tags_function',10,2);
Then you would create a function like
function remove_tags_function($postID, $post){
if($parent_id = wp_is_post_revision($postID))
{
$postID = $parent_id;
$post = get_post($postID);
}
if($post->post_author != 'YOUR AUTHOR NUMBER'){
$tags = wp_get_post_tags( $post_id );
$i = 0;
foreach($tags as $tag){
if(in_array("TAG NAME", $tag)) unset $tags[$i];
$i++;
}
}}
I have not tested it, but logically it would work.
EDIT:
That's not gonna work!
Try to put the following in a .php file in your plugin folder. Not tested for now, but it looks fine.
<?php
add_action('save_post', 'remove_tags_function',10,2);
function remove_tags_function($postID, $post){
if($parent_id = wp_is_post_revision($postID))
{
$postID = $parent_id;
$post = get_post($postID);
}
$user_info = $user_info = get_userdata($post->post_author);
if($user_info->user_level != 10){ // 10 = admin
untag_post($postID, array('TAGS', ... ));
}}
function untag_post($post_ids, $tags) {
global $wpdb;
if(! is_array($post_ids) ) {
$post_ids = array($post_ids);
}
if(! is_array($tags) ) {
$tags = array($tags);
}
foreach($post_ids as $post_id) {
$terms = wp_get_object_terms($post_id, 'post_tag');
$newterms = array();
foreach($terms as $term) {
if ( !in_array($term->name,$tags) ) { //$term will be a wordpress Term object.
$newterms[] = $term;
}
}
wp_set_object_terms($post_id, $newterms, 'post_tag', FALSE);
}
} // I got this from http://wordpress.stackexchange.com/questions/49248/remove-tags-from-posts-in-php/49256#49256
?>
based on crowjonah's wonderful answer, here is a function to remove multiple tags:
<?php
/** block non-admins from using specific post tags **/
function remove_tags_function( $post_id ){
if(!current_user_can('manage_options')){ // if the logged in user cannot manage options (only admin can)
$post_tags = wp_get_post_terms( $post_id, 'post_tag', array( 'fields'=>'names' ) ); //grab all assigned post tags
$pos = array_intersect( array('TAG1', 'TAG2', 'TAG3', 'ETC...'), $post_tags ); //check for the prohibited tag
if( !empty($pos) ) { //if found
$post_tags = array_diff($post_tags, $pos);
wp_set_post_terms ($post_id, $post_tags, 'post_tag'); //override the posts tags with all prior tags, excluding the tag we just unset
}
}//end if. If the current user CAN manage options, the above lines will be skipped, and the tag will remain
}
add_action('save_post', 'remove_tags_function', 10, 1); //whenever a post is saved, run the below function
?>
Itamar