Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Making a subtitle plugin work with all post types WordPress

  • SOLVED

I'm working with a plugin called Subheadings that add subtitle functionality to Pages and Posts. I need to make it work with other/all post types.

Can you walk me through what I need to do to a) modify this to work with other post types; and b) modify the options page to have a checkbox list of post types to choose from?

The main relevant part of the plugin code is below. I've successfully changed 'page' to 'my_other_post_type' in these lines and gotten the plugin to work with another post type (but there could be more to it, so the full code is here: bit.ly/j6wbg2):


function meta()
{
$this->meta_box('page');
if (isset($this->options['posts'])) {
$this->meta_box('post');
}
}
function meta_box($type='page')
{
add_meta_box(
$this->tag.'_postbox',
$this->name, array(&$this, 'panel'),
$type,
'normal',
'high'
);
}

// this part might also be relevant?

if (!current_user_can('edit_'.($_POST['post_type'] == 'page' ? 'page' : 'post'), $post_id)) {
return $post_id;
}



And the relevant part of the plugin settings page is here. (This is the checkbox to enable it for posts.)

<label for="subheading[posts]">
<input name="subheading[posts]" type="checkbox" id="subheading[posts]" value="1" <?php if (array_key_exists('posts', $this->options)) { checked('1', $this->options['posts']); } ?> />
Enable for posts as well as pages.
</label>


Since this is a situation I frequently come across—needing to extend post/page-centric plugins to work with custom post types, I'd also be interested to know if you all have any general tips/rules of thumb about this. I am pretty new to PHP and Wordpress development and want to learn as much as I can.

Answers (3)

2011-05-23

Kailey Lampert answers:

I believe I have worked out a solution for you.

In settings.php, add this at line 44 (this adds the post type choices):
<?php
if (array_key_exists('post_types', $this->options)) { $value = $this->options['post_types']; }
else $value = array();
//print_r(get_option('subheading'));
$pts = get_post_types( array( 'public' => true ) );
echo '<p><label for="fb_like_pts">Show on</label> ';
foreach ($pts as $pt) {
if ('attachment' == $pt) continue;
echo '<label for="subheading[post_types]['.$pt.']">';
echo '<input type="checkbox" id="subheading[post_types]['.$pt.']" name="subheading[post_types][]" value="'.$pt.'" '.(in_array($pt, $value) ? ' checked="checked"' : '').' /> ';
echo $pt.'</label> ';
}
echo '</p>';

?>


Then replace the contents of the meta_box() function (in index.php) with (adds the subheading box to the appropriate pages):

$options = get_option('subheading');
$pts = $options['post_types'];
foreach($pts as $type) {
add_meta_box(
$this->tag.'_postbox',
$this->name, array(&$this, 'panel'),
$type,
'normal',
'high'
);
}

and settings_validate() with this (validates the post type checkboxes):


if (is_array($inputs)) {
foreach ($inputs AS $key => $input) {
if ($key == 'post_types') {
// die(print_r($input,true));
$inputs[$key] = array_map('esc_attr',$input);
}
else if (in_array($key, array('before', 'after'))) {
if (empty($inputs[$key])) {
unset($inputs[$key]);
} else {
$inputs[$key] = format_to_post($inputs[$key]);
}
} else {
$inputs[$key] = ($inputs[$key] == 1 ? 1 : 0);
}
}
return $inputs;
}


I've attached a zip copy in case the above is confusing


web559 comments:

I'm getting this error when I activate the plugin (using your attached zip):
<blockquote>Warning: Invalid argument supplied for foreach() in /home/epi/2.epi-data.org/may10/wp-content/plugins/subheading/index.php on line 95</blockquote>


Kailey Lampert comments:

Should go away after you re-save the settings. Let me know if it doesn't.


web559 comments:

It goes away if one or more post types is checked. It would be nice to prevent the errors in any case, though.

Ok, here's one way of preventing the errors: wrap the foreach($pts as $type){...} loop in if(!empty($pts)) { }. (Idea from http://php.syntaxerrors.info/index.php?title=Invalid_argument_supplied_for_foreach)


web559 comments:

It goes away if one or more post types is checked. It would be nice to prevent the errors in any case, though.

Ok, here's one way of preventing the errors: wrap the foreach($pts as $type){...} loop in if(!empty($pts)) { }. (Idea from http://php.syntaxerrors.info/index.php?title=Invalid_argument_supplied_for_foreach)


Kailey Lampert comments:

The plugin actually has several other errors that show up when WP_DEBUG is true. For my own sanity, I'm working on a clean version. I can share it with you when I'm finished if I get your contact information.


web559 comments:

Do you know how to output the labels of the post types (e.g. Post Type) instead of the database names (post_type)?


Kailey Lampert comments:

In settings.php, replace


$pts = get_post_types( array( 'public' => true ) );

echo '<p><label for="fb_like_pts">Show on</label> ';

foreach ($pts as $pt) {

if ('attachment' == $pt) continue;

echo '<label for="subheading[post_types]['.$pt.']">';

echo '<input type="checkbox" id="subheading[post_types]['.$pt.']" name="subheading[post_types][]" value="'.$pt.'" '.(in_array($pt, $value) ? ' checked="checked"' : '').' /> ';

echo $pt.'</label> ';

}

echo '</p>';


with this:

$post_types = get_post_types( array( 'public' => true ), 'objects' );
echo '<p>Show on ';
foreach ($post_types as $slug => $obj) {
if ('attachment' == $slug) continue;
echo '<label for="subheading[post_types]['.$slug.']">';
echo '<input type="checkbox" id="subheading[post_types]['.$slug.']" name="subheading[post_types][]" value="'.$slug.'" '.(in_array($slug, $value) ? ' checked="checked"' : '').' /> ';
echo $obj->labels->name.'</label> ';
}
echo '</p>';


web559 comments:

Great, thank you. Now how do I select you as the winner? When I click "Assign prize money" it takes me to a page that talks about voting for the winner. Or is everything done by vote now?


Kailey Lampert comments:

Looks like the voting bit is an experiment: [[LINK href="http://codewi.se/2011/04/22/voting-assign-prize-money/"]]http://codewi.se/2011/04/22/voting-assign-prize-money/[[/LINK]]


Kailey Lampert comments:

I guess you will need to vote for a winner using the Assign Prize Money link.

The post I linked (found in the footer of this site) indicates voting as an experiment - but there's another post that suggests [[LINK href="http://codewi.se/2011/04/22/experimental-week/"]]it's official now[[/LINK]].

2011-05-24

Denzel Chia answers:

Hi,


<blockquote>Can you walk me through what I need to do to a) modify this to work with other post types; and b) modify the options page to have a checkbox list of post types to choose from?
</blockquote>

Did you write this codes yourself or did you get it from somewhere?

for your function settings_page() within your SubHeading class, there is an include once settings.php
It seems to me that this settings.php is the file that provides the option inputs. So you need to provide this file for experts here to modify or add in code, so that you can have a checkbox list of post types to choose from.

If it is codes from a plugin or a tutorial, it is easier if you tell us where to get it.
So that we can modify it to suit your requirements (a) and (b).

Thanks.
Denzel

2011-05-24

Duncan O'Neill answers:

This code is working for me on my local test-site. The only file you need to edit is /subheading/index.php.

Replace ( best to just comment it out in the first instance ) the contents of function meta() with the following ( at line 84 in my version );


$postTypes = get_post_types();
foreach ($postTypes as $pT){
$this->meta_box($pT);
}


So that the entire function now reads;


function meta()
{
//$this->meta_box('page');
//if (isset($this->options['posts'])) {
// $this->meta_box('post');
//}
$postTypes = get_post_types();
foreach ($postTypes as $pT){
$this->meta_box($pT);
}
}


Please let me know if this works.

best,

Duncan