Skip to content. | Skip to navigation

Navigation

You are here: Home / Support / Guides / Tools / Plone / Plone 3 Themes / PloneFormGen and jscalendar

Personal tools

Plone 3 Themes

How to (customize) a Plone 3 Theme

PloneFormGen and jscalendar

PloneFormGen is a Plone Product for creating forms. It allows you to add a Date/Time field and then the rabbit hole opened...

The field let's you use some pull down menus or a JavaScript popup widget to select a date. The popup had no styling whatsoever.

It turns out the jscalendar is a third party product in Plone from dynarch.com (in particular, version 1.0). It does all the usual stuff. Except without a stylesheet.

Stylesheets

It took me a long time to fathom that, despite their presence in portal_styles; plone_3rdparty; jscalendar the stylesheets were simply not being called upon. There's two reasons for that.

portal_css

Plone is not generating any code to reference the stylesheets. To convince it otherwise you need to add a reference to a jscalendar stylesheet.

Go to Site Setup; ZMI; portal_css and whizz down to the bottom. Add a new entry with:

field value
id/URL calendar-theme.css
CSS media screen

and click save.

If you then scroll down to the bottom again Plone will probably be whinging about it being missing. Which it is.

calendar-theme.css

Create a new stylesheet in .../skins/plonetheme_mytheme_styles called calendar-theme.css and put in it the contents of customizing portal_styles; plone_3rdparty; jscalendar; theme.css. Or one of the other stylesheets if you prefer.

The immediate problem with this is that it will be missing a dozen GIFs which it uses for background URLs when the mouse moves over various elements in the popup.

You can copy all of the referenced GIFs into .../skins/plonetheme_mytheme_custom_images but I didn't like them (too many horizontal lines!) and replaced all but one of them with a suitable background-color.

The remaining GIF is menuarrow.gif which I put in a jscalendar subdirectory and edited the background-url appropriately.

I couldn't put calendar-theme.css in a jscalendar subdirectory, it wouldn't be discovered.

Overrides

You can set some default values for the Date/Time field but they are fixed and not incredibly useful. You can set some "dynamic" overrides (the override itself isn't dynamic by the resultant value is).

The default value should be a TALES expression which can be python: followed by any legal Python expression. So long as you know what is in scope...

What I wanted to do was not merely set the default date to be today (which would be DateTime()) but rather set it to be the first Monday at least two weeks from now. This would be more than the minimum lead time for the service in question and you want it to be defaulting to a Monday because otherwise, if someone is browsing on a Saturday, the default value being a Saturday just looks daft.

Python has plenty of datetime operators available (strftime, weekday, strptime even) but every invocation fell over. Searching on plone tales datetime would occasionally drop me at the Zope API Reference Appendix B with the helpful comments that the cost of maintaining the documentation was too hard, please read the source code. RTFS, indeeed!

Eventually, I found the old Zope API Appendix B which reveals lots of anachronistic functions (dow for weekday: why?) and that DateTime() would accept a string as an argument that it would filter through strptime to generate a date. There's hope!

Default

So, we can now have the following expression to initialise the date on a Monday at least two weeks hence:

DateTime() + 21 - DateTime().dow() + 1

as (obviously) integer arithmetic means days. So we need to go three weeks days forward and then dow days backwards and correct for dow() (dow() starts with Sunday as 0) to get back to that Monday.

Validator

We can also define a validator in the same way. value will have the form YYYY-mm-dd HH:MM which is perfectly suited for DateTime() to parse and we use the suggested:

test(value=='eggs', False, 'input must be eggs')

format to get:

test(DateTime(value).dow() in [ 1, 2, 3, 4, 5], False, DateTime(value).strftime("%d %b %Y") + " is a weekend")

to ensure the requested date is not a weekend.

A Python Script Validator

TALES and test are very limiting and as documented here you can use a Python Script with much greater flexibility.

Add the Python Script

Go To Site Setup; ZMI; navigate your site through to the PloneFormGen folder and add a Script (Python) and give it an id of, say, dateValidator.

Edit the script with:

field  
Parameter List value

ie, value is going to be made available to the script as a bound variable.

The script itself might look like:

if DateTime(value).dow() in [ 0, 6]:
   return DateTime(value).strftime("%d %b %Y") + " is a weekend "
if DateTime(value).dow() in [ 5]:
   return DateTime(value).strftime("%d %b %Y") + " is a Friday "
else:
   return False

noting that you should return False when you're happy the date is OK and some pertinent string otherwise.

Validator

Change the validator in Overrides to:

python: folder.dateValidator(value)

Document Actions