appy.pod: xhtml2odt: ability to include images from img tags (anonymously). Non-anonymous solution for a Appy/Zope server only; function 'document': allow to specify size of images in cm or px, or via a 'style' tag; appy.gen: allow to upload images in ckeditor fields; improved error management.
This commit is contained in:
parent
98fafad14a
commit
2bd3fe1eeb
10 changed files with 206 additions and 54 deletions
|
@ -2138,7 +2138,8 @@ class Pod(Type):
|
|||
stylesMapping = self.stylesMapping
|
||||
rendererParams = {'template': StringIO.StringIO(template.content),
|
||||
'context': podContext, 'result': tempFileName,
|
||||
'stylesMapping': stylesMapping}
|
||||
'stylesMapping': stylesMapping,
|
||||
'imageResolver': tool.o.getApp()}
|
||||
if tool.unoEnabledPython:
|
||||
rendererParams['pythonWithUnoPath'] = tool.unoEnabledPython
|
||||
if tool.openOfficePort:
|
||||
|
|
|
@ -21,7 +21,8 @@ homePage = '''
|
|||
</tal:main>
|
||||
'''
|
||||
errorPage = '''
|
||||
<tal:main define="tool python: context.config">
|
||||
<tal:main define="tool python: context.config"
|
||||
on-error="string: ServerError">
|
||||
<html metal:use-macro="context/ui/template/macros/main">
|
||||
<div metal:fill-slot="content" tal:define="o python:options">
|
||||
<p tal:condition="o/error_message"
|
||||
|
|
|
@ -1387,31 +1387,71 @@ class BaseMixin:
|
|||
for name in templateName.split('/'): res = getattr(res, name)
|
||||
return res
|
||||
|
||||
def download(self):
|
||||
'''Downloads the content of the file that is in the File field named
|
||||
p_name.'''
|
||||
def download(self, name=None):
|
||||
'''Downloads the content of the file that is in the File field whose
|
||||
name is in the request. This name can also represent an attribute
|
||||
storing an image within a rich text field. If p_name is not given, it is retrieved
|
||||
from the request.'''
|
||||
name = self.REQUEST.get('name')
|
||||
if not name: return
|
||||
appyType = self.getAppyType(name)
|
||||
if (not appyType.type =='File') or not appyType.isShowable(self,'view'):
|
||||
return
|
||||
if '_img_' not in name:
|
||||
appyType = self.getAppyType(name)
|
||||
else:
|
||||
appyType = self.getAppyType(name.split('_img_')[0])
|
||||
if not appyType.isShowable(self, 'view'):
|
||||
from zExceptions import NotFound
|
||||
raise NotFound()
|
||||
theFile = getattr(self.aq_base, name, None)
|
||||
if theFile:
|
||||
response = self.REQUEST.RESPONSE
|
||||
response.setHeader('Content-Disposition', 'inline;filename="%s"' % \
|
||||
theFile.filename)
|
||||
# Define content type
|
||||
if theFile.content_type:
|
||||
response.setHeader('Content-Type', theFile.content_type)
|
||||
response.setHeader('Cachecontrol', 'no-cache')
|
||||
response.setHeader('Expires', 'Thu, 11 Dec 1975 12:05:05 GMT')
|
||||
return theFile.index_html(self.REQUEST, self.REQUEST.RESPONSE)
|
||||
|
||||
def allows(self, permission):
|
||||
def upload(self):
|
||||
'''Receives an image uploaded by the user via ckeditor and stores it in
|
||||
a special field on this object.'''
|
||||
# Get the name of the rich text field for which an image must be stored.
|
||||
params = self.REQUEST['QUERY_STRING'].split('&')
|
||||
fieldName = params[0].split('=')[1]
|
||||
ckNum = params[1].split('=')[1]
|
||||
# We will store the image in a field named [fieldName]_img_[nb].
|
||||
i = 1
|
||||
attrName = '%s_img_%d' % (fieldName, i)
|
||||
while True:
|
||||
if not hasattr(self.aq_base, attrName):
|
||||
break
|
||||
else:
|
||||
i += 1
|
||||
attrName = '%s_img_%d' % (fieldName, i)
|
||||
# Store the image. Create a fake File instance for doing the job.
|
||||
fakeFile = gen.File(isImage=True)
|
||||
fakeFile.name = attrName
|
||||
fakeFile.store(self, self.REQUEST['upload'])
|
||||
# Return the URL of the image.
|
||||
url = '%s/download?name=%s' % (self.absolute_url(), attrName)
|
||||
resp = "<script type='text/javascript'>window.parent.CKEDITOR.tools" \
|
||||
".callFunction(%s, '%s');</script>" % (ckNum, url)
|
||||
self.REQUEST.RESPONSE.write(resp)
|
||||
|
||||
def allows(self, permission, raiseError=False):
|
||||
'''Has the logged user p_permission on p_self ?'''
|
||||
return self.getUser().has_permission(permission, self)
|
||||
hasPermission = self.getUser().has_permission(permission, self)
|
||||
if not hasPermission and raiseError:
|
||||
from AccessControl import Unauthorized
|
||||
raise Unauthorized
|
||||
return hasPermission
|
||||
|
||||
def getEditorInit(self, name):
|
||||
'''Gets the Javascrit init code for displaying a rich editor for
|
||||
'''Gets the Javascript init code for displaying a rich editor for
|
||||
field named p_name.'''
|
||||
return "CKEDITOR.replace('%s', {toolbar: 'Appy'})" % name
|
||||
return "CKEDITOR.replace('%s', {toolbar: 'Appy', filebrowserUploadUrl:"\
|
||||
"'%s/upload'})" % (name, self.absolute_url())
|
||||
|
||||
def getCalendarInit(self, name, years):
|
||||
'''Gets the Javascript init code for displaying a calendar popup for
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<html metal:use-macro="context/ui/template/macros/main">
|
||||
<metal:fill fill-slot="content"
|
||||
tal:define="contextObj context/getParentNode;
|
||||
dummy python: contextObj.allows('Modify portal content', raiseError=True);
|
||||
errors request/errors | python:{};
|
||||
layoutType python:'edit';
|
||||
layout python: contextObj.getPageLayout(layoutType);
|
||||
|
@ -9,7 +10,8 @@
|
|||
phase phaseInfo/name;
|
||||
page request/page|python:'main';
|
||||
cssJs python: contextObj.getCssAndJs(contextObj.getAppyTypes(layoutType, page), layoutType);
|
||||
confirmMsg request/confirmMsg | nothing;">
|
||||
confirmMsg request/confirmMsg | nothing;"
|
||||
tal:on-error="structure python: tool.manageError(error)">
|
||||
|
||||
<tal:comment replace="nothing">Include type-specific CSS and JS.</tal:comment>
|
||||
<link tal:repeat="cssFile cssJs/css" rel="stylesheet" type="text/css"
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
<html metal:use-macro="context/ui/template/macros/main">
|
||||
<metal:fill fill-slot="content"
|
||||
tal:define="contextObj python: context.getParentNode();
|
||||
dummy python: contextObj.allows('View', raiseError=True);
|
||||
portal_type python: context.portal_type.lower().replace(' ', '_');
|
||||
errors python: req.get('errors', {});
|
||||
layoutType python:'view';
|
||||
layout python: contextObj.getPageLayout(layoutType);
|
||||
phaseInfo python: contextObj.getAppyPhases(currentOnly=True, layoutType='view');
|
||||
page req/page|python:'main';
|
||||
phase phaseInfo/name;">
|
||||
phase phaseInfo/name;"
|
||||
tal:on-error="structure python: tool.manageError(error)">
|
||||
<metal:prologue use-macro="context/ui/page/macros/prologue"/>
|
||||
<metal:show use-macro="context/ui/page/macros/show"/>
|
||||
<metal:footer use-macro="context/ui/page/macros/footer"/>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue