Loading Hasty Logo
Blog
Show your WordPress pages as a select option in a metabox field
Quick Tips
18. December 2017
timelapseEstimated reading time:

Show your WordPress pages as a select option in a metabox field

You want a user to select a page or post, in a field of a metabox you created with Hasty

With this simple function a WordPress user, which has the capability to edit pages or posts, can select a page in a metabox via a select input. The select input shows all pages of the site and saves the ID of the page if selected. This page ID can be retrieved on the selected page, post or custom post type.

class selectapageMetabox {
	private $screen = array(
		'post',
		'page',
	);
	private $meta_fields = array(
		array(
			'label' => 'Select Pages',
			'id' => 'selectpages_26854',
			'type' => 'selectpages',
		),
	);
	public function __construct() {
		add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
		add_action( 'save_post', array( $this, 'save_fields' ) );
	}
	public function add_meta_boxes() {
		foreach ( $this->screen as $single_screen ) {
			add_meta_box(
				'selectapage',
				__( 'Select a Page', 'textdomain' ),
				array( $this, 'meta_box_callback' ),
				$single_screen,
				'advanced',
				'default'
			);
		}
	}
	public function meta_box_callback( $post ) {
		wp_nonce_field( 'selectapage_data', 'selectapage_nonce' );
		$this->field_generator( $post );
	}
	public function field_generator( $post ) {
		$output = '';
		foreach ( $this->meta_fields as $meta_field ) {
			$label = '<label for="' . $meta_field['id'] . '">' . $meta_field['label'] . '</label>';
			$meta_value = get_post_meta( $post->ID, $meta_field['id'], true );
			if ( empty( $meta_value ) ) {
				$meta_value = $meta_field['default']; }
			switch ( $meta_field['type'] ) {
				case 'selectpages':
					$input = sprintf(
						'<select id="%s" name="%s">',
						$meta_field['id'],
						$meta_field['id']
					);
					$pages_array = array();
					$args = array(
						'post_type' => 'page',
						'post_status' => 'publish'
					); 
					$pages = get_pages($args);

					foreach ( $pages as $page ) {
						$meta_field_value = $page->ID;
						$input .= sprintf(
							'<option %s value="%s">%s</option>',
							$meta_value == $meta_field_value ? 'selected' : '',
							$meta_field_value,
							$page->post_title
						);
					}
					$input .= '</select>';
					break;
				default:
					$input = sprintf(
						'<input %s id="%s" name="%s" type="%s" value="%s">',
						$meta_field['type'] !== 'color' ? 'style="width: 100%"' : '',
						$meta_field['id'],
						$meta_field['id'],
						$meta_field['type'],
						$meta_value
					);
			}
			$output .= $this->format_rows( $label, $input );
		}
		echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
	}
	public function format_rows( $label, $input ) {
		return '<tr><th>'.$label.'</th><td>'.$input.'</td></tr>';
	}
	public function save_fields( $post_id ) {
		if ( ! isset( $_POST['selectapage_nonce'] ) )
			return $post_id;
		$nonce = $_POST['selectapage_nonce'];
		if ( !wp_verify_nonce( $nonce, 'selectapage_data' ) )
			return $post_id;
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
			return $post_id;
		foreach ( $this->meta_fields as $meta_field ) {
			if ( isset( $_POST[ $meta_field['id'] ] ) ) {
				switch ( $meta_field['type'] ) {
					case 'email':
						$_POST[ $meta_field['id'] ] = sanitize_email( $_POST[ $meta_field['id'] ] );
						break;
					case 'text':
						$_POST[ $meta_field['id'] ] = sanitize_text_field( $_POST[ $meta_field['id'] ] );
						break;
				}
				update_post_meta( $post_id, $meta_field['id'], $_POST[ $meta_field['id'] ] );
			} else if ( $meta_field['type'] === 'checkbox' ) {
				update_post_meta( $post_id, $meta_field['id'], '0' );
			}
		}
	}
}
if (class_exists('selectapageMetabox')) {
	new selectapageMetabox;
};
Copy to clipboard
Put this code somewhere in your functions

The ID of the selected page can be outputted with the following function:

get_post_meta( get_the_ID(), 'selectpages_26854', true );
Copy to clipboard