Home

Lullabot

Lullabot Ideas

We know stuff. We empower you to know stuff too.

On Site Drupal Training

We'll come to you! Graduate from your own on-site courses and become Drupalistas!

How to create a "publish on" option for nodes

Article by Ted SerbinskiMay 5, 2006 - 5:08pm

UPDATE: I've completely rewritten scheduler module now and it makes use of this technique (minus the CCK part). Has complete publish and unpublish options, along with JSCalendar support.


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:

<?php
/**
* 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.');
  }
}
?>

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.

<?php
/**
* 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';
    }
  }
}
?>

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.

<?php
/**
* 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;
    }
  }
?>

Excellent! Now all we need to do is setup a cron job to run and publish these podcasts when their publish on date occurs.

<?php
/**
* 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);
  }
}
?>

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?

Comments

Tones (not verified) on May 5, 2006 - 5:52pm

!

this is freaking great.

Cutter (not verified) on May 5, 2006 - 7:45pm

Very slick

Nice! Thanks for sharing this.

A couple questions: Can you make this a day/time event, not just a day event?

And can you also add an unpublish day/time?

May 6, 2006 - 11:09am Ted Serbinski

Yes, you can easily make

Yes, you can easily make this a day/time event as well. Just take out these lines:

<?php
// Use only year, month, and day in textfield.
$form['#jscalendar_ifFormat'] = '%Y-%m-%d';
// Don't show time.
$form['#jscalendar_showsTime'] = 'false';
?>

As for an unpublish day/time, this would be easy too. Just add another CCK field for unpublishing. Then use in your hook_form_alter() make sure to duplicate that code to append to the new field. In hook_cron() you'll want to add another query that looks for all nodes that are published AND have an unpublish field that equals CURDATE().

cutter (not verified) on May 8, 2006 - 9:45pm

Thanks again.

Excellent! You guys rock.

Anonymous (not verified) on May 7, 2006 - 7:51pm

What about >= CURDATE() ?

Nice! Thinking though, what about using >= CURDATE instead of = curdate? Just in case, say the cron jobs go bad, or server goes down, etc. (I know, this never happends :)), the system can almost 'self-repair' but publishing any 'lagging' nodes that were missed during the outage?

Anonymous (not verified) on May 8, 2006 - 12:21pm

Err, backwards logic

Lol. sorry about that on last post, I meant =< (less than or equal to).

May 8, 2006 - 11:45pm Ted Serbinski

The only problem with that

The only problem with that is you assume *all* content that is older than today should be published. There are many cases when that content may need to be unpublished, and hence, you could run into a problem there :-)

tomit (not verified) on May 9, 2006 - 4:37pm

Use in an events module

Can this be done with the events module? I would like to use this to allow users to search through events by date ranges. This JSCalendar would make this so user friendly.

May 10, 2006 - 2:04pm Ted Serbinski

Yes, you can adapt the

Yes, you can adapt the hook_form_alter() to look for the 'event' type. Then you can simple append the "jscalendar" class to the input date for events. You'd have to figure out what fields to attach to, but this should be fairly straightforward.

bert Wynants (not verified) on May 22, 2006 - 8:11am

cache update

and how about the cache? don't you have to flush the cache?

lubtex (not verified) on June 3, 2006 - 12:53am

date change

The date field in CCK seems to have changed. All of the date fields now seem to require it to be in the format "YYYYMMDDTHH:MM:SS" (with T being an actual "T").

John H (not verified) on July 17, 2006 - 8:50pm

publish off?

Very nice work indeed. Anyone thought about using the same technique to unpublish a node?

Tee (not verified) on July 23, 2006 - 6:25pm

The module doesn't work right.

The publish on time doesn't work correctly.

It states the format: "1981-11-24 15:24:07" (Is 1981 an error?)
But doesn't work unless you use 2006-07-23 15:24:07 -400 and even when you do that, it posts 4 hours behind.

Ramdak (not verified) on July 23, 2006 - 9:00pm

Only CCK?

Lovely work on a most important area. A few questions, though:

1.) Does this work only with CCK content types?
2.) Can this be used to automatically unpublish nodes at a set date?

Extending this:

1.) Does this give a block? You could then use it as a kind of alerts thing
2.) Could you consider providing an option for showing a countdown? This could be something like, "21 days, 3 hours, 10 minutes to register", with the 'to register' field being definable by admin- I mean, not all nodes may deal with registration, so admins should have the choice to put whatever they want.

DVkid (not verified) on August 4, 2006 - 9:43pm

Just a though...

How much more work would it take to make this a CCK field type? I have yet to really crack open the CCK modules but that seems like an intuitive way of using this. Any thoughts? I'm gonna go look at some of the other field modules and see if I can't grok it.

graham (not verified) on November 6, 2006 - 2:45pm

Would it be possible to use

Would it be possible to use this to repeatedly publish/unpublish content on, e.g., the 1st of the month? (My client has 31 posts that they want to display on the appropriate date of the month.)

Peter (not verified) on November 15, 2006 - 3:59pm

Keep up your great work Ted

Keep up your great work Ted :)

Anonymous (not verified) on December 14, 2006 - 8:11am

Good work, Ted! You can't

Good work, Ted! You can't imagine the quantity of sleepless nights i have searching the right decision with Publish On.

3dsl Eugen (not verified) on March 1, 2007 - 1:27pm

simple

thx guys, easy to follow :D

About this 'bot

Ted Serbinski

Ted graduated from Cornell University with a degree in Information Science, Systems, and Technology and a minor in Computer & Electrical Engineering. While working on a 5 month coop at Intel in Massachusetts, Ted quickly realized that building web based tools was far more his forte than debugging...

more

Recent

Drupal Voices 160: Moshe Weitzman on Page Rendering in Drupal 7

Podcast 9.02.2010

Drupal Voices 159: John Albin Wilkins on Drupal 7 Theming

Podcast 9.01.2010

Drupal Voices 158: Emma Jane Hogbin on PHP for Designers

Podcast 8.31.2010

Command Line Basics: More Editing with Vi/Vim

Video 8.31.2010

Lullabot's Back to School Sale

Blog 8.30.2010

Popular

Drupal Voices 160: Moshe Weitzman on Page Rendering in Drupal 7

Podcast 9.02.2010

Drupal Voices 159: John Albin Wilkins on Drupal 7 Theming

Podcast 9.01.2010

Photo galleries with Views Attach

Article 6.01.2009

Announcing BeautyTips, a jQuery Tooltip Plugin

Article 10.20.2008

Install a Local Web Server on Ubuntu

Video 11.14.2007
 
  • Home
  • Services
  • Events
  • Ideas
  • Store

Connect the Bots:

Twitter Facebook YouTube blip.tv All Posts Newsletter
  • Ideas
  • Blog
  • Podcasts
  • Videos
  • About
  • Contact
  • Jobs
  • Services
    • Training
  • Events
    • Training Workshops
    • Other Events
    • Conferences
    • Calendar
  • Products
    • Videos
    • Books
    • Swag
  • Ideas
    • Blog
    • Podcast
    • Videos
  • About
    • Philosophy
    • Team
    • Presskit
  • Contact
    • General
    • Work Inquiries
    • Mailing List