Question

I need to create a custom post meta box(es) for my custom post type "Slideshow" (this post type is already created). Each metabox will hold the content in each slide slide and save it to corresponding custom fields. Each metabox should contain the following fields:

  • Title (Text Field)
  • Image (Either a Text Field for the img URL or ideally a Dropdown List showing thumbnails of the images attached attached to the post)
  • Embed Code (Text Area)
  • Description (wysiwyg)
  • Hide the Slide (Checkbox to use to temporarily hide a slide without deleting it)
  • Delete Slide (button that deletes the contents of the post meta fields that were filled in by this slide)

I would also like a button somewhere that allows me to "Add a slide" so when it is clicked, it adds another "Slide" Custom Meta Box which is a duplicate of the first but adds an incremental number to each custom post meta field. I currently just have 15 metaboxes and the Slideshow template is set up in a way that if only 5 of the metaboxes are filled in then only 5 slides display.

Finally, I'd like to be able to re-order the slides, whether by "Drag and Drop" or by another Text Field that I can type the order number in.

I have gotten it almost where I need it with the "More Fields" plugin and some code help from Rarst. With the "More Fields" plugin I have the following fields in each metabox:

  • Title (Text Field)
  • Image (A dropdown list of the images attached to the post)
  • Embed Code (Text Area)
  • Description (wysiwyg)
  • Hide the Slide (Checkbox to use to temporarily hide a slide without deleting it)

Here is a screenshot of how I have it setup through the "More Fields" plugin:

alt text

The problem with this is that there is no way to delete a slide once it is made because "More Fields" doesn't use <?php delete_post_meta($post_id, $key, $value); ?> anywhere. The other problem with the plugin is that it is too unreliable and breaks frequently with updates.

I have been able to implement a similar solution with my own custom metaboxes that includes:

  • Title (Text Field)
  • Image (Text Field for the img URL)
  • Embed Code (Text Area)
  • Description (Text Area)
  • Hide the Slide (Checkbox to use to temporarily hide a slide without deleting it)

With this implementation I can't seem to get the multiple TinyMCE fields to work or the image dropdown box. The TinyMCE code seems to work until I add the code that create incremental copies of the first metabox at which point I get this error right above the field where the TinyMCE buttons should be: Warning: array_push() [function.array-push]: First argument should be an array....

Also, right now I am relying on my writers to know to put in EITHER a video or an image for each slide and that's ok but it may be better to have a radio button that lets them choose which one the slide is (probably default to image) which is tied to a conditional display statement in the slideshow template.

I am handling image uploads via the built-in "Featured Image" box in the sidebar although I wouldn't mind a custom metabox that simply said "Upload Images" at the top of the write panel.

Ultimately I am looking for a slideshow similar to this: http://www.nytimes.com/slideshow/2010/08/10/science/20100810angier-1.html. I want mine to also be able to have a video as the content in the slide instead of a picture. I need an intuative and easy to use Admin panel for my writers (they are not very tech savvy and not reliable using html and/or shortcodes). Just in case it's not clear from the example, every slide should generate a new pageview.

The Drag'n'Drop reordering isn't a high priority but it would be cool. I found a plugin that handles this really well: SlideDeck. Unfortunately the plugin doesn't suit my needs but the way they handle ordering of the slides is pretty slick. It's a seperate metabox in the sidebar that lets you drag the slides around into the order you like. This is also how you add slides, by clicking on an "Add Slide" button which adds another Slide Metabox to the write panel. Here is a screenshot:

alt text

You can also see more screenshots of it in action in the wordpress repository.

Here is all my code:

The functions setting up my Slideshow Post Type and Slideshow Pagination: http://loak.pastebin.com/g63Gf186

The original code from DeluxeBloggingTips.com (DBT) that I based my Metaboxes off of: http://loak.pastebin.com/u9YTQrxf

The version of the DBT code that I modified to give me incremental versions of the same metabox: http://loak.pastebin.com/WtxGdPrN

