Filtered by Zope

Page 4

Reset

MUnderscorePatch - tired of typing manage_main?

November 29, 2006
0 comments Zope

I often use the Zope management interface but not to do much ZMI like stuff. Just simple things like creating new base objects, changing properties or testing a change to a template. For some reason I seem to lack the ability to spell the word manage_main. I can't remember how many times I've accidently typed manage-main , mange_main, manag_main, manage)_main etc.

There's got to be an end to that! Hence the MUnderscorePatch monkey patch. Now, all I have to do is to type in m_ at the end of the URL and it becomes the same as manage_main. Ie. I go to http://localhost:8080/ then I append m_ so that it becomes http://localhost:8080/m_ and it redirects automatically to http://localhost:8080/manage_main

Silly but actually quite useful for me. Want to download it too?

Sending HTML emails in Zope

October 26, 2006
3 comments Zope

Here are a few lessons learnt when sending HTML emails in Zope with unicode data. I'm still a beginner with this stuff and still probably have a lot to learn. What I've achived now works but might break with different encodings or on different systems so don't assume that these patterns will work in your setup.

To the send the email I'm using the default MailHost that comes with Zope 2.8.5. I call it's send() passing the subject line a second time because the subject line is already in the body string.

The most valuable piece of magic to learn and remember from this is that when you construct the multi-part message you have to attach the plain text before the html text. Thank you Lukasz Lakomy for that tip!

Here's the code that constructs the message and send it:


# -*- coding: iso-8859-1 -*-
e_subject = u'Provsprängning'
e_from = u'some@spammer.com'
e_to = u'some@receiver.com'
body_html = u'<html>provsprängningen <em>av</em> kärnvapen</html>'
body_plain = u'provsprängningen *av* kärnvapen'

mime_msg = MIMEMultipart('related')
mime_msg['Subject'] = e_subject
mime_msg['From'] = e_from
mime_msg['To'] = e_to
mime_msg.preamble = 'This is a multi-part message in MIME format.'

# Encapsulate the plain and HTML versions of the message body 
# in an 'alternative' part, so message agents can decide 
# which they want to display.
msgAlternative = MIMEMultipart('alternative')
mime_msg.attach(msgAlternative)

# plain part
msg_txt = MIMEText(body,  _charset='iso-8859-1')
msgAlternative.attach(msg_txt)

# html part
msg_txt = MIMEText(rendered_html, _subtype='html', 
                   _charset='iso-8859-1')
msgAlternative.attach(msg_txt)

self.MailHost.send(mime_msg.as_string())

Comparing Ruby and PHP

September 21, 2006
0 comments Zope

I was reading Of snakes and rubies; Or why I chose Python over Ruby which is an article comparing Python and Ruby. The blog article has loads of comments. This one I liked in particular

"For people writing good production code in PHP, I'm not trying to pile on - I know you get disrespected enough. It's possible to write well-structured sites on PHP, and lots of you do. It's just that in PHP, anyone can learn how to create spaghetti code in 10 minutes, but you have to learn a decent-sized body of knowledge to gain the ability to separate presentation from logic. By contrast, when novices get started in Rails, they're using good structure by default. They have to make an effort to screw it up."

That is soo true! Because you have to do Rails in the Rails way and (unless you're exceptional) in no other way, all your apps will follow a certain clean standard.

Why am I pointing this out? Because Zope2 is just as bad as PHP in this way. A lot of beginners use Zope's web interface (aka. Zope Management Interface, ZMI) to write code for their web sites and web apps. That's the equivalent of a non-guru PHP developer who naively mixes SQL with CSS with HTML with business logic all in one document. Not good. Or is it?

I'm about to slowly leave Zope2 for Zope3 where things are really strict. Apparently, the reason why the configuration is done in XML is to force people to not mess up their code. At first I was very reluctant to this almost arrogant approach. PHP is not successful because of technical raw power but because of thoughtlessness. You don't have to change gears, turn, break, check mirrors and throttle to get started. Just apply more gas!

Perhaps the Zope community can learn something from Rails here. Getting started should be PHP-like easy and moving from "Hello World!" towards something much more complicated should be done in a strict fashion.

I know I did. At Fry-IT we have command line tools that allow you to create a structured (filesystem based) web app filled with folders, stubs, standard templates and blank .py files where you fill in the blanks and within minutes you have a well structured codebase. It's not as good as the Rails tools but he idea is the same. Let's learn from PHP and Rails, a non-PhD threshold to get started to skip boilerplate stuff and a set one way to do it once you've started.

TinyMCE + Zope = ZTinyMCE

June 1, 2006
8 comments Zope

ZTinyMCE in action This is my first release of ZTinyMCE. ZTinyMCE makes it easy to use TinyMCE, the best Open Source WYSIWYG editor in my opinion.

We at Fry-IT use this a lot for our websites as shown in the screenshots. The ZTinyMCE product works only with Zope2. Once you have it installed and you have created a ZTinyMCE instance in your root plus a ZTinyMCE Configuration object called "tinymce.conf" all you have to do to convert a plain page of HTML with textareas to a plain page of HTML with WYSIWYG textareas is this:


<script tal:replace="structure here/tinymce.conf">
</script>

Setting security declarations to Zope classes

February 2, 2006
5 comments Python, Zope

If you're into Zope python product stuff, read on, otherwise don't bother.

Thanks to Brian Lloyd (Zope corp) and Florent Guillaume (Nuxeo) I now know how to set security declarations on a class outside the class. It doesn't work like a normal python class (new or old style) which was a bit of a surprise. This is how you do it in a "normal" python class:


class _Z:
  def __init__(self):
      self.z = "Z"
  def declareProtected(self, *a,**k):
      print "++declare something+"

def foo():
  print "I'm being called"
  return _Z()

class A:
  security=foo()
  def __init__(self):
      pass
A.security.declareProtected("foo")

When you import or run that it spits out:


I'm being called
++declare something+

Now imagine this python product class:


class MyProduct(OFS.Folder):
   security=ClassSecurityInfo()
   security.declareProtected('View', 'rss')
   def rss(self):

setattr(MyProduct, 'rss.xml', MyProduct.rss)
MyProduct.security.declareProtected('View', 'rss.xml')

Apart from the last line this should look very familiar to Zope python product developers. In principle it's the same as the dummy example above, but it doesn't work. You get an AttributeError on security on that last line.

As Florent explains:

"That's because for all classes deriving from ExtensionClass there's a magical call (indirectly) to InitializeClass as soon as they are defined. That's one of the numerous things Jim pioneered with ExtensionClasses, at a time where metaclasses didn't exist."

Thanks to Brians tips I've now found the correct way of doing it which is this:


class MyProduct(OFS.Folder):
   security=ClassSecurityInfo()
   security.declareProtected('View', 'rss')
   def rss(self):

setattr(MyProduct, 'rss.xml', MyProduct.rss)
#MyProduct.security.declareProtected('View', 'rss.xml')
security = ClassSecurityInfo()
security.declareProtected('View', 'rss.xml')
security.apply(MyProduct)

Worth remembering because with more recent version of Zope2 you get annoying warning messages if you declare security settings on methods that aren't defined until (perhaps in a loop) after the class has been defined.

Thanks for the advice guys!