Changing Portal Transforms Settings via Python

erstellt von Johannes Raggam — 29.03.2010 15:45

If you have to change some portal_transforms settings you can't use a Generic Setup config file for this (as of 2010-03-25, Products.PortalTransforms 2.0b4). But you can change it with python and a Generic Setup import step. Here's how to do it.

Warning: Security: The configuration shown below allows users to use nasty HTML tags which can be a security issue if not used carefully.

Let's say we have a plone package called MY.PACKAGE.

Writing an Generic Setup Import Step Method

This setup method is definded in MY.PACKAGE/setuphandlers.py. It configures the safe_html portal_transform a bit less paranoid about nasty tags and valid_tags, so that content managers are allowed to insert iframe, object, embed, param, script, style, tags and more into the TinyMCE editor:

import logging
from Products.CMFCore.utils import getToolByName
from Products.PortalTransforms.Transform import make_config_persistent

logger = logging.getLogger('MY.PACKAGE.setuphandlers')

def isNotThisProfile(context, marker_file):
    return context.readDataFile(marker_file) is None

def setup_portal_transforms(context):
    if isNotThisProfile(context, 'MY.PACKAGE-PROFILENAME.txt'): return

    logger.info('Updating portal_transform safe_html settings')

    tid = 'safe_html'

    pt = getToolByName(context, 'portal_transforms')
    if not tid in pt.objectIds(): return

    trans = pt[tid]

    tconfig = trans._config
    tconfig['class_blacklist'] = []
    tconfig['nasty_tags'] = {'meta': '1'}
    tconfig['remove_javascript'] = 0
    tconfig['stripped_attributes'] = ['lang', 'valign', 'halign', 'border',
                                     'frame', 'rules', 'cellspacing',
                                     'cellpadding', 'bgcolor']
    tconfig['stripped_combinations'] = {}
    tconfig['style_whitelist'] = ['text-align', 'list-style-type', 'float',
                                  'width', 'height', 'padding-left',
                                  'padding-right'] # allow specific styles for
                                                   # TinyMCE editing
    tconfig['valid_tags'] = {
        'code': '1', 'meter': '1', 'tbody': '1', 'style': '1', 'img': '0',
        'title': '1', 'tt': '1', 'tr': '1', 'param': '1', 'li': '1',
        'source': '1', 'tfoot': '1', 'th': '1', 'td': '1', 'dl': '1',
        'blockquote': '1', 'big': '1', 'dd': '1', 'kbd': '1', 'dt': '1',
        'p': '1', 'small': '1', 'output': '1', 'div': '1', 'em': '1',
        'datalist': '1', 'hgroup': '1', 'video': '1', 'rt': '1', 'canvas': '1',
        'rp': '1', 'sub': '1', 'bdo': '1', 'sup': '1', 'progress': '1',
        'body': '1', 'acronym': '1', 'base': '0', 'br': '0', 'address': '1',
        'article': '1', 'strong': '1', 'ol': '1', 'script': '1', 'caption': '1',
        'dialog': '1', 'col': '1', 'h2': '1', 'h3': '1', 'h1': '1', 'h6': '1',
        'h4': '1', 'h5': '1', 'header': '1', 'table': '1', 'span': '1',
        'area': '0', 'mark': '1', 'dfn': '1', 'var': '1', 'cite': '1',
        'thead': '1', 'head': '1', 'hr': '0', 'link': '1', 'ruby': '1',
        'b': '1', 'colgroup': '1', 'keygen': '1', 'ul': '1', 'del': '1',
        'iframe': '1', 'embed': '1', 'pre': '1', 'figure': '1', 'ins': '1',
        'aside': '1', 'html': '1', 'nav': '1', 'details': '1', 'u': '1',
        'samp': '1', 'map': '1', 'object': '1', 'a': '1', 'footer': '1',
        'i': '1', 'q': '1', 'command': '1', 'time': '1', 'audio': '1',
        'section': '1', 'abbr': '1'}
    make_config_persistent(tconfig)
    trans._p_changed = True
    trans.reload()

 

Registering the Import Step Method with Generic Setup

Add an import step in MY.PACKAGE/MYPROFILESDIR/PROFILENAME/import_steps.xml like so:

<?xml version="1.0"?>
<import-steps>
  <import-step
    id="MY.PACKAGE-portal_transforms"
    handler="MY.PACKAGE.setuphandlers.setup_portal_transforms"
    title="MY.PACKAGE portal_transforms setup"
    version="1.0">
    <dependency step="plone-final"/>
  </import-step>
</import-steps>

And create the File MY.PACKAGE/MYPROFILESDIR/PROFILENAME/MY.PACKAGE-PROFILENAME.txt, so that this import step is not run for any profile but just for this one.

Calling the Import Step Method in ZMI, portal_setup

Goto your site's portal_setup in ZMI, select your registered profile and import the import step "MY.PACKAGE portal_transforms setup". That's it.

 

This HowTo is also available in the collective.developermanual.
Artikelaktionen
2 Comments
20.04.2010 15:05 - http://claimid.com/thet wrote

table widths with tinymce

i updated the setup_portal_transforms method in the article to allow tinymce to change the table width and height and persist these settings.

for that, width and height must be added to the style_whitelist of portal_transforms.
20.04.2010 16:23 - Johannes Raggam wrote

paragraph paddings

now also with paragraph paddings. those are done with padding-left.

Speedup: Plone 4 and Caching

erstellt von Jens W. Klein — 15.03.2010 16:25

plone.app.caching (et al) speeds up Plone 4

Austrian EurofighterPlone 4 is much faster than Plone ever was. But anyway, you want caching in front of it. So I do.

We're using the chain browser -> nginx -> varnish [-> pound] -> Zope -> (ZEO).

Plan is to

  1. let the browser cache as much as possible,
  2. let varnish cache as much as possible,
  3. let Zope purge pages in varnish after update.

With Plone 4 we get a complete new caching infrastructure. Its plone.app.caching and its dependencies plone.caching, z3c.caching, plone.cachepurging and plone.transformchain.

Now, at time of writing, Plone 4 is beta and all caching infrastructure is alpha. To make it work you better take it from subversion. Take your buildout (with mr.developer as usal) and modify it like so:

[buildout]
# ...
auto-checkout +=
#   ...    
    plone.app.caching
    plone.cachepurging
    plone.caching
    z3c.caching
    plone.transformchain

# ...

[sources]
# ...
plone.app.caching = svn https://svn.plone.org/svn/plone/plone.app.caching/trunk/
plone.cachepurging = svn https://svn.plone.org/svn/plone/plone.cachepurging/trunk/
plone.caching = svn https://svn.plone.org/svn/plone/plone.caching/trunk/
z3c.caching = svn http://svn.zope.org/repos/main/z3c.caching/trunk/
plone.transformchain = svn https://svn.plone.org/svn/plone/plone.transformchain/trunk/

[versions]
# ...
z3c.form = 2.2.0

[instance]
eggs = 
#   ...
    plone.app.caching

Now let buildout run, (re)start your instance and apply the profile of plone.app.caching (HTTP caching support).

In Plones control panel theres now a new item Caching - here you get verbose instructions how to configure it.

Photo by dugspr at Flickr under CC-License.

Artikelaktionen
0 Comments

Redirect FTP in Zope

erstellt von Peter Holzer — 16.12.2009 19:20

Since no FTP-Proxy could provide me a directive for a destination folder, i wrote a really small patch.

path.jpg

betabug: ftp is meant for the dumpster of digital technology anyway
hpeter: webdav is already running ... client wants ftp
hpeter: that's why i tried ftp-proxy
betabug: hpeter: state security concerns, ftp is insecure, webdav can be run over https
betabug: only terrorists use ftp
betabug: or worse: if we still use ftp, the terrorists have won!

 

[Fill in Usual Disclaimers] + You don't want to do this on a shared instance since your're patching the ftp-server of your instance!

I found the suspected code in the __init__ method of zope_ftp_channel in ZServer/FTPServer.py.

You only have to change self.path='/' into self.path='/[whatevernameyouwant]' and your entering path for ftp will change to that url. You can still do a CWD and enter any other directory you have the permission to.

from ZServer.medusa.ftp_server import ftp_channel
from ZServer import requestCloseOnExec
from ZServer.FTPServer import zope_ftp_channel 

def patched_ftp__init__ (self, server, conn, addr, module):
    ftp_channel.__init__(self,server,conn,addr)
    requestCloseOnExec(conn)
    self.module=module
    self.userid=''
    self.password=''
    self.path='/plone'
    self.cookies={}

print "patched ftp root for login redirection"

zope_ftp_channel.__init__ = patched_ftp__init__

I'm certain there is a better, nicer,... way of doing this, that's the nature of a patch ;-)

 

Picture by Egan Snow under cc by-sa http://www.flickr.com/photos/egansnow/268912449/

Artikelaktionen

Tasty Tasty Soup: cornerstone.soup

erstellt von Jens W. Klein — 03.12.2009 10:55

Version 1.0 of the isolated container for queryable records released.

Soup CansYesterday I meet Robert to finish work on cornerstone.soup after our cologne alliance partner Sven found an odd bug. We simplified the soup recipe, but now its really yummy. Version 1.0 is released.

cornerstone.soup is a genric storage for mass-data in an isolated container. Light-weight records are stored in an IOBTree. A Zope-Tool-Kit catalog in used to index values of interest. cornerstone.soup is no out-of-the-box package. Its addressed to developers needing to solve the problem of storing tiny entities of mass-data, where heavy weight archetypes or dexterity are too much effort and are to slow. I.e if you need a container for non-CMSish content, like votes, data from a poll, orders in a webshop, measuring data, or alike.

Isolated means, for each soup we store all in one persistent local utility. Stored are generic „Records“ which are persistent items with attributes passed in at construction time as keyword arguments. Also the catalog with its indexes is part of the local utility. Items are accessed by query.

We tested the soup with Zope 2.10 and Zope 2.12. It works in a plain Zope. We are using it at the moment in a Plone 3.3

For more information read the documentation at pypi: cornerstone.soup.

Artikelaktionen
0 Comments

AGX: A Generator for X (eggs)

erstellt von Jens W. Klein — 28.11.2009 12:20

Today is the third day of sprint - restrospective on the first two.

AGX sprint participantsNow after two successful days of the sprint  we have a good outcome.

Michael Launay and Vincent Fretin from Ecreall  (Lille/ France) arrived Wednesday evening after a 1000km car-ride and joined Robert and Jens at BlueDynamics Office in Innsbruck Thursday morning. After synchronizing our minds showing what was done so far we started pair-programming. We expected Gogo from Vienna to join us in the evening, but he got ill and was not able to get on his flight. But fortunately he started to help out remotely.

Michael + Jens worked on the UML internal model. The import of XMI to UML, and the internal model (class-diagram) representaion was already finished by Jens and Robert in the last 3 weeks. Now the real difficult work had to be done: Get useful information out of the model. We wrote some convinience classes following roughly the adpater pattern (but not using ZCA here). Its all tested and documented by doctests - I'd say we have a very good coverage. Most of the time was needed to find the edge-cases in modelling.

Vincent + Robert paired to work on the transformation and generation of Python-code. The connection of the transformations as a chain works now. The generation for filesystem-structures is almost done. Python generation is work in progress and task for today. Gogo helped here by taking specific tasks. All code is tested and documented with doctests as well.

Today we plan to finish the UML convinience API and get the core work for Python-code-representation in a tree done. If this is done we can start writing our first real code generation chain: And what will it be? No, not Plone-code: We will generate AGX-generators! This means: python eggs, packages, modules, methods, classes and decorators.

for the agx-sprint team

-- Jensens

Artikelaktionen
0 Comments
1 2 3 4 5 6 7 8 9 ...