So for the new TWiT site, I needed a mechanism for being able to set a date to publish certain nodes on. I could have opted for the Scheduler module, but that was a bit bulky, 4.7 support was flaky, and it required another table in the database. I also wanted an easy way to integrate JSCalendar from the awesome Javascript Tools module.
What to do?
Combine in a module a cup of CCK, a quarter cup of JSTools, and a sprinkle of hooks, and voila, instant publish on capabilities!
Here’s how the code actually breaks down:
First, define a hook_help to make it clear what your module does on the admin/modules page:
[coolcode lang="php" linenum="on" download=none]
/**
* Implementation of hook_help().
*/
function YOUR_MODULE_NAME_help($section) {
switch ($section) {
case 'admin/modules#description':
return t('Use this module to schedule the publishing of podcasts.');
}
}
[/coolcode]
Next, define a new content type with CCK, in this example, my content type is “podcast”. Add all of the necessary fields you need, and then add a textfield “publish on”. Now, to get the JSCalendar to hook into this field, we need to use hook_form_alter() to add this capability to that field on the node/edit pages.
[coolcode lang="php" linenum="on" download=none]
/**
* Make use of JS calendar picker on podcast edit forms
*/
function YOUR_MODULE_NAME_form_alter($form_id, &$form) {
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
//set this to the type of content you want to publish on
if ($form['type']['#value'] == 'content-podcast') {
$form['field_publish_on'][0]['value']['#attributes'] = array('class' => 'jscalendar');
// Use only year, month, and day in textfield.
$form['#jscalendar_ifFormat'] = '%Y-%m-%d';
// Don't show time.
$form['#jscalendar_showsTime'] = 'false';
}
}
}
[/coolcode]
Great! Now we can use the Javascript calendar picker to set dates for when our podcasts should be published. Since we don’t want our podcast published if a date has been selected, we need to make sure the podcast is unpublished when a date has been entered.
[coolcode lang="PHP" linenum="on" download=none]
/**
* Implementation of hook_nodeapi().
*/
function YOUR_MODULE_NAME_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
if ($node->type == 'content-podcast') {
switch ($op) {
case 'submit':
//right before we save the node, we need to check if a "publish on" value has been set
//if it has been set, we want to make sure the node is unpublished
if ($node->field_publish_on[0]['value'] != '') {
$node->status = 0;
}
break;
}
}
[/coolcode]
Excellent! Now all we need to do is setup a cron job to run and publish these podcasts when their publish on date occurs.
[coolcode lang="PHP" linenum="on" download=none]
/**
* Implementation of hook_cron().
*/
function YOUR_MODULE_NAME_cron() {
$nids = db_query('SELECT n.nid FROM {node_content_podcast} p INNER JOIN {node} n ON p.nid = n.nid WHERE n.status = 0 AND p.field_publish_on_value = CURDATE()');
while ($result = db_fetch_object($nids)) {
db_query('UPDATE {node} SET status = 1 WHERE nid = %d', $result->nid);
}
}
[/coolcode]
Bingo! Now we can set the date for when nodes should be published and it only took about a dozen lines of code.
Doesn’t Drupal rock?