Jump to content


Photo

Release: SchedulePages

Module

  • Please log in to reply
39 replies to this topic

#1 formmailer

formmailer

    Sr. Member

  • Members
  • PipPipPipPip
  • 245 posts
  • 28

  • LocationHudiksvall, Sweden (but originally from The Netherlands)

Posted 02 December 2011 - 05:32 AM

Hi,

I just uploaded the first version of the SchedulePages module to Github:
https://github.com/f...r/SchedulePages

This plugin module allows you to schedule (un)publication of pages.

I hope you guys will like it.

//Jasper

Usage:
======
  • Place the SchedulePages.module file into the site/modules folder and install the plugin from the admin area.
  • Install/activate the LazyCron module (if you haven't already). This module is part of the Processwire core, but it isn't activated by default.
  • Add the following date fields to your template:
    publish_from
    publish_until
Note: the fields are already created during the installation of the module
  • That't all. LazyCron will run take care of (un)publishing your pages that have a the publish dates set. It will run on every hour.
    Please note: LazyCron hooks are only executed during pageviews that are delivered by ProcessWire. They are not executed when using ProcessWire's API from other scripts.
Edit: Changed the name of the module and function as Ryan suggested below.
Edit 2: Updated instructions. Required fields are now automatically created and from now it runs every hour.
Edit 3: Added module dependency. The updated module is on Github

#2 Soma

Soma

    Hero Member

  • Moderators
  • 3,188 posts
  • 1745

  • LocationSH, Switzerland

Posted 02 December 2011 - 05:45 AM

Hey, congrats on the module.

This can be very useful I guess, will check it out soon.

@somartist | modules created | support me, flattr my work flattr.com


#3 Guillaume

Guillaume

    Jr. Member

  • Members
  • PipPip
  • 11 posts
  • 0

  • LocationFrance

Posted 02 December 2011 - 05:52 AM

This is cool, I see the potential for this module. You guys are having too much fun coding PW modules, I hope to join the party soon! :)

#4 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 02 December 2011 - 06:23 AM

Great stuff formmailer, this was quick! Will definitely test this and probably start using too!

EDIT: I took quick look to code. It seems that you hook into LazyCron::everyDay. This means it checks status only on daily basis. I think that is fine for most cases, but I think it would be good to have possibility for tighter schedule. I know our clients schedule many time on hourly basis (ie. they write press release at the morning and want it to be released 14:00).

#5 ryan

ryan

    Hero Member

  • Administrators
  • 5,773 posts
  • 3116

  • LocationAtlanta, GA

Posted 02 December 2011 - 03:53 PM

Formmailer this looks great, and incredibly useful! This is definitely one of those things that clients ask for and I have a feeling your module is going to get a lot of use. :)

I agree with Antti that a great upgrade would be to have a little finer control (maybe down to the hour?) whether in this version or some future version.

Another nice upgrade would be having your module install/uninstall the publish_from and publish_until fields automatically. I'll be happy to show you how to do this if you'd like?

---
Edit: also wanted to add: you might want to just call the module 'SchedulePosts' rather than ProcessSchedulePosts. That's because 'Process' is meant to refer to modules that extend the 'Process' module type (i.e. interactive admin modules). Also, 'Posts' is not a term that's used in ProcessWire... nothing wrong with using it, but maybe 'Pages' or something would be better? :) Like 'SchedulePages' or something like that

#6 formmailer

formmailer

    Sr. Member

  • Members
  • PipPipPipPip
  • 245 posts
  • 28

  • LocationHudiksvall, Sweden (but originally from The Netherlands)

Posted 02 December 2011 - 04:52 PM

I agree with Antti that a great upgrade would be to have a little finer control (maybe down to the hour?) whether in this version or some future version.

I actually thought about this, but since I only used a date field in this release, it didn't seem necesary to run more than once a day. But I will add (half)hour support as well.
Just for those who don't like LazyCron, it's also possible to run this plugin from a specific template, with the following:
<?php 
$SchedulePages = $modules->get("SchedulePages");
$SchedulePages->RunSchedulePages();

This would allow you to set-up a real cron job using wget or curl, just to activate the scheduling function. But just now this doesn't add antything since the date fields are set to midnight.
As I can see the current date picker doesn't support times, or does it? This would almost be a requirement for adding time support to this module.

Another nice upgrade would be having your module install/uninstall the publish_from and publish_until fields automatically. I'll be happy to show you how to do this if you'd like?

That would be great! I tried to find out how to do that, but gave up after a while.
And while you are at it: would it be possible to create a FieldsetTab (called Schedule) as well and add this with a single click (or drag-n-drop) to a template? It would be great if these scheduled dates alway would appear in their own Schedule tab without having a user creating the FielssetTab field and add the date fields in it.

Edit: also wanted to add: you might want to just call the module 'SchedulePosts' rather than ProcessSchedulePosts. That's because 'Process' is meant to refer to modules that extend the 'Process' module type (i.e. interactive admin modules). Also, 'Posts' is not a term that's used in ProcessWire... nothing wrong with using it, but maybe 'Pages' or something would be better? :) Like 'SchedulePages' or something like that

Good points. I changed the name, both for the module and the function.

/Jasper

#7 ryan

ryan

    Hero Member

  • Administrators
  • 5,773 posts
  • 3116

  • LocationAtlanta, GA

Posted 03 December 2011 - 11:40 AM

Here's how to create a new field from your install function:

<?php

public function ___install() {
    $field = new Field();
    $field->type = $this->modules->get("FieldtypeDatetime");
    $field->name = 'publish_from';
    $field->label = 'Publish From Date';
    $field->dateOutputFormat = wire('config')->dateFormat;
    $field->dateInputFormat = wire('config')->dateFormat;
    $field->datepicker = 1; // if you want datepicker enabled
    $field->defaultToday = 1; // if you want dates to default to today
    $field->save();
    // repeat for publish_until field
}

public function ___uninstall() {
    // only do the following if you want to uninstall the fields that were installed
    // this may be one thing that's safe to leave to the user
    $field = wire('fields')->get('publish_from'); 
    if($field && $field->numFieldgroups() > 0) 
        throw new WireException("Can't uninstall because field publish_from is still being used. Please remove it from any templates."); 
    wire('fields')->delete($field); 
    // repeat for publish_until field
}

Creating tabs is a little different because not only will you have to create the field, but you'll have to add it to fieldgroups. And I'm not sure how you determine what fieldgroups it should be added to. I think this is almost something that is better to leave to the user... or handle on the module's config settings, where they can check boxes next to the templates they want to have scheduled pages. If you are interested, I can help with that next week – my wife gives me crap about being on the computer on the weekend. :)


#8 formmailer

formmailer

    Sr. Member

  • Members
  • PipPipPipPip
  • 245 posts
  • 28

  • LocationHudiksvall, Sweden (but originally from The Netherlands)

Posted 03 December 2011 - 03:26 PM

Thanks Ryan, I didn't know that creating the new fields was so easy.  :)
I leave uninstalling the fields to the user, like you suggested.

I had the following idea regarding the schedule tab. It would be very nice if the plugin could add a "Do you want to enable scheduled publishing for this template-checkbox" on the Edit template page.
When this checkbox is checked a tab called "Schedule" should be created and it should contain the publish_from and publish_until fields.

Would it be possible to do something like this? I think this would be more user friendly than selecting templates in the module config.

my wife gives me crap about being on the computer on the weekend. :)


I know how that feels. :)

/Jasper

#9 formmailer

formmailer

    Sr. Member

  • Members
  • PipPipPipPip
  • 245 posts
  • 28

  • LocationHudiksvall, Sweden (but originally from The Netherlands)

Posted 02 January 2012 - 04:52 AM

Ryan,

...or handle on the module's config settings, where they can check boxes next to the templates they want to have scheduled pages. If you are interested, I can help with that next week – my wife gives me crap about being on the computer on the weekend. 

