Skip to content

Instantly share code, notes, and snippets.

@taniarascia
Last active February 13, 2024 07:51
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save taniarascia/9edee074b04569c00343a6a1045235e7 to your computer and use it in GitHub Desktop.
Save taniarascia/9edee074b04569c00343a6a1045235e7 to your computer and use it in GitHub Desktop.
Inlcuding custom fields and uploads in a WordPress post
<?php
function create_post_your_post() {
register_post_type( 'your_post',
array(
'labels' => array(
'name' => __( 'Your Post' ),
),
'public' => true,
'hierarchical' => true,
'has_archive' => true,
'supports' => array(
'title',
'editor',
'excerpt',
'thumbnail',
),
'taxonomies' => array(
'post_tag',
'category',
)
)
);
register_taxonomy_for_object_type( 'category', 'your_post' );
register_taxonomy_for_object_type( 'post_tag', 'your_post' );
}
add_action( 'init', 'create_post_your_post' );
function add_your_fields_meta_box() {
add_meta_box(
'your_fields_meta_box', // $id
'Your Fields', // $title
'show_your_fields_meta_box', // $callback
'your_post', // $screen
'normal', // $context
'high' // $priority
);
}
add_action( 'add_meta_boxes', 'add_your_fields_meta_box' );
function show_your_fields_meta_box() {
global $post;
$meta = get_post_meta( $post->ID, 'your_fields', true ); ?>
<input type="hidden" name="your_meta_box_nonce" value="<?php echo wp_create_nonce( basename(__FILE__) ); ?>">
<p>
<label for="your_fields[text]">Input Text</label>
<br>
<input type="text" name="your_fields[text]" id="your_fields[text]" class="regular-text" value="<?php if (is_array($meta) && isset($meta['text'])) { echo $meta['text']; } ?>">
</p>
<p>
<label for="your_fields[textarea]">Textarea</label>
<br>
<textarea name="your_fields[textarea]" id="your_fields[textarea]" rows="5" cols="30" style="width:500px;"><?php echo $meta['textarea']; ?></textarea>
</p>
<p>
<label for="your_fields[checkbox]">Checkbox
<input type="checkbox" name="your_fields[checkbox]" value="checkbox" <?php if ( $meta['checkbox'] === 'checkbox' ) echo 'checked'; ?>>
</label>
</p>
<p>
<label for="your_fields[select]">Select Menu</label>
<br>
<select name="your_fields[select]" id="your_fields[select]">
<option value="option-one" <?php selected( $meta['select'], 'option-one' ); ?>>Option One</option>
<option value="option-two" <?php selected( $meta['select'], 'option-two' ); ?>>Option Two</option>
</select>
</p>
<p>
<label for="your_fields[image]">Image Upload</label><br>
<input type="text" name="your_fields[image]" id="your_fields[image]" class="meta-image regular-text" value="<?php echo $meta['image']; ?>">
<input type="button" class="button image-upload" value="Browse">
</p>
<div class="image-preview"><img src="<?php echo $meta['image']; ?>" style="max-width: 250px;"></div>
<script>
jQuery(document).ready(function ($) {
// Instantiates the variable that holds the media library frame.
var meta_image_frame;
// Runs when the image button is clicked.
$('.image-upload').click(function (e) {
// Get preview pane
var meta_image_preview = $(this).parent().parent().children('.image-preview');
// Prevents the default action from occuring.
e.preventDefault();
var meta_image = $(this).parent().children('.meta-image');
// If the frame already exists, re-open it.
if (meta_image_frame) {
meta_image_frame.open();
return;
}
// Sets up the media library frame
meta_image_frame = wp.media.frames.meta_image_frame = wp.media({
title: meta_image.title,
button: {
text: meta_image.button
}
});
// Runs when an image is selected.
meta_image_frame.on('select', function () {
// Grabs the attachment selection and creates a JSON representation of the model.
var media_attachment = meta_image_frame.state().get('selection').first().toJSON();
// Sends the attachment URL to our custom image input field.
meta_image.val(media_attachment.url);
meta_image_preview.children('img').attr('src', media_attachment.url);
});
// Opens the media library frame.
meta_image_frame.open();
});
});
</script>
<?php }
function save_your_fields_meta( $post_id ) {
// verify nonce
if ( isset($_POST['your_meta_box_nonce'])
&& !wp_verify_nonce( $_POST['your_meta_box_nonce'], basename(__FILE__) ) ) {
return $post_id;
}
// check autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// check permissions
if (isset($_POST['post_type'])) { //Fix 2
if ( 'page' === $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
} elseif ( !current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
}
$old = get_post_meta( $post_id, 'your_fields', true );
if (isset($_POST['your_fields'])) { //Fix 3
$new = $_POST['your_fields'];
if ( $new && $new !== $old ) {
update_post_meta( $post_id, 'your_fields', $new );
} elseif ( '' === $new && $old ) {
delete_post_meta( $post_id, 'your_fields', $old );
}
}
}
add_action( 'save_post', 'save_your_fields_meta' );
@MarkIvanowich
Copy link

If later you wish to sort your posts by any of these fields, it will not work.

The website article and these pages are describing how to store numerous fields into one meta_key. While this is efficient for fast loading when displaying, you can never use WP_Query to sort posts by an individual field using this method. I suggest using Wordpress' Developer Handbook on Custom Meta Boxes to save an individual field as a query-able meta_key. You could even create a hybrid of the two websites to get the best of both methods while keeping one Meta Box.

Hopefully this saves someone some headache that I just experienced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment