I have been trying to get this worked out for over a year and have tried numerous ways and have not been able to get it to work. I’d really appreciate it if someone could help me with this. Here’s what I’m trying to do…
I need to create 15 custom metaboxes for the Write screen on my custom post type for Slideshows (lom_slideshow). Each metabox will be the same except for the number of slide (Eg, Slide 1, Slide 2…). I would like the metaboxes to save each field into the seperate Custom Field.
Here are the fields that need to be in each metabox:
- Number/Text Field
- Title: Slide Number
- Custom Field Key: slide1-number
- Checkbox
- Title: Hide This Slide
- Custom Field Key: slide1-hide
- Radio toggle
- Title: Slide Type
- Custom Field Key: slide1-slidetype
- Values: Image Slide or Video Slide
- Text Field
- Title: Slide Title
- Custom Field Key: slide1-title
- Image (this one could work several ways and I don’t really care how it works as long as it does)
- Title: Slide Image
- Custom Field Key: slide1-image
- How it will function: as long as it does one of the following things I’ll be happy…
- A) A dropdown list of all the image attachment associated with the post.
- B) A list of thumbnails for all the attached images associated with the post.
- C) An image upload field to upload an image and attach it to the post.
- WYSIWYG
- Title: Slide Description
- Custom Field Key: slide1-desc
- Type: wysiwyg
- Textarea
- Title: Video Embed Code
- Custom Field Key: slide1-embed
Slide 2 will be the same but the all the Custom Field Values will be appended with “slide2-” instead of “slide1-“
The only other consideration is that I’d like them to be in the main content column and only visible on my Slideshow custom post type (lom_slideshow).
Like I said I have tried this numerous time and never got it right. I have gotten close in the past and have gotten the whole thing working except I couldn’t get multiple instances of the WYSIWYG to show up on the page. I no longer have that code because I have changed it numerous times since then. I ultimately decided on using the More Fields Plugin to do this instead of my own code and tested it with 5 meta boxes for development, but then when I tried to implement it with the 15 boxes I needed the plugin wreaked havoc on my database tables. I really don’t want another plugin.
I’m actually looking for someone to just tell me how to code it. I don’t need links to tutorials because I am confident that I have tried them all unless it was published in the last hour or so.
For some background here was what I was originally trying to do: Help Creating a Slideshow Custom Post Type with Custom Meta Boxes?
EAMann provided me with a very comprehensive answer however it was outside my skill set and I couldn’t implement it. I have simplified my request down to this question here in hopes of finally being done with this.
Solve a complex Problem (rationally)
To solve complex problems, there is a kind of standardized/well known approach: Divide your complex problem into a set of smaller problems. Smaller problems are easier to solve. If you have solved each smaller problem you most often have solved your complex problem already.
Locate and Divide into Parts
So far for the theory. Let’s check your needs. I line-up in my own words what you described above:
So how to code that? I think the most important part is that before you start to actual coding, you make up your mind what you really want to achieve and how to divide the problem into the smaller parts. The list above might not be complete it’s just what I could read from your question. And the format is quite unspecific. It’s just more or less a repetition from what you wrote but a bit ordered into single points.
So check if those are your needs and extend that list to all you see fit.
When done, the next step is to look how those needed stuff could be expressed in simple words and as a list of features of your plugin
Looks quite simple now, right? I probably might have missed something here, so double check on your own before you continue. As written, before starting to code just make up your mind in simple wording and terms. Don’t even think about which parts are problematic and which are not or how to code some detail like the naming of HTML Input elements. I know that’s hard if you already tried for such a long time now to restart from scratch because there are many ideas in your mind’s back that come up again.
Grab a pencil and some paper. This often helps to make up someone’s mind.
As you can see I did not specify the need of a Metabox or a Custom Post Type here. It’s too specific to learn about the parts of your problem first. Metabox or Custom Post Type is very concrete, possibly something how to code the plugin already. So I kept this out for the moment and tried to short but precisely describe the needs. The Metabox or similar is something which might play a role in the Design. Let’s see.
Design your Plugin
After you know what you need/want to achieve, you can make up the mind about how to design the plugin. This could be done by drawing a little picture. Just Identify the parts from your Feature List and set them in relation to each other. As you can see, you actually do not need to do fine arts 😉 :
Excuse my bad writing, I hope this can be read. In any case, you can create your own image, this is just an example. Designs can vary, so if you would not draw it the same way, that’s just normal.
I like to do the beginning of the design step on paper because it helps to get a better view on the problem from above and it’s much faster on paper then on the computer.
So now you could compare your list with your design and check if all features from the list are covered by the parts you have in the design. Looks good so far for my list and my image, so I continue, but don’t skip this step. Otherwise you do not know if you have missed something. And as you start to code soon, it’s much more hard to change something that’s already coded than an image or a list.
Separation of Problems in the Design
Now this plugin becomes more concrete in ones mind. After some little design, it’s probably the right time to start coding. As we have the list on top, I could go through and think about each point on it’s own and cross-check with the Design so that I know how the parts are in relationship to each other.
Because if every single part is done, the plugin is ready without making up the mind on the whole thing at once, which was the original problem.
I do the coding now a bit in comment style and some sample code. It’s a first implementation idea and the code is untested. It’s just to get the hands dirty for me and for you to probably have an example of how – but not must – this can be written. I tend to be too specific sometimes already, so mind me. When I write code, I re-write it quite often while creating it, but I can not make this visible while creating the sample code. So bear this in mind. If you see something to be done simpler, choose your route. You need to change and extend your code later on, so this is really only some example code.
Plugin
Just a class that handles the basic operation like registering hooks and providing the Slideshow with it’s Slides and the Metaboxes for the Editor. This is where everything starts. Plugins are started at a single point of code. I call that bootstrap:
So this plugin class is already quite complete. I did not specify how to retrieve the postID but it’s already encapsulated in a function on it’s own. Next to that I did not code to check whether or not this is the right page to display the editor, but there’s already some stub code for that.
In the end, the editorAction() is called if the request is on the actual custom post type editor page and in there, the Metaboxes are aquired. That’s it. Plugin should be pretty complete now. It has the slideshow and takes care of the Metaboxes. Compared with the design, those are the parts which are linked with the plugin. Compare with the image:
Looks complete. Job done on that part.
Slideshow and Slides
A Slideshow is 1:1 mapped to a post. So it needs to have the Post ID. The Slideshow can take care of holding the data, so it’s basically a Datatype. It stores all the values you need there. It’s a compound datatype in the sense that it consist have 0 to N slides. A Slide again is another Datatype that holds the information for each Slide.
The slide then is used by a metabox and probably a form.
I additionally choosed to implement the storage and retrieval of the slideshow data as well into those datatypes (the box labeled Store in the design). That’s somehow dirty as it mixes datatypes and actual objects.
But as the Store is connected to Slideshow and Slides only in the Design I connected them with each other. Probably too close for the future, but for a first implementation of the design, I think it’s a valid approach for the moment. As this is the first approach it won’t take much time after it will get refactored anyway so even with some issues I’m quite confident that the direction is right:
The Slideshow and Slide classes are also quite complete but lacks actual code as well. It’s just to show my idea of having the properties / methods and some handling stuff as well on how the retrieval of data could be implemented.
Metabox
The Metabox needs to know which Slide it represents. So it needs to know the Slideshow and the concrete Slide. The Slideshow can be provided by the Plugin, the Slide could be represented by the index (e.g. 0 … N where N is count of slides in the slideshow – 1).
The Metabox class is actually extending the plugin class somehow. It does some of the work that could be done by the plugin class as well, but as I wanted to have it represent the slide in context of the plugin while being able to have multiple instances, I choosed this way.
The Metabox now needs to take care of the request logic: It represents one Metabox which is actually somehow output but it’s also input as it needs to deal with form input.
The good thing is, it actually does not deal with the details because form output and input are done by the form objects.
So probably if I would have coded this class to an end, I would have removed it completely. I don’t know right now. For the moment it represents the Metabox on the editor page for one specific slide.
Metaboxes
I only wrote some little code here so far. The Metaboxes class acts as a manager for all metaboxes. The representative of the Slideshow as Metabox represents a slide.
That stub code does not much but instantiating one Metabox per Slide. It can and must do more in the end.
You probably might want to make use the of the Composite Pattern here, so to do an action on a Metaboxes object will do the same action on every Metabox it carries. Comparable with the instantiation, where it creates new Metaboxes. So you don’t need to deal with individual Metaboxes later on, just with the Metaboxes object. Just an Idea.
Form
The Form is probably the most complex thing you have in terms of dealing with stuff and lines of code. It needs to abstract your data to be processed via the Browser. So it must be able to handle multiple instances. You can achieve this by prefixing form element names (as they need to be unique) with a genreal prefix (e.g. “slide”), then an identifier (the slide index, I name it index here as you want to be able to change the number e.g. to have a sort key) and then the actual value identifier (e.g. “number” or “hide”).
Let’s see: A form knows about it’s prefix, the slide’s number and all fields it contains. This pretty much maps to the Slideshow and Slide datatypes spoken about above. Some little stub-code:
This class is quite large now because it takes care of three things at once:
It is wiser to split this up into the three parts it represents. I leave that up to you. It does already show how you can encapsulate the forms functionality into smaller tasks so it’s easier to comply with your needs. E.g. in case the Image Input element form output needs tweaks, it can be easily extended / polished. Same for WYSIWYG. You can change the implementation later on as it won’t interfere for you slideshow and slide datatypes much.
The principle behind this is also called Separation of Concerns, and that is just about how I started my answer: Divide the problem into smaller problems. Those separated problems are easier to solve.
I hope this helps for the moment. In the end I didn’t come back to Custom Post Types even. I know they must go inside the plugin, but with a new design it’s probably easy to find the place where to write the code to.
What’s left?
I know you said you don’t want another plug-in but I would recommend checking out “Verve meta boxes” or “Custom Field Templates”, the latter having a lot of options, but verve has a nice drag + drop interface.
As for you datatabse issue, can you elaborate on why you need multiple wysiwyg fields and why this is effecting the database? I have used over 40 custom field on some pages and did not notice any trouble.
As for the slideshow, I did something similar and had to write my own using jquery and query_post types. For instance this shows a random post in the slider for the custom post type called “movies”. You can add in any custom meta values by using get_post_meta.