Do you have time to help me with this or my idea above (if that's possible to do it like that).

/Jasper

#10 ryan

ryan

    Hero Member

  • Administrators
  • 5,773 posts
  • 3116

  • LocationAtlanta, GA

Posted 02 January 2012 - 11:43 AM

Sorry, I forgot about this earlier. Here's how to add such a configuration option. First off, tell ProcessWire that your module will be configurable by adding 'implements ConfigurableModule', like this:

class SchedulePages extends WireData implements Module, ConfigurableModule {

Next, determine the name of the variable you will use to hold the template IDs: I'll use $scheduleTemplateIDs. Set that in your __construct() to initialize it as a known variable in your module:

<?php
public function __construct() {
    $this->set('scheduleTemplateIDs', array()); 
}

Now you need to implement the ConfigurableModule interface by adding a static function called getModuleConfigInputfields. It is static so that ProcessWire's Modules section can call upon it without actually initializing the module. Or to put it another way, it ensures that if you have CSS or JS files being loaded in your __construct() or init() then they won't be altering the display of the module configuration screen. :)

This function is given an array of the current configuration data saved with your module. If it's the first time your module is configured, it will very likely be empty.

<?php
static public function getModuleConfigInputfields(array $data) {

    // create a wrapper to hold our field(s)
    $form = new InputfieldWrapper(); 

    // set our default if this config var isn't already present
    if(!isset($data['scheduleTemplateIDs'])) $data['scheduleTemplateIDs'] = array(); 

    // create a field to select templates
    $f = wire('modules')->get('InputfieldCheckboxes');
    $f->label = 'Select the templates you want';
    $f->description = 'Additional description if you want it';
    $f->notes = 'Some optional extra notes at the bottom'; 
    $f->attr('name', 'scheduleTemplateIDs'); 

    // add the checkbox options
    foreach(wire('templates') as $template) {
        $f->addOption($template->id, $template->name); 
    }

    // set the current value
    $f->attr('value', $data['scheduleTemplateIDs']); 

    // add it to the form
    $form->add($f); 

    return $form; 
}

Now when the user clicks on your module in Admin > Modules, they will see checkboxes they can use. After they save, PW will now know to automatically send a $scheduleTemplateIDs var to your module every time it's loaded. That variable will be set before your module's init() is called. So you could do something like this in your init() or anywhere in your module:

<?php
$page = wire('page'); 
if(in_array($page->template->id, $this->scheduleTemplateIDs)) {
    // do something
} 


#11 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 20 March 2012 - 03:41 PM

Jasper, I just send you a pull request for this module. I added few minor features:
  • Checks publish dates right after saving, and keeps page unpublished if required.
  • Made module configurable to choose cron interval
  • Simplified the code little bit (took 2 unnecessary foreach loops out).
I had earlier done this kind of stuff on selector level, but this is much nicer - shows scheduled pages as unpublished on admin pagetree also.

#12 formmailer

formmailer

    Sr. Member

  • Members
  • PipPipPipPip
  • 245 posts
  • 28

  • LocationHudiksvall, Sweden (but originally from The Netherlands)

Posted 21 March 2012 - 02:54 AM

Thanks Antti! I just merged the request.
Good idea to check for the dates when saving. This eliminates the need of the 2 foreach loops. These were there to ensure that pages without a published until date would be published. But it's better to require a date. If the page needs to be there forever you someone can use a date in 2062 or something like that.

I like the configurable part for the cron interval. Thanks for adding this.

/Jasper

#13 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 21 March 2012 - 05:19 AM

Thanks Jasper. It was nice coding, since you had clean and well commented code.

About removing the foreach: I don't think I changed any functionality (at least not on purpose). There is still 2 foreach loops, but there were 4 before my commit. You had foreach where you removed certain items from PageArray, and after that another foreach where you published/unpublished those pages. Don't know if that has any real performance advantage, but it makes code shorter.


On page save I only check if:
a) You have publish_from > publish_until => don't publish, dates don't make any sense
b) publish_from > current time => don't publish, even if I try to publish
c) publish_until < current time => don't publish, even if I try to publish

#14 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 21 March 2012 - 07:27 AM

If the page needs to be there forever you someone can use a date in 2062 or something like that.


That was bug on my side, I didn't check that publish_until actually has a value. Fixed and send new pull request for you.

#15 formmailer

formmailer

    Sr. Member

  • Members
  • PipPipPipPip
  • 245 posts
  • 28

  • LocationHudiksvall, Sweden (but originally from The Netherlands)

Posted 21 March 2012 - 07:29 AM

Already merged. :)

Also updated README.

Edited by formmailer, 21 March 2012 - 07:59 AM.


#16 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 26 March 2012 - 01:23 AM

I translated this module, but it still uses default language. Is there some problems how I have coded those lang snippets: https://github.com/f...ges.module#L116 (like user lang is not defined at that point?).

#17 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 27 March 2012 - 09:29 AM

Hmm.. Another lang issue, now with Shop module. I am sure it did worked before and on the same site. Only thing I can think of is that now I have module folder as symlink, and module files in totally different folder (in both of these, Schedulepages and Shop). Could this cause the issue? Translator finds the files ok and lets translate without problems.

#18 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 27 March 2012 - 09:44 AM

That seems to be the issue, I tried this with AdminBar and same thing than with others. Modules seem to run fine from symlink, but multilang stuff fails then.

#19 ryan

ryan

    Hero Member

  • Administrators
  • 5,773 posts
  • 3116

  • LocationAtlanta, GA

Posted 27 March 2012 - 11:19 AM

You are right about this, because the module's path+file forms it's textdomain, and that's the primary key for PW to connect the file with the translations. I'm just wondering if I can somehow update the translation functions to use the location of the symlink rather than the path it point to. PW finds the textdomain by using the __FILE__ magic constant, and this returns the actual path of the file. I don't know if there is a way to get PHP to recognize the path of the symlink, at least not in a similar manner?

#20 apeisa

apeisa

    Hero Member

  • Moderators
  • 2,525 posts
  • 851

  • LocationVihti, Finland

Posted 11 June 2012 - 01:09 AM

Ryan, this might be helpful topic: http://stackoverflow...together-nicely

It would be great to run many modules as symlinks, makes maintaining so much easier.





Also tagged with one or more of these keywords: Module

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users