Last January, Tim Owens did a masterful job of assembling the Daily Create site out of a premium theme (Salutation), a mix of plugins (including Awesome Flickr Gallery, Tubepress, and Gravity Forms), etc– and no custom code.

When I arrived at UMW in February, I offered to take over the creation of the challenges. It is a mix of ones submitted by our site users, borrowed ones from the Daily Shoot, b3ta Challenges, the Vancouver Draw Down, and the 30 Day Drawing Challenge, plus about a good 30% we just dreamed up.

Creating them turned out to be a bit tedious as there was at least 7 different things to set on the interface. We had to have them, scheduled in advance, each to be published at 10:00 am EST.

All thee steps for editing a Daily Create

(click for full size image)

(1) The title would be present if it was submitted via a form; for one from scratch it is entered/pasted.
(2) The post name was manually entered, based on the tag for the day
(3) Depending on the type of Daily Create, we had a format for the post that would use a set of links to flickr, you tube tags to set up the instructions, and for the embedding of media, a Tubepress shortcode, flickr gallery ID, or a SoundCLoud embed code. For these, the tag had to be manually entered in at least two spots. For the flickr ones, we would have to create an Awesome flickr gallery (another admin page), and manually copy/paste the shortcode. I started by copying from old posts (and managing a few times to edit the wrong one) and later kept a generalized version in a text doc for cutting/pasting
(4) The future date for publishing was manually set (10:00am EST)
(5) Two categories assigned for the type, and an overall category we use to group all assignments.
(6) The tag is entered here
(7) The theme required a selection menu to match it to the type of assignment (each type has its own graphic which is displayed in the single post view.

I did this for about two months before rolling up my elbows to see if this could be streamlined.

Each of the four types (Audio, Video, Photography, Drawing) have a different content structure which is what embeds the creative works in a post. When I looked it at, once the type was set and the tag as known (the tag tdc123 is also the slug for the post), it was potentially template-able.

I looked to see if there were any plugins for setting up at least the templates for the content, but did not find any that allowed for multiple templates.

But ti was looking at the admin interface for this very theme (the theme options down the right sidebar) that it dawned on me that I could possibly create my own box with a drop down menu to select a type, and when saved, the post would automagically fill in the right content and check the right boxes, etc.

So after completing the Daily Creates for 6 months in advance, doing this seriously paid off. I was typically able to knock off a months worth in about 90 minutes, and more of that was having to look around or make up assignments.

The way is works now is for a new post or if I edit something that is a draft, the TDC Settings meta box is activated.

(click for full size image)

(Gulp, note in this fake example, it should be a Drawing type, not photography, this assignment is not reallly in the mix… yet)

The only thing it needs is (1) the title, (the code automatically creates the next tag it should use based on the last one created) and (2) I just select the type from the drop down menu, and click Save Draft.

When saved, everything else is done for me!

(click for full size image)

(1) Tag is used for the url
(2) The basic content is created according to the kind of assignment, and the tag is inserted where it is needed. The * is because the automation is not 100% complete; I still have to generate the flickr gallery shortcode for Photography and Drawing types (I did experiment with calling the code directly; it was close but not quite correct). Also, the embed codes for SoundCloud are random IDs, not related to the group name, so that code is also manual.
(3) The future publication date is automatically set! This saves a ton of time. It simply looks for the last one created, and then sets the publication date for 24 hours later.
(4) Categories automatically checked
(5) (6) The tags and the header setting for the template are auto selected.

This is all done by some custom code to intercept the hook when a draft is saved, and then updating the post data (and some post metadata).

Below is the semi hairy code… broken into parts for explanation. This all lives in the functions.php part of the theme template (which truly should be done as a child theme). If I were more clever, I would have made it a plugin, but the code would be the same (One day I want to be 0.01% as code clever as Boone Gorges).

Here we go… code below the fold…

The first thing we need to put in is a hook to add the meta box when the admin interface is built, tis simply says when the admin page is loaded and it is time to add meta boxes (those things on the right), call my function tdc_meta_box_add() to do set up the work of building the form interface you see (it passes all the variables the box needs, including the ‘high’ option to place it at the top right)

A few utility scripts were needed… tdc_get_next_tag() looks in the database to find the most recent tag used (via a custom query), and then returns an incremented on; so if the most recent one created was tdc233, we return tdc234.

Likewise, we need to find the date of the post of the last one created (it is not the edited ddate but the date it is set to be published in the future)

And now we have the callback function to do the work. A couple of things going on here, we need to make sure it only gets called for a new or a draft post (so it does not override an existing one).

If a draft had been made before, ti stores the tdc tag as a post_meta data, we check this first to see if it has been assigned, if not we give it a flag value of just ‘tdc’- this signals later that we need to find the next tag available via our custom function created above.

We have to find the tag we should use for the new post and insert it in the text field of the form (allowed for it to be edited). We put the date for the new post in a hidden form field, along with a tag to indicate if it is a brand new post. The checkl box to confirm the over-write allows us to choose whether we change the post content or not (we do not want to change it if the post is still a draft).

Whew, that was just to create the form in the box of our interface. Now we have to make it do something. To do this we need to set up a hook to catch when a post is saved:

This could happen whether the Save as Draft, Post, or Update buttons are pressed by the user.

Basically this does a few checks to make sure we are doing it only for the kinds of saves we want to be doing. If the type selection is not set we want to bail. We do not want to change anything if the user unselects te check box. And we do not want to be doing this on a WordPress autosave…

The code to remoce the hook was a subtle trick I found was needed to make it possible for me to edit the post date. That was obscure! I think that was the reason, I cannot even find the reference, it was likely at Stack Overflow.

The whole point is to pass the tag, date, type, and post id to our function that will do the updating.

And her we do the work of updating the post via tdc_update_post() It is basically setting up an array of all the new values for the post (and adding/editing a few postmeta fields for info tracking). One of the nitty things is that in the type of assignment (which is what gets set as the theme’s layer heading” is not stored as values like “Photography”, “vide” but cryptic keys like ‘y0krz2ep75f’ — these are actually buried in an options array in the blog meta table, and rather than parsing through that, I got lazy and hadn coded it. This should be updated one day…

And that is how its done! For reference, below you will find all of this custom code in one block.

It was fun to work through, and I am pretty darned proud of it, but like all code, it could likely use some improvements. I’m just the kind who bangs at it til it works, sand then tweaks the corners forever.

If this kind of stuff has value, please support me by tossing a one time PayPal kibble or monthly on Patreon
Become a patron at Patreon!
Profile Picture for CogDog The Blog
An early 90s builder of web stuff and blogging Alan Levine barks at on web storytelling (#ds106 #4life), photography, bending WordPress, and serendipity in the infinite internet river. He thinks it's weird to write about himself in the third person. And he is 100% into the Fediverse (or tells himself so) Tooting as


  1. I love that you share this stuff. I don’t always follow all the details but I file it away for future reference if I ever want to do something similar (which has happened more than once over the years). What I most get out of these posts is some insight into how you think & problem solve; and that’s awesome!

  2. Thanks for sharing this! My school district tends to block most tools that involve any kind of sharing (flckr, YouTube, SoundClould, and even and so I’m constantly figuring out how to build my own systems for students to at least be able to share with each other inside our system. Is there a post anywhere that gives similar insight into how you guys built the Assignments area of ds106?

  3. This is great stuff Alan – love how you folded your own workflow for the TDC. A great example of working smarter, not harder.

Leave a Reply

Your email address will not be published. Required fields are marked *