A modified version of the DBT code that Chris Burbridge created to allow for multiple instances of TinyMCE: http://loak.pastebin.com/Mqb3pKhx With this code the TinyMCEs do work.

My modification of Burbridge's code that tries to incorporate my incrementation and a field that lets you choose the image from a dropdown list of all the images attached to the post: http://loak.pastebin.com/xSuenJTK In this attempt, the TinyMCE is broken and the dropdown doesn't work.

This probably doesn't matter but just in case you are wondering, here is the code I use to pull the embed code from the custom post meta, resize it, and insert it in the post: http://loak.pastebin.com/n7pAzEAw

This is an edited version of the original question to reflect the current status of the project and answers the questions posted in the comments. Thanks to Chris_O for putting the bounty on this. Also, thanks to Rarst and Justin for helping me out with a lot of this in the ThemeHybrid.com forum. I have spent hours and hours on this and am stuck (I spent a couple hours alone on this Question). Any help would be greatly appreciated.

Was it helpful?

Solution

From the looks of things, your safest bet and easiest route would be to fork the More Fields plugin specifically for your use. The two biggest features I can see your fork needing are a field "factory" and a drag-and-drop interface.

Multiple Fields

My suggestion would be to look at the WordPress Widget class and use it as a model for your field factory - basically, borrow the ability to create multiple instances of a field once you have the framework built for it.

This is the core of how multiple widgets work in a sidebar:

  • You define the code for each widget once by extending the WP_Widget class.
  • Then, you can create as many copies of the widget as you want
    • The specifics of each widget are stored as serialized data in the options table
  • You can customize each widget, remove them with a simple delete command, and set their positioning explicitly through the Appearance drag-and-drop interface

Drag-and-drop

Once again, I suggest looking to the WordPress widget system for inspiration. We've already got a fairly intuitive drag-and-drop interface set up there, so it would be fairly easy to re-purpose much of the same code elsewhere. Or, if you want to get really fancy, you can implement your own drag-and-drop system inside a separate custom meta field.

So each slide would be defined by a custom meta box that's linked to the post. The order of the slides would be set by a separate custom meta box that's also linked to the post. I'd recommend submitting slide updates via AJAX so you can dynamically update the slide order meta box based on the information (this prevents having to manually hit "update" and wait for the page to reload before moving things around).

jQuery UI has a great "draggable" interface that you could easily manipulate for your purposes within this custom meta box. The hard part isn't building the interface, it's getting consistent, accurate communication between the meta box and the collection of slide meta boxes elsewhere on the page.

In Summary

What I gathered from your post is that you have a somewhat workable solution:

  • You've added 15 custom fields to your custom post type via the More Fields widget but want to dynamically add/remove fields rather than work with a set number
  • You want a way to adjust the order of these custom fields so that the slides load in order

The way I'd approach this is to abstract the custom meta creation process to a class I can use over and again to create new custom meta fields. Then I'd extend the class to initialize two types of meta boxes: one for slides, one for slide structure. I'd also build into the slide structure meta box the ability to dynamically create new slide meta boxes (the slide meta boxes would house their own "delete" action).

The entire slideshow would be stored not by the slide meta boxes, but by the slide structure meta box into a custom meta field for the post - the custom meta would be a jagged array, with each of the slides represented as arrays within it - in order. Customizing the order of the slideshow in the structure meta box would reorganize the array and re-save the post meta. This way I only have 1 meta value to read back out when I want access to the slideshow.

Between SlideDeck, More Fields, and the custom code you've put together so far, you've already got most of your solution in hand ... you just need to get it all working together at the same time. I'd focus on getting the root implementation down first before adding the JavaScript embellishments - dynamically creating, modifying, saving, and deleting slides is more important than a rich text editor, IMO. Get that cracked out first. Then get the ordering system down. Then you can focus on getting multiple instances of TinyMCE working on the page.

OTHER TIPS

I found this, which is exactly what you're (I'm) looking for -> http://pippinsplugins.com/drag-and-drop-order-for-plugin-options/

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top