David Noble Posted December 30, 2012 Share Posted December 30, 2012 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. Link to comment Share on other sites More sharing options...
Marty Walker Posted December 30, 2012 Share Posted December 30, 2012 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 Link to comment Share on other sites More sharing options...
David Noble Posted December 30, 2012 Author Share Posted December 30, 2012 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 Link to comment Share on other sites More sharing options...
SiNNuT Posted December 30, 2012 Share Posted December 30, 2012 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 3 Link to comment Share on other sites More sharing options...
Soma Posted December 30, 2012 Share Posted December 30, 2012 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; 5 Link to comment Share on other sites More sharing options...
SiNNuT Posted December 30, 2012 Share Posted December 30, 2012 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. Link to comment Share on other sites More sharing options...
Soma Posted December 30, 2012 Share Posted December 30, 2012 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'); } } Link to comment Share on other sites More sharing options...
Soma Posted December 30, 2012 Share Posted December 30, 2012 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 1 Link to comment Share on other sites More sharing options...
Pete Posted December 30, 2012 Share Posted December 30, 2012 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). 1 Link to comment Share on other sites More sharing options...
David Noble Posted December 30, 2012 Author Share Posted December 30, 2012 Thanks everyone for you help! I'll have a go at implementing it Link to comment Share on other sites More sharing options...
SiNNuT Posted December 31, 2012 Share Posted December 31, 2012 Thanks everyone for you help! I'll have a go at implementing it One more thing. Seeing as you mentioned a migration scenario, be sure to checkout http://modules.processwire.com/modules/import-pages-csv/ if you haven' t already. In a lot of scenarios very useful for importing some data. Link to comment Share on other sites More sharing options...
David Noble Posted January 8, 2013 Author Share Posted January 8, 2013 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! 5 Link to comment Share on other sites More sharing options...
neildaemond Posted July 3, 2013 Share Posted July 3, 2013 did this ever end up being an official module? did anyone improve on this method? Link to comment Share on other sites More sharing options...
neildaemond Posted July 3, 2013 Share Posted July 3, 2013 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. Link to comment Share on other sites More sharing options...
artfulrobot Posted April 19, 2023 Share Posted April 19, 2023 Just linking back to https://processwire.com/modules/publish-date/ which is a module that "is an extended version of what the ProcessWire community came up with in this thread" Although, also noting that it seems PW core now creates a published field on the pages table which holds the datetime that the page was published, or `null`; so that module no longer seems to be needed. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now