WordPress Plugin WP Sub Post
WP Sub Post is a wordpress plugin that allow you to make your wordpress post has a parent or child post.
Notes:
- Child post is a real post that has a parent.
- Child post only displayed on it's parent post page or when parent page is displayed.
- Child post can not be viewed individually.
- Child post has all possibility like a normal post, such as attachment, custom fields etc.
Features:
- Add/edit parent post directly from your post area.
- No need to edit theme file.
Limitations:
- No setting page
- I don't know about it's compatibility.
Bugs:
- Not compatible with my syntax highlight plugin

Screenshot
Plugin page:
New/Edit post page:
View Single Post:
RSS:
Code:
Here is the code of this plugins... Hahaha.. little bit messy
WP Sub Post
WP Sub Post
<?php</p>
/*
Plugin Name: WP Sub Post
Plugin URI: http://wordpress.org/#
Description: You can make a post is a child of another post.
Author: Takien
Version: 0.1 Alpha
Author URI: http://takien.com
*/
////////////////////////////
class Walker_PostDropdown extends Walker {
var $tree_type = 'post';
var $db_fields = array ('parent' => 'post_parent', 'id' => 'ID');
function start_el(&$output, $page, $depth, $args) {
$pad = str_repeat(' ', $depth * 3);
$output .= "\tID\"";
if ( $page->ID == $args['selected'] )
$output .= ' selected="selected"';
$output .= '>';
$title = esc_html($page->post_title);
$output .= "$pad$title";
$output .= "\n";
}
}
/////////////
function &wp_get_posts($args = '') {
global $wpdb;
$defaults = array(
'child_of' => 0, 'sort_order' => 'ASC',
'sort_column' => 'post_title', 'hierarchical' => 1,
'exclude' => '', 'include' => '',
'meta_key' => '', 'meta_value' => '',
'authors' => '', 'parent' => -1, 'exclude_tree' => '',
'number' => '', 'offset' => 0
);
$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );
$number = (int) $number;
$offset = (int) $offset;
$cache = array();
$key = md5( serialize( compact(array_keys($defaults)) ) );
if ( $cache = wp_cache_get( 'wp_get_posts', 'posts' ) ) {
if ( is_array($cache) && isset( $cache[ $key ] ) ) {
$pages = apply_filters('wp_get_posts', $cache[ $key ], $r );
return $pages;
}
}
if ( !is_array($cache) )
$cache = array();
$inclusions = '';
if ( !empty($include) ) {
$child_of = 0; //ignore child_of, parent, exclude, meta_key, and meta_value params if using include
$parent = -1;
$exclude = '';
$meta_key = '';
$meta_value = '';
$hierarchical = false;
$incpages = preg_split('/[\s,]+/',$include);
if ( count($incpages) ) {
foreach ( $incpages as $incpage ) {
if (empty($inclusions))
$inclusions = $wpdb->prepare(' AND ( ID = %d ', $incpage);
else
$inclusions .= $wpdb->prepare(' OR ID = %d ', $incpage);
}
}
}
if (!empty($inclusions))
$inclusions .= ')';
$exclusions = '';
if ( !empty($exclude) ) {
$expages = preg_split('/[\s,]+/',$exclude);
if ( count($expages) ) {
foreach ( $expages as $expage ) {
if (empty($exclusions))
$exclusions = $wpdb->prepare(' AND ( ID <> %d ', $expage);
else
$exclusions .= $wpdb->prepare(' AND ID <> %d ', $expage);
}
}
}
if (!empty($exclusions))
$exclusions .= ')';
$author_query = '';
if (!empty($authors)) {
$post_authors = preg_split('/[\s,]+/',$authors);
if ( count($post_authors) ) {
foreach ( $post_authors as $post_author ) {
//Do we have an author id or an author login?
if ( 0 == intval($post_author) ) {
$post_author = get_userdatabylogin($post_author);
if ( empty($post_author) )
continue;
if ( empty($post_author->ID) )
continue;
$post_author = $post_author->ID;
}
if ( '' == $author_query )
$author_query = $wpdb->prepare(' post_author = %d ', $post_author);
else
$author_query .= $wpdb->prepare(' OR post_author = %d ', $post_author);
}
if ( '' != $author_query )
$author_query = " AND ($author_query)";
}
}
$join = '';
$where = "$exclusions $inclusions ";
if ( ! empty( $meta_key ) || ! empty( $meta_value ) ) {
$join = " LEFT JOIN $wpdb->postmeta ON ( $wpdb->posts.ID = $wpdb->postmeta.post_id )";
// meta_key and meta_value might be slashed
$meta_key = stripslashes($meta_key);
$meta_value = stripslashes($meta_value);
if ( ! empty( $meta_key ) )
$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_key = %s", $meta_key);
if ( ! empty( $meta_value ) )
$where .= $wpdb->prepare(" AND $wpdb->postmeta.meta_value = %s", $meta_value);
}
if ( $parent >= 0 )
$where .= $wpdb->prepare(' AND post_parent = %d ', $parent);
$query = "SELECT * FROM $wpdb->posts $join WHERE (post_type = 'post' AND post_status = 'publish') $where ";
$query .= $author_query;
$query .= " ORDER BY " . $sort_column . " " . $sort_order ;
if ( !empty($number) )
$query .= ' LIMIT ' . $offset . ',' . $number;
$pages = $wpdb->get_results($query);
if ( empty($pages) ) {
$pages = apply_filters('wp_get_posts', array(), $r);
return $pages;
}
// Sanitize before caching so it'll only get done once
$num_pages = count($pages);
for ($i = 0; $i < $num_pages; $i++) {
$pages[$i] = sanitize_post($pages[$i], 'raw');
}
// Update cache.
update_page_cache($pages);
if ( $child_of || $hierarchical )
$pages = & get_page_children($child_of, $pages);
if ( !empty($exclude_tree) ) {
$exclude = (int) $exclude_tree;
$children = get_page_children($exclude, $pages);
$excludes = array();
foreach ( $children as $child )
$excludes[] = $child->ID;
$excludes[] = $exclude;
$num_pages = count($pages);
for ( $i = 0; $i < $num_pages; $i++ ) {
if ( in_array($pages[$i]->ID, $excludes) )
unset($pages[$i]);
}
}
$cache[ $key ] = $pages;
wp_cache_set( 'wp_get_posts', $cache, 'posts' );
$pages = apply_filters('wp_get_posts', $pages, $r);
return $pages;
}
//////////////
function walk_post_dropdown_tree() {
$args = func_get_args();
if ( empty($args[2]['walker']) ) // the user's options are the third parameter
$walker = new Walker_PostDropdown;
else
$walker = $args[2]['walker'];
return call_user_func_array(array(&$walker, 'walk'), $args);
}
function wp_dropdown_posts($args = '') {
$defaults = array(
'depth' => 0, 'child_of' => 0,
'selected' => 0, 'echo' => 1,
'name' => 'page_id', 'show_option_none' => '', 'show_option_no_change' => '',
'option_none_value' => ''
);
$r = wp_parse_args( $args, $defaults );
extract( $r, EXTR_SKIP );
$pages = wp_get_posts($r);
$output = '';
$name = esc_attr($name);
if ( ! empty($pages) ) {
$output = "
<select id=""$name\"" name="\"$name\"">
<option value="\"-1\"">$show_option_no_change</option>
<option value="\""">$show_option_none</option>
\n";
}
$output = apply_filters('wp_dropdown_pages', $output);
if ( $echo )
echo $output;
return $output;
}
/////////////////////////////
/* Use the admin_menu action to define the custom boxes */
add_action('admin_menu', 'myplugin_add_custom_box');
/* Use the save_post action to do something with the data entered */
add_action('save_post', 'myplugin_save_postdata');
/* Adds a custom section to the "advanced" Post and Page edit screens */
function myplugin_add_custom_box() {
if( function_exists( 'add_meta_box' )) {
add_meta_box( 'myplugin_sectionid', __( 'WP Sub Posts', 'myplugin_textdomain' ), 'myplugin_inner_custom_box', 'post', 'side','high' );
//add_meta_box( $id, $title, $callback, $page, $context, $priority );
add_meta_box( 'myplugin_sectionid', __( 'WP Sub Posts', 'myplugin_textdomain' ), 'myplugin_inner_custom_box', 'page', 'advanced' );
} else {
add_action('dbx_post_advanced', 'myplugin_old_custom_box' );
add_action('dbx_page_advanced', 'myplugin_old_custom_box' );
}
}
function myplugin_inner_custom_box() {
echo '
<style type="text/css">
select#parent_id, select#parent_id option {
width:250px;
}
</style>
';
echo '
<input id="myplugin_noncename" name="myplugin_noncename" type="hidden" value="' .
wp_create_nonce( plugin_basename(__FILE__) ) . '" />'; ?>
<h5><?php _e('Parent') ?></h5>
<label for="post_parent">Please select the parent of this post</label>
<?php
$currentid = $_GET['post'];
wp_dropdown_posts(array('exclude_tree' => $currentid,
'selected' => $post->post_parent,
'name' => 'parent_id',
'show_option_none' => __('Main Post (no parent)'),
'sort_column' => 'menu_order, post_title'));
}
/* Prints the edit form for pre-WordPress 2.5 post/page */
function myplugin_old_custom_box() {
echo '
<div class="dbx-b-ox-wrapper">' . "\n";
echo '
<fieldset id="myplugin_fieldsetid" class="dbx-box">' . "\n";
echo '
<div class="dbx-h-andle-wrapper">
<h3 class="dbx-handle">' .
__( 'WP Sub Posts', 'myplugin_textdomain' ) . "</h3>
</div>
";
echo '
<div class="dbx-c-ontent-wrapper">
<div class="dbx-content">';
// output editing form
myplugin_inner_custom_box();
// end wrapper
echo "</div>
</div>
</fieldset>
</div>
\n";
}
/* When the post is saved, saves our custom data */
function myplugin_save_postdata( $post_id ) {
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['myplugin_noncename'], plugin_basename(__FILE__) )) {
return $post_id;
}
// verify if this is an auto save routine. If it is our form has not been submitted, so we dont want
// to do anything
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
return $post_id;
// Check permissions
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ) )
return $post_id;
} else {
if ( !current_user_can( 'edit_post', $post_id ) )
return $post_id;
}
// OK, we're authenticated: we need to find and save the data
$mydata = $_POST['parent_id'];
return $mydata;
}
add_filter('posts_where','where_no_parent');
add_filter ('the_content','subpost_template', 1, 2 );
function subpost_template($content) {
if(is_singular) {
remove_filter('posts_where','where_no_parent');
}
echo $content;
$idnya = get_the_ID();
$child = new WP_Query("post_type=post&post_parent=".$idnya."");
while($child->have_posts()) : $child->the_post();
echo '
<blockquote>
';
echo '
<h3>';
the_title();
echo '</h3>
';
$childid = get_the_ID();
the_content();
edit_post_link('Edit','','',$childid);
echo '</blockquote>
';
endwhile;
wp_reset_query();
}
function where_no_parent($where) {
global $wpdb;
$where .= " AND post_parent = 0";
return $where;
}
?>
?> subpost_template()
subpost_template()
<?php
if(is_singular()) {
remove_filter('posts_where','where_no_parent');
}
$parentID = get_the_ID();
$childposts = get_posts(array(
'post_type' => 'post',
'numberposts' => -1,
'post_status' => 'publish',
'post_parent' => $parentID
));
$subcontent = "";
foreach($childposts as $childpost){
$subcontent .= "
<blockquote>
";
$subcontent .= "
<h3>".$childpost->post_title."</h3>
";
$subcontent .= $childpost->post_content;
$subcontent .= '
<a rel="nofollow" href="'.get_edit_post_link($childpost->ID).'">Edit</a>
';
$subcontent .= "</blockquote>
";
}
$content .= $subcontent;
return $content;
}
<p>?> WP Dropdown Post
wp_dropdown_posts()
<?php</p>
$currentid = $_GET['post'];
wp_dropdown_posts(array('exclude_tree' => $currentid,
'selected' => $post->post_parent,
'name' => 'parent_id',
'show_option_none' => __('Main Post (no parent)'),
'sort_column' => 'menu_order, post_title'));
<p>?> You can download alpha version of this plugin here http://cektkp.com/wpsubpost
If it not working please Click here
This plugin is Alpha version, use it for testing purpose only. Any problem caused by this plugin is not my responsibility.
Demo:
See below:
Code Update WP Sub Post
There are some changes to the WP Sub Post:
- Fixed/Added, now child post can be viewed as a single post, with link to the Parent Post instead of displaying blank post with 'Post not found' title.
- Added, CSS class and id to the blockquote of the child post. It would be useful to make a link like http://example.com/parentpost.html#childpostXXX. while XXX is your child post ID.
Two functions that are changed subpost_template() and where_no_parent()
WP Sub Post
<?php
function subpost_template($content) {
global $post;
$parentID = get_the_ID();
$childposts = get_posts(array(
'post_type' => 'post',
'numberposts' => -1,
'post_status' => 'publish',
'post_parent' => $parentID
));
$subcontent = "";
foreach($childposts as $childpost){
$subcontent .= "
<blockquote class=\"sub_post\" id=\"subpost_".$childpost->ID."\">";
$subcontent .= "
<h3>".$childpost->post_title."</h3>
";
$subcontent .= $childpost->post_content;
$subcontent .= '
<p class="postmetadata"><small>This sub post was added on: '.date('l, dS F, Y',strtotime($childpost->post_date)).' <a href="'.get_edit_post_link($childpost->ID).'" rel="nofollow">Edit</a></small>
';
$subcontent .= "</blockquote>
";
}
if($post->post_parent !== 0) {
$parent_info = '
<blockquote>This post is a child post of <strong>'.get_the_title($post->post_parent).'</strong>. To view the parent post, please <a href="'.get_permalink($post->post_parent).'">click here.</a></blockquote>
';
$content = $parent_info.$content;
}
$content .= $subcontent;
return $content;
}
function where_no_parent($where) {
global $wpdb;
if(!is_single()) {
$where .= " AND post_parent = 0";
}
else {
$where .= " AND post_type = 'post'";
}
return $where;
}
<p>?>
Finally you can see the demo here
Yesterday, I was failed to add a demo directly in this site because of incompatibility with smart tags (all smart tags are not working when WP Sub Post is activated).
The problem comes from my old stupid function
subpost_template():DThanks and sorry to polvocdo
, actually your revision is the answer.
Ha ha I'm forget to replace mine with your revision :hammer: ....
This is a child post
This is an individual post (http://takien.com/536/this-is-a-child-post.php) that attached to the another post ( http://takien.com/550/wordpress-plugin-wp-sub-post.php)
Child post could be useful when you want to add an additional information to the main post, news analysis, or update. Instead of editing the main post, you can now simply Add New post and mark it as child post.
Child post also has it's own functionality, can handle attachment, displaying image. etc.
But you can't see this post in the post editing page (wp-admin/edit.php) because of filter in the plugin to prevent child post to be displayed individually in the main page, post listing, feed, etc. Hahaha.. don't worry, I will fix it soon.
Incoming search terms:
- WP Sub post
- wordpress sub posts
- sub post wordpress
- wordpress sub post
- wordpress subpost
- wp_dropdown_posts
- wordpress post parent plugin
- wordpress sub-posts
- wordpress subposts
- wordpress child post
See Also
Tags: child post, Wordpress, wordpress plugins, wordpress sub post






WordPress Plugin WP Sub Post
bagus bang nih,cocok buat situs berita.
Lanjutkan, walau sudah 100 hari berlalu ...
LAnjutkan ...
wah, keren euy. ide plugin yg keren dan kalau udah stabil bakal killer. Pasti banyak yang akan butuh untuk mindahkan ke kanan dan kekiri post child mereka.
hehe maskasih mas uwiuw,
mudah2an ada waktu untuk ngutak-atik lagi
Child post can not be viewed individually.?? I still can see it individually. A bug maybe.
sorry.. the code is still confusing me..
udah di tes untuk 3.0 ?
udah bro, no problemo
This is a great idea - however, I have it installed on WordPress 3.0. When you give a post a "parent," the post itself disappears from the list of posts (in the admin area, under "Posts>Posts") to be edited or deleted in the future. So far, the only way I've found to get to a child post to be edited is to view the source code of the parent post editing screen, find the child page in the dropdown (the value is the post ID) and change the post ID in the "edit" screen to the child's value that I found by viewing the source code.
I've managed ot mess with the plugin a bit to add a secondary section in the parent page to show a list of that posts' children, but that's all it does. So far, I can't get it to *ink* to the actual child page so if you select it, it'll move to that child page's edit screen.
I know this is in alpha, but I thought I'd let you know.
I just installed the plugin on a new pages, plugin seam to work with out any problem, i although have the following questions.
1. is there any way to awoid that pictures overlap the next sub post, this seams to happen if you dont have enoug text in the sub post. (like with your monkey picture above)
Morten
Thanks Morten,
I think your problem is only about CSS.
Ok, then i will see if i can find some help solving that issue (:
please give me your links here
Hi Takien,
i solved it by making sure i have enought text which is ok solution for me now, i am quite happy with the result here http://www.medulin-croatia.com/apartments-accommodation-for-4-6-persons-medulin/
One improvment could be not having to forward the subpost to the main post, the sub post occur in related post and gives a 404 if you havent redirected them.
Morten
Actually i have fix this problem and updated my code.
Please refer to my sub post above Code Update WP Sub Post
to to make sub post redirected to the parent post,
please edit this line
<?php
$parent_info = '<blockquote>This post is a child post of <strong>'.get_the_title($post->post_parent).'</strong>. To view the parent post, please <a href="'.get_permalink($post- rel="nofollow">post_parent).'">click here.</a></blockquote>';
?>
and replace with your own Redirection code (e.g. HTML redirection)
BTW, your site is nice
Thanks, i will try to fix it
Morten