Jump to content
David Noble

Show date published on a page

Recommended Posts

Hi, I'm a totally new user of ProcessWire and I'm just starting to migrate an existing site. One of the requirements is to to show the "date published" on pages on the site. This is the actual date published - not the date it was created or modified. As there does not appear to be a field that holds this date I imagine that I will have to create a field and include it on my templates (which is very easy to do with this system). My question is - how would I go about populating this date? Is there anyway to hook into the publish event?

(I've looked through the API, and I can see that I can hook into the save event. I've also found the code in the ProcessPageEdit module that works out the page is unpublished, and gives the option to save and publish, but I'm really not sure where to go from there.)

Any help greatly appreciated.

Share this post


Link to post
Share on other sites

Hi David,

You need to setup a "publish_date" field of the datetime type. In your template code you'd check against that field.

<?php
$today = time();
$blog = $pages->get("/blog/")->find("sort=-publish_date, publish_date<$today");
?>

I'm not sure if this help but that's how I setup blog/news pages.

Regards

Marty

Share this post


Link to post
Share on other sites

Hi Marty, Thanks for the quick reply. I'm not sure I've explained what I'm trying to do well enough.

I can see how what you've suggested would help me if I wanted to show blogs with a publish date that was less than today. What I'm trying to do is set the "publish_date" when the status of the page changes to published (or from unpublished I guess). That way I can retrieve the publish_date and display it on the page eg: "This page was published on: 30 December 2012".

Cheers

Share this post


Link to post
Share on other sites

I don't have coding skills but if you have some this would be an easy module i guess. Something like:

/**
*
* "Set Publish Date" module
*
*/

class SetPublishDate extends WireData implements Module {

/**
 * getModuleInfo is a module required by all modules to tell ProcessWire about them
 *
 * @return array
 *
 */
public static function getModuleInfo() {

 return array(

	 'title' => 'Set Publish Date',
	 'version' => 001,
	 'summary' => 'your summary',
	 'singular' => true,
	 'autoload' => true
	 );
}

/**
 * Initialize the module
 *
 * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called
 * when ProcessWire's API is ready. As a result, this is a good place to attach hooks.
 *
 */
public function init() {

 // add a hook after the $pages->save
 $this->pages->addHookAfter('save', $this, 'afterSave');

}

public function afterSave($event) {
 $page = $event->arguments[0];

 if($page->is(Page::statusUnpublished) || isset($page->publish_date)) return;
 $page->of(false);
 $page->publish_date = date('Y-m-d H:i:s'); // not sure about the date format
 $page->save('publish_date'); // save only specific field like this?

}

}

Perhaps someone more experienced can help you out

  • Like 3

Share this post


Link to post
Share on other sites

That's a good example sinnut, but a minor change to make it work:


public function afterSave($event) {
   $page = $event->argumentsByName('page'); // get argument by name, more readable
   if($page->is(Page::statusUnpublished) || $page->publish_date) return;
   $page->publish_date = time();
   $page->save('publish_date');
}

isset() wouldn't work in the previous example as the field exists but is not populated it will always return true.

Also $page->of(false) isn't really required as in a module the page has no outputformatting on anyway.

To populate the datetime field you'd just give it a timestamp. As the field holds input-outputformatting date formatting it will take that. Not wrong but no need to.

If you also need to restrict to certain pages you could add a check for the template before status check.

if("article" == $page->template) return;
  • Like 4

Share this post


Link to post
Share on other sites

To be honest i'm amazed that i wasn't far off track, made my first amazing module hehehe

Indeed, you'd probably want to check for templates that actually have the publish_date field.

Also maybe build in the logic for what needs to happen when a published page gets 'unpublished', because it now basically only fires once; when a page gets published that has an empty publish_date field

Curious to see if there are other/better approaches.

Share this post


Link to post
Share on other sites

Of course you can improve it a little with more logics if needed.

Only on pages that have the publish_date field.

Remove date if page is unpublished.

Add value if published and not populated yet.


public function afterSave($event) {
   // get page object saved
   $page = $event->argumentsByName('page');

   // only on pages that have a publish_date field
   if(!$page->template->hasField('publish_date')) return;

   if($page->is(Page::statusUnpublished)) {
       // if unpublished, empty the field if not empty already
       if(!$page->publish_date) return;
       $page->publish_date = '';
       $page->save('publish_date');
   } else if(!$page->publish_date) {
       // if page (published) and field not populated, add current timestamp
       $page->publish_date = time();
       $page->save('publish_date');
   }
}

Share this post


Link to post
Share on other sites

To be honest i'm amazed that i wasn't far off track, made my first amazing module hehehe

That's great. I felt the same way when seeing even I could make such powerful modules without learning something very difficult. It's not very different from when using API anywhere in front-end. So you can use your knowledge already aquired and start dreaming away.

Indeed, you'd probably want to check for templates that actually have the publish_date field.

Also maybe build in the logic for what needs to happen when a published page gets 'unpublished', because it now basically only fires once; when a page gets published that has an empty publish_date field

Curious to see if there are other/better approaches.

Agreed. See examples on previous post :D

  • Like 1

Share this post


Link to post
Share on other sites

I know it's not the same thing as David was requesting, but there's also this module for scheduling publishing of pages in the future as well as optional unpublishing: http://modules.processwire.com/modules/schedule-pages/

I use this module on one site on the rare occasions I have lots of news and want to spread the articles out over the week.

Just thought I'd mention it as if you were using some of the code the guys above have come up with you want to be careful to match your fieldnames with both modules (changing $page->publish_date in the above code to $page->publish_from would do the trick).

  • Like 1

Share this post


Link to post
Share on other sites

Hi all, I just wanted to let you know that I've implemented the solution you helped me out with above, and it works wonderfully. I now have a site ready to move from development to production. I can't believe how easy it has been with Processwire. I've been able to implement things that were just way too hard to bother trying to do in some other CMSs.

Again. Thanks for all your help!

  • Like 5

Share this post


Link to post
Share on other sites

hey guys, I tried putting the following code into /site/modules/SetPublishDate.module

 

/**
*
* "Set Publish Date" module
*
*/

class SetPublishDate extends WireData implements Module {

/**
         * getModuleInfo is a module required by all modules to tell ProcessWire about them
         *
         * @return array
         *
         */
public static function getModuleInfo() {

         return array(

                 'title' => 'Set Publish Date',
                 'version' => 001,
                 'summary' => 'your summary',
                 'singular' => true,
                 'autoload' => true
                 );
}

/**
         * Initialize the module
         *
         * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called
         * when ProcessWire's API is ready. As a result, this is a good place to attach hooks.
         *
         */
public function init() {

         // add a hook after the $pages->save
         $this->pages->addHookAfter('save', $this, 'afterSave');

}

public function afterSave($event) {
    // get page object saved
    $page = $event->argumentsByName('page');

    // only on pages that have a publish_date field
    if(!$page->template->hasField('publish_date')) return;

    if($page->is(Page::statusUnpublished)) {
        // if unpublished, empty the field if not empty already
        if(!$page->publish_date) return;
        $page->publish_date = '';
        $page->save('publish_date');
    } else if(!$page->publish_date) {
        // if page (published) and field not populated, add current timestamp
        $page->publish_date = time();
        $page->save('publish_date');
    }
}

}

However, in the module section it will detect the module but then shows as  version 0.0.0 and summary 'inactive'

after pressing 'install', if get these errors:

/** * * "Set Publish Date" module * */ class SetPublishDate extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( 'title' => 'Set Publish Date', 'version' => 001, 'summary' => 'your summary', 'singular' => true, 'autoload' => true ); } /** * Initialize the module * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. * */ public function init() { // add a hook after the $pages->save $this->pages->addHookAfter('save', $this, 'afterSave'); } public function afterSave($event) { // get page object saved $page = $event->argumentsByName('page'); // only on pages that have a publish_date field if(!$page->template->hasField('publish_date')) return; if($page->is(Page::statusUnpublished)) { // if unpublished, empty the field if not empty already if(!$page->publish_date) return; $page->publish_date = ''; $page->save('publish_date'); } else if(!$page->publish_date) { // if page (published) and field not populated, add current timestamp $page->publish_date = time(); $page->save('publish_date'); } } }

Error Class 'SetPublishDate' not found (line 437 of /var/www/xxxx/wire/core/Modules.php)

This error message was shown because you are logged in as a Superuser. Error has been logged. 

Any ideas? I'm using PW2.2.9

EDIT (SOLVED) -> I left out the "<?php" at the beginning of the file.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...