class TinyMCEControlPanelForm(ControlPanelForm): """TinyMCE Control Panel Form""" implements(ITinyMCEControlPanelForm) tinymcelayout = FormFieldsets(ITinyMCELayout) tinymcelayout.id = 'tinymcelayout' tinymcelayout.label = _(u'Layout') tinymcetoolbar = FormFieldsets(ITinyMCEToolbar) tinymcetoolbar.id = 'tinymcetoolbar' tinymcetoolbar.label = _(u'Toolbar') tinymcelibraries = FormFieldsets(ITinyMCELibraries) tinymcelibraries.id = 'tinymcelibraries' tinymcelibraries.label = _(u'Libraries') tinymceresourcetypes = FormFieldsets(ITinyMCEResourceTypes) tinymceresourcetypes.id = 'tinymceresourcetypes' tinymceresourcetypes.label = _(u'Resource Types') form_fields = FormFieldsets(tinymcelayout, tinymcetoolbar, tinymceresourcetypes, tinymcelibraries) label = _(u"TinyMCE Settings") description = _(u"Settings for the TinyMCE Wysiwyg editor.") form_name = _("TinyMCE Settings")
class TinyMCEControlPanelForm(ControlPanelForm): """TinyMCE Control Panel Form""" implements(ITinyMCEControlPanelForm) tinymcelayout = FormFieldsets(ITinyMCELayout) tinymcelayout.id = 'tinymcelayout' tinymcelayout.label = _(u'Layout') tinymcetoolbar = FormFieldsets(ITinyMCEToolbar) tinymcetoolbar.id = 'tinymcetoolbar' tinymcetoolbar.label = _(u'Toolbar') tinymcelibraries = FormFieldsets(ITinyMCELibraries) tinymcelibraries.id = 'tinymcelibraries' tinymcelibraries.label = _(u'Libraries') tinymceresourcetypes = FormFieldsets(ITinyMCEResourceTypes) tinymceresourcetypes.id = 'tinymceresourcetypes' tinymceresourcetypes.label = _(u'Resource Types') form_fields = FormFieldsets( tinymcelayout, tinymcetoolbar, tinymceresourcetypes, tinymcelibraries ) label = _(u"TinyMCE Settings") description = _(u"Settings for the TinyMCE Wysiwyg editor.") form_name = _("TinyMCE Settings") @form.action(__(u'label_save', default=u'Save'), name=u'save') def handle_edit_action(self, action, data): CheckAuthenticator(self.request) if form.applyChanges(self.context, self.form_fields, data, self.adapters): self.status = __("Changes saved.") notify(ConfigurationChangedEvent(self, data)) self._on_save(data) else: self.status = __("No changes made.") @form.action(__(u'label_cancel', default=u'Cancel'), validator=null_validator, name=u'cancel') def handle_cancel_action(self, action, data): IStatusMessage(self.request).addStatusMessage(__("Changes canceled."), type="info") portal = getToolByName(self.context, name='portal_url')\ .getPortalObject() url = getMultiAdapter((portal, self.request), name='absolute_url')() self.request.response.redirect(url + '/plone_control_panel') return ''
def getConfiguration(self, context=None, field=None, request=None): results = {} # Get widget attributes widget = getattr(field, 'widget', None) filter_buttons = getattr(widget, 'filter_buttons', None) allow_buttons = getattr(widget, 'allow_buttons', None) redefine_parastyles = getattr(widget, 'redefine_parastyles', None) parastyles = getattr(widget, 'parastyles', None) rooted = getattr(widget, 'rooted', False) toolbar_width = getattr(widget, 'toolbar_width', self.toolbar_width) # Get safe html transform safe_html = getattr(getToolByName(self, 'portal_transforms'), 'safe_html') # Get kupu library tool filter # Settings are stored on safe_html transform in Plone 4 and # on kupu tool in Plone 3. kupu_library_tool = getToolByName(self, 'kupu_library_tool', None) # Remove to be stripped attributes try: style_whitelist = safe_html.get_parameter_value('style_whitelist') except (KeyError, AttributeError): if kupu_library_tool is not None: style_whitelist = kupu_library_tool.getStyleWhitelist() else: style_whitelist = [] results['valid_inline_styles'] = style_whitelist # Replacing some hardcoded translations labels = {} labels['label_styles'] = translate(_('(remove style)'), context=request) labels['label_paragraph'] = translate(_('Normal paragraph'), context=request) labels['label_plain_cell'] = translate(_('Plain cell'), context=request) labels['label_style_ldots'] = translate(_('Style...'), context=request) labels['label_text'] = translate(_('Text'), context=request) labels['label_tables'] = translate(_('Tables'), context=request) labels['label_selection'] = translate(_('Selection'), context=request) labels['label_lists'] = translate(_('Lists'), context=request) labels['label_print'] = translate(_('Print'), context=request) labels['label_no_items'] = translate(_('No items in this folder'), context=request) labels['label_no_anchors'] = translate(_('No anchors in this page'), context=request) results['labels'] = labels # Add styles to results results['styles'] = [] results['table_styles'] = [] if not redefine_parastyles: if isinstance(self.tablestyles, StringTypes): for tablestyle in self.tablestyles.split('\n'): if not tablestyle: # empty line continue tablestylefields = tablestyle.split('|') tablestyletitle = tablestylefields[0] tablestyleid = tablestylefields[1] if tablestyleid == 'plain': # Do not duplicate the default style hardcoded in the # table.htm.pt continue if request is not None: tablestyletitle = translate(_(tablestylefields[0]), context=request) results['styles'].append(tablestyletitle + '|table|' + tablestyleid) results['table_styles'].append(tablestyletitle + '=' + tablestyleid) if isinstance(self.styles, StringTypes): styles = [] for style in self.styles.split('\n'): if not style: # empty line continue stylefields = style.split('|') styletitle = stylefields[0] if request is not None: styletitle = translate(_(stylefields[0]), context=request) merge = styletitle + '|' + '|'.join(stylefields[1:]) styles.append(merge) results['styles'].extend(styles) if parastyles is not None: results['styles'].extend(parastyles) # Get buttons from control panel results['buttons'] = self.getEnabledButtons(context=context) # Filter buttons if allow_buttons is not None: allow_buttons = self.translateButtonsFromKupu( context=context, buttons=allow_buttons) results['buttons'] = filter(lambda x: x in results['buttons'], allow_buttons) if filter_buttons is not None: filter_buttons = self.translateButtonsFromKupu( context=context, buttons=filter_buttons) results['buttons'] = filter(lambda x: x not in filter_buttons, results['buttons']) # Get valid html elements results['valid_elements'] = self.getValidElements() # Set toolbar_location if self.toolbar_external: results['toolbar_location'] = 'external' else: results['toolbar_location'] = 'top' if self.autoresize: results['path_location'] = 'none' results['resizing_use_cookie'] = False results['resizing'] = False results['autoresize'] = True else: results['path_location'] = 'bottom' results['resizing_use_cookie'] = True if self.resizing: results['resizing'] = True else: results['resizing'] = False results['autoresize'] = False if '%' in self.editor_width: results['resize_horizontal'] = False else: results['resize_horizontal'] = True try: results['editor_width'] = int(self.editor_width) except (TypeError, ValueError): results['editor_width'] = 600 try: results['editor_height'] = int(self.editor_height) except (TypeError, ValueError): results['editor_height'] = 400 try: results['toolbar_width'] = int(toolbar_width) except (TypeError, ValueError): results['toolbar_width'] = 440 if self.directionality == 'auto': language = context.Language() if not language: portal_properties = getToolByName(context, "portal_properties") site_properties = portal_properties.site_properties language = site_properties.getProperty('default_language', None) directionality = (language[:2] in RIGHT_TO_LEFT) and 'rtl' or 'ltr' else: directionality = self.directionality results['directionality'] = directionality if self.contextmenu: results['contextmenu'] = True else: results['contextmenu'] = False portal = getSite() results['portal_url'] = aq_inner(portal).absolute_url() nav_root = getNavigationRootObject(context, portal) results['navigation_root_url'] = nav_root.absolute_url() if self.content_css and self.content_css.strip() != "": results['content_css'] = self.content_css else: results['content_css'] = '/'.join( [results['portal_url'], self.getId(), "@@tinymce-getstyle"]) if self.link_using_uids: results['link_using_uids'] = True else: results['link_using_uids'] = False if self.allow_captioned_images: results['allow_captioned_images'] = True else: results['allow_captioned_images'] = False if self.rooted or rooted: results['rooted'] = True else: results['rooted'] = False results['customplugins'] = [] if self.customplugins is not None: results['customplugins'].extend(self.customplugins.split('\n')) results['entity_encoding'] = self.entity_encoding props = getToolByName(self, 'portal_properties') livesearch = props.site_properties.getProperty('enable_livesearch', False) if livesearch: results['livesearch'] = True else: results['livesearch'] = False AVAILABLE_LANGUAGES = set( 'sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl ' 'ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa ' 'pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr tw uk ur cy vi zu' .split()) if 'LANGUAGE' in context.REQUEST: results['language'] = context.REQUEST.LANGUAGE[:2] if results['language'] not in AVAILABLE_LANGUAGES: results['language'] = "en" else: results['language'] = "en" try: results['document_url'] = context.absolute_url() parent = aq_parent(aq_inner(context)) if getattr(aq_base(context), 'checkCreationFlag', None) and context.checkCreationFlag(): parent = aq_parent(aq_parent(parent)) results['parent'] = parent.absolute_url() + "/" else: if IFolderish.providedBy(context): results['parent'] = context.absolute_url() + "/" else: results['parent'] = parent.absolute_url() + "/" except AttributeError: results['parent'] = results['portal_url'] + "/" results['document_url'] = results['portal_url'] # Get Library options results['libraries_spellchecker_choice'] = \ self.libraries_spellchecker_choice # init vars specific for "After the Deadline" spellchecker mtool = getToolByName(portal, 'portal_membership') member = mtool.getAuthenticatedMember() results['atd_rpc_id'] = 'Products.TinyMCE-' + ( member.getId() or '') # None when Anonymous User results['atd_rpc_url'] = "%s/@@" % portal.absolute_url() results['atd_show_types'] = self.libraries_atd_show_types.strip( ).replace('\n', ',') results[ 'atd_ignore_strings'] = self.libraries_atd_ignore_strings.strip( ).replace('\n', ',') return json.dumps(results)
def upload(self): """Adds uploaded file""" object = aq_inner(self.context) if not IFolderish.providedBy(object): object = object.getParentNode() context = self.context request = context.REQUEST ctr_tool = getToolByName(self.context, 'content_type_registry') id = request['uploadfile'].filename content_type = request['uploadfile'].headers["Content-Type"] typename = ctr_tool.findTypeName(id, content_type, "") # Permission checks based on code by Danny Bloemendaal # 1) check if we are allowed to create an Image in folder if not typename in [t.id for t in context.getAllowedTypes()]: return self.errorMessage(_("Not allowed to upload a file of this type to this folder")) # 2) check if the current user has permissions to add stuff if not context.portal_membership.checkPermission('Add portal content', context): return self.errorMessage(_("You do not have permission to upload files in this folder")) # Get an unused filename without path id = self.cleanupFilename(id) title = request['uploadtitle'] description = request['uploaddescription'] newid = context.invokeFactory(type_name=typename, id=id) if newid is None or newid == '': newid = id obj = getattr(context, newid, None) # Set title + description. # Attempt to use Archetypes mutator if there is one, in case it uses a custom storage if title: try: obj.setTitle(title) except AttributeError: obj.title = title if description: try: obj.setDescription(description) except AttributeError: obj.description = description # set primary field pf = obj.getPrimaryField() pf.set(obj, request['uploadfile']) if not obj: return self.errorMessage(_("Could not upload the file")) obj.reindexObject() utility = getUtility(ITinyMCE) if utility.link_using_uids: return self.okMessage("resolveuid/%s" % (uuidFor(obj))) return self.okMessage("%s" % (obj.absolute_url()))
def upload(self): # NOQA """Adds uploaded file""" context = aq_inner(self.context) if not IFolderish.providedBy(context): context = aq_parent(context) request = context.REQUEST ctr_tool = getToolByName(context, 'content_type_registry') utility = getToolByName(context, 'portal_tinymce') uploadfile = request['uploadfile'] id = uploadfile.filename content_type = uploadfile.headers["Content-Type"] typename = ctr_tool.findTypeName(id, content_type, "") # Permission checks based on code by Danny Bloemendaal # 1) check if the current user has permissions to add stuff if not context.portal_membership.checkPermission( 'Add portal content', context): return self.errorMessage( _("You do not have permission to upload files in this folder")) # 2) check image types uploadable in folder. # priority is to content_type_registry image type allowed_types = [t.id for t in context.getAllowedTypes()] if typename in allowed_types: uploadable_types = [typename] else: uploadable_types = [] if content_type.split('/')[0] == 'image': image_portal_types = utility.imageobjects.split('\n') uploadable_types += [ t for t in image_portal_types if t in allowed_types and t not in uploadable_types ] # limitfilesizepanel check size_check = self.check_file_size(uploadable_types, request) if size_check and not size_check.get('valid', False): msg = lfspmf( 'validation_error', default= u"Validation failed. Uploaded data is too large: ${size}MB (max ${max}MB)", # NOQA mapping={ 'size': safe_unicode("%.1f" % size_check.get('sizeMB')), 'max': safe_unicode("%.1f" % size_check.get('maxsize')) }) return self.errorMessage(msg) # end otf limitfilesizepanel check # Get an unused filename without path id = self.cleanupFilename(id) for metatype in uploadable_types: try: newid = context.invokeFactory(type_name=metatype, id=id) if newid is None or newid == '': newid = id break except ValueError: continue except BadRequest: return self.errorMessage(_("Bad filename, please rename.")) else: return self.errorMessage( _("Not allowed to upload a file of this type to this folder")) obj = getattr(context, newid, None) # Set title + description. # Attempt to use Archetypes mutator if there is one, in case it uses # a custom storage title = request['uploadtitle'] description = request['uploaddescription'] if title: try: obj.setTitle(title) except AttributeError: obj.title = title if description: try: obj.setDescription(description) except AttributeError: obj.description = description if HAS_DEXTERITY and IDexterityContent.providedBy(obj): if not self.setDexterityItem(obj, uploadfile, id): msg = _( "The content-type '${type}' has no image- or file-field!", mapping={'type': metatype}) return self.errorMessage(msg) else: # set primary field pf = obj.getPrimaryField() pf.set(obj, uploadfile) if not obj: return self.errorMessage(_("Could not upload the file")) obj.reindexObject() folder = obj.aq_parent.absolute_url() if utility.link_using_uids: path = "resolveuid/%s" % (uuidFor(obj)) else: path = obj.absolute_url() tiny_pkg = pkg_resources.get_distribution("Products.TinyMCE") if tiny_pkg.version.startswith('1.2'): # Plone < 4.3 return self.okMessage(path) else: # Plone >= 4.3 return self.okMessage(path, folder)
def upload(self): """Adds uploaded file""" object = aq_inner(self.context) if not IFolderish.providedBy(object): object = aq_parent(object) context = self.context request = context.REQUEST ctr_tool = getToolByName(self.context, "content_type_registry") utility = getUtility(ITinyMCE) id = request["uploadfile"].filename content_type = request["uploadfile"].headers["Content-Type"] typename = ctr_tool.findTypeName(id, content_type, "") # Permission checks based on code by Danny Bloemendaal # 1) check if the current user has permissions to add stuff if not context.portal_membership.checkPermission("Add portal content", context): return self.errorMessage(_("You do not have permission to upload files in this folder")) # 2) check image types uploadable in folder. # priority is to content_type_registry image type allowed_types = [t.id for t in context.getAllowedTypes()] if typename in allowed_types: uploadable_types = [typename] else: uploadable_types = [] if content_type.split("/")[0] == "image": image_portal_types = utility.imageobjects.split("\n") uploadable_types += [t for t in image_portal_types if t in allowed_types and t not in uploadable_types] # Get an unused filename without path id = self.cleanupFilename(id) title = request["uploadtitle"] description = request["uploaddescription"] for metatype in uploadable_types: try: newid = context.invokeFactory(type_name=metatype, id=id) if newid is None or newid == "": newid = id obj = getattr(context, newid, None) # set primary field pf = obj.getPrimaryField() pf.set(obj, request["uploadfile"]) break except ValueError: continue except BadRequest: return self.errorMessage(_("Bad filename, please rename.")) else: return self.errorMessage(_("Not allowed to upload a file of this type to this folder")) # Set title + description. # Attempt to use Archetypes mutator if there is one, in case it uses a custom storage if title: try: obj.setTitle(title) except AttributeError: obj.title = title if description: try: obj.setDescription(description) except AttributeError: obj.description = description if not obj: return self.errorMessage(_("Could not upload the file")) obj.reindexObject() if utility.link_using_uids: return self.okMessage("resolveuid/%s" % (uuidFor(obj))) return self.okMessage("%s" % (obj.absolute_url()))
def upload(self): # NOQA """Adds uploaded file""" context = aq_inner(self.context) if not IFolderish.providedBy(context): context = aq_parent(context) request = context.REQUEST ctr_tool = getToolByName(context, 'content_type_registry') utility = getToolByName(context, 'portal_tinymce') uploadfile = request['uploadfile'] id = uploadfile.filename content_type = uploadfile.headers["Content-Type"] typename = ctr_tool.findTypeName(id, content_type, "") # Permission checks based on code by Danny Bloemendaal # 1) check if the current user has permissions to add stuff if not context.portal_membership.checkPermission( 'Add portal content', context): return self.errorMessage( _("You do not have permission to upload files in this folder")) # 2) check image types uploadable in folder. # priority is to content_type_registry image type allowed_types = [t.id for t in context.getAllowedTypes()] if typename in allowed_types: uploadable_types = [typename] else: uploadable_types = [] if content_type.split('/')[0] == 'image': image_portal_types = utility.imageobjects.split('\n') uploadable_types += [ t for t in image_portal_types if t in allowed_types and t not in uploadable_types] # limitfilesizepanel check size_check = self.check_file_size(uploadable_types, request) if size_check and not size_check.get('valid', False): msg = lfspmf( 'validation_error', default=u"Validation failed. Uploaded data is too large: ${size}MB (max ${max}MB)", # NOQA mapping={ 'size': safe_unicode("%.1f" % size_check.get('sizeMB')), 'max': safe_unicode("%.1f" % size_check.get('maxsize')) } ) return self.errorMessage(msg) # end otf limitfilesizepanel check # Get an unused filename without path id = self.cleanupFilename(id) for metatype in uploadable_types: try: newid = context.invokeFactory(type_name=metatype, id=id) if newid is None or newid == '': newid = id break except ValueError: continue except BadRequest: return self.errorMessage(_("Bad filename, please rename.")) else: return self.errorMessage( _("Not allowed to upload a file of this type to this folder")) obj = getattr(context, newid, None) # Set title + description. # Attempt to use Archetypes mutator if there is one, in case it uses # a custom storage title = request['uploadtitle'] description = request['uploaddescription'] if title: try: obj.setTitle(title) except AttributeError: obj.title = title if description: try: obj.setDescription(description) except AttributeError: obj.description = description if HAS_DEXTERITY and IDexterityContent.providedBy(obj): if not self.setDexterityItem(obj, uploadfile, id): msg = _( "The content-type '${type}' has no image- or file-field!", mapping={'type': metatype}) return self.errorMessage(msg) else: # set primary field pf = obj.getPrimaryField() pf.set(obj, uploadfile) if not obj: return self.errorMessage(_("Could not upload the file")) obj.reindexObject() folder = obj.aq_parent.absolute_url() if utility.link_using_uids: path = "resolveuid/%s" % (uuidFor(obj)) else: path = obj.absolute_url() tiny_pkg = pkg_resources.get_distribution("Products.TinyMCE") if tiny_pkg.version.startswith('1.2'): # Plone < 4.3 return self.okMessage(path) else: # Plone >= 4.3 return self.okMessage(path, folder)
def getConfiguration(self, context=None, field=None, request=None): results = {} # Get widget attributes widget = getattr(field, 'widget', None) filter_buttons = getattr(widget, 'filter_buttons', None) allow_buttons = getattr(widget, 'allow_buttons', None) redefine_parastyles = getattr(widget, 'redefine_parastyles', None) parastyles = getattr(widget, 'parastyles', None) rooted = getattr(widget, 'rooted', False) toolbar_width = getattr(widget, 'toolbar_width', self.toolbar_width) # Get safe html transform safe_html = getattr(getToolByName(self, 'portal_transforms'), 'safe_html') # Get kupu library tool filter # Settings are stored on safe_html transform in Plone 4 and # on kupu tool in Plone 3. kupu_library_tool = getToolByName(self, 'kupu_library_tool', None) # Remove to be stripped attributes try: style_whitelist = safe_html.get_parameter_value('style_whitelist') except (KeyError, AttributeError): if kupu_library_tool is not None: style_whitelist = kupu_library_tool.getStyleWhitelist() else: style_whitelist = [] results['valid_inline_styles'] = style_whitelist # Replacing some hardcoded translations labels = {} labels['label_styles'] = translate(_('(remove style)'), context=request) labels['label_paragraph'] = translate(_('Normal paragraph'), context=request) labels['label_plain_cell'] = translate(_('Plain cell'), context=request) labels['label_style_ldots'] = translate(_('Style...'), context=request) labels['label_text'] = translate(_('Text'), context=request) labels['label_tables'] = translate(_('Tables'), context=request) labels['label_selection'] = translate(_('Selection'), context=request) labels['label_lists'] = translate(_('Lists'), context=request) labels['label_print'] = translate(_('Print'), context=request) labels['label_no_items'] = translate(_('No items in this folder'), context=request) labels['label_no_anchors'] = translate(_('No anchors in this page'), context=request) results['labels'] = labels # Add styles to results results['styles'] = [] results['table_styles'] = [] if not redefine_parastyles: if isinstance(self.tablestyles, StringTypes): for tablestyle in self.tablestyles.split('\n'): if not tablestyle: # empty line continue tablestylefields = tablestyle.split('|') tablestyletitle = tablestylefields[0] tablestyleid = tablestylefields[1] if tablestyleid == 'plain': # Do not duplicate the default style hardcoded in the # table.htm.pt continue if request is not None: tablestyletitle = translate(_(tablestylefields[0]), context=request) results['styles'].append(tablestyletitle + '|table|' + tablestyleid) results['table_styles'].append(tablestyletitle + '=' + tablestyleid) if isinstance(self.styles, StringTypes): styles = [] for style in self.styles.split('\n'): if not style: # empty line continue stylefields = style.split('|') styletitle = stylefields[0] if request is not None: styletitle = translate(_(stylefields[0]), context=request) merge = styletitle + '|' + '|'.join(stylefields[1:]) styles.append(merge) results['styles'].extend(styles) if parastyles is not None: results['styles'].extend(parastyles) # Get buttons from control panel results['buttons'] = self.getEnabledButtons(context=context) # Filter buttons if allow_buttons is not None: allow_buttons = self.translateButtonsFromKupu(context=context, buttons=allow_buttons) results['buttons'] = filter(lambda x: x in results['buttons'], allow_buttons) if filter_buttons is not None: filter_buttons = self.translateButtonsFromKupu(context=context, buttons=filter_buttons) results['buttons'] = filter(lambda x: x not in filter_buttons, results['buttons']) # Get valid html elements results['valid_elements'] = self.getValidElements() # Set toolbar_location if self.toolbar_external: results['toolbar_location'] = 'external' else: results['toolbar_location'] = 'top' if self.autoresize: results['path_location'] = 'none' results['resizing_use_cookie'] = False results['resizing'] = False results['autoresize'] = True else: results['path_location'] = 'bottom' results['resizing_use_cookie'] = True if self.resizing: results['resizing'] = True else: results['resizing'] = False results['autoresize'] = False if '%' in self.editor_width: results['resize_horizontal'] = False else: results['resize_horizontal'] = True try: results['editor_width'] = int(self.editor_width) except (TypeError, ValueError): results['editor_width'] = 600 try: results['editor_height'] = int(self.editor_height) except (TypeError, ValueError): results['editor_height'] = 400 try: results['toolbar_width'] = int(toolbar_width) except (TypeError, ValueError): results['toolbar_width'] = 440 if self.directionality == 'auto': language = context.Language() if not language: portal_properties = getToolByName(context, "portal_properties") site_properties = portal_properties.site_properties language = site_properties.getProperty('default_language', None) directionality = (language[:2] in RIGHT_TO_LEFT) and 'rtl' or 'ltr' else: directionality = self.directionality results['directionality'] = directionality if self.contextmenu: results['contextmenu'] = True else: results['contextmenu'] = False if self.content_css and self.content_css.strip() != "": results['content_css'] = self.content_css else: results['content_css'] = self.absolute_url() + """/@@tinymce-getstyle""" if self.link_using_uids: results['link_using_uids'] = True else: results['link_using_uids'] = False if self.allow_captioned_images: results['allow_captioned_images'] = True else: results['allow_captioned_images'] = False if self.rooted or rooted: results['rooted'] = True else: results['rooted'] = False results['customplugins'] = [] if self.customplugins is not None: results['customplugins'].extend(self.customplugins.split('\n')) results['entity_encoding'] = self.entity_encoding portal = getUtility(ISiteRoot) results['portal_url'] = aq_inner(portal).absolute_url() nav_root = getNavigationRootObject(context, portal) results['navigation_root_url'] = nav_root.absolute_url() props = getToolByName(self, 'portal_properties') livesearch = props.site_properties.getProperty('enable_livesearch', False) if livesearch: results['livesearch'] = True else: results['livesearch'] = False AVAILABLE_LANGUAGES = set( 'sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl ' 'ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa ' 'pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr tw uk ur cy vi zu'.split()) if 'LANGUAGE' in context.REQUEST: results['language'] = context.REQUEST.LANGUAGE[:2] if results['language'] not in AVAILABLE_LANGUAGES: results['language'] = "en" else: results['language'] = "en" try: results['document_url'] = context.absolute_url() if getattr(aq_base(context), 'checkCreationFlag', None): parent = aq_parent(aq_inner(context)) if context.checkCreationFlag(): parent = aq_parent(aq_parent(parent)) results['parent'] = parent.absolute_url() + "/" else: if IFolderish.providedBy(context): results['parent'] = context.absolute_url() + "/" else: results['parent'] = parent.absolute_url() + "/" except AttributeError: results['parent'] = results['portal_url'] + "/" results['document_url'] = results['portal_url'] # Get Library options results['libraries_spellchecker_choice'] = \ self.libraries_spellchecker_choice # init vars specific for "After the Deadline" spellchecker mtool = getToolByName(portal, 'portal_membership') member = mtool.getAuthenticatedMember() results['atd_rpc_id'] = 'Products.TinyMCE-' + (member.getId() or '') # None when Anonymous User results['atd_rpc_url'] = "%s/@@" % portal.absolute_url() results['atd_show_types'] = self.libraries_atd_show_types.strip().replace('\n', ',') results['atd_ignore_strings'] = self.libraries_atd_ignore_strings.strip().replace('\n', ',') return json.dumps(results)
def upload(self): """Adds uploaded file""" object = aq_inner(self.context) if not IFolderish.providedBy(object): object = aq_parent(object) context = self.context request = context.REQUEST ctr_tool = getToolByName(self.context, 'content_type_registry') utility = getUtility(ITinyMCE) id = request['uploadfile'].filename content_type = request['uploadfile'].headers["Content-Type"] typename = ctr_tool.findTypeName(id, content_type, "") # Permission checks based on code by Danny Bloemendaal # 1) check if the current user has permissions to add stuff if not context.portal_membership.checkPermission( 'Add portal content', context): return self.errorMessage( _("You do not have permission to upload files in this folder")) # 2) check image types uploadable in folder. # priority is to content_type_registry image type allowed_types = [t.id for t in context.getAllowedTypes()] if typename in allowed_types: uploadable_types = [typename] else: uploadable_types = [] if content_type.split('/')[0] == 'image': image_portal_types = utility.imageobjects.split('\n') uploadable_types += [ t for t in image_portal_types if t in allowed_types and t not in uploadable_types ] # Get an unused filename without path id = self.cleanupFilename(id) title = request['uploadtitle'] description = request['uploaddescription'] for metatype in uploadable_types: try: newid = context.invokeFactory(type_name=metatype, id=id) if newid is None or newid == '': newid = id obj = getattr(context, newid, None) # set primary field pf = obj.getPrimaryField() pf.set(obj, request['uploadfile']) break except ValueError: continue except BadRequest: return self.errorMessage(_("Bad filename, please rename.")) else: return self.errorMessage( _("Not allowed to upload a file of this type to this folder")) # Set title + description. # Attempt to use Archetypes mutator if there is one, in case it uses a custom storage if title: try: obj.setTitle(title) except AttributeError: obj.title = title if description: try: obj.setDescription(description) except AttributeError: obj.description = description if not obj: return self.errorMessage(_("Could not upload the file")) obj.reindexObject() if utility.link_using_uids: return self.okMessage("resolveuid/%s" % (uuidFor(obj))) return self.okMessage("%s" % (obj.absolute_url()))
def getConfiguration(self, context=None, field=None, request=None): results = {} # Get widget attributes widget = getattr(field, "widget", None) filter_buttons = getattr(widget, "filter_buttons", None) allow_buttons = getattr(widget, "allow_buttons", None) redefine_parastyles = getattr(widget, "redefine_parastyles", None) parastyles = getattr(widget, "parastyles", None) rooted = getattr(widget, "rooted", False) toolbar_width = getattr(widget, "toolbar_width", self.toolbar_width) # Get safe html transform safe_html = getattr(getToolByName(self, "portal_transforms"), "safe_html") # Get kupu library tool filter # Settings are stored on safe_html transform in Plone 4 and # on kupu tool in Plone 3. kupu_library_tool = getToolByName(self, "kupu_library_tool", None) # Remove to be stripped attributes try: style_whitelist = safe_html.get_parameter_value("style_whitelist") except (KeyError, AttributeError): if kupu_library_tool is not None: style_whitelist = kupu_library_tool.getStyleWhitelist() else: style_whitelist = [] results["valid_inline_styles"] = style_whitelist # Replacing some hardcoded translations labels = {} labels["label_styles"] = translate(_("(remove style)"), context=request) labels["label_paragraph"] = translate(_("Normal paragraph"), context=request) labels["label_plain_cell"] = translate(_("Plain cell"), context=request) labels["label_style_ldots"] = translate(_("Style..."), context=request) labels["label_text"] = translate(_("Text"), context=request) labels["label_tables"] = translate(_("Tables"), context=request) labels["label_selection"] = translate(_("Selection"), context=request) labels["label_lists"] = translate(_("Lists"), context=request) labels["label_print"] = translate(_("Print"), context=request) labels["label_no_items"] = translate(_("No items in this folder"), context=request) labels["label_no_anchors"] = translate(_("No anchors in this page"), context=request) results["labels"] = labels # Add styles to results results["styles"] = [] results["table_styles"] = [] if not redefine_parastyles: if isinstance(self.tablestyles, StringTypes): for tablestyle in self.tablestyles.split("\n"): if not tablestyle: # empty line continue tablestylefields = tablestyle.split("|") tablestyletitle = tablestylefields[0] tablestyleid = tablestylefields[1] if tablestyleid == "plain": # Do not duplicate the default style hardcoded in the # table.htm.pt continue if request is not None: tablestyletitle = translate(_(tablestylefields[0]), context=request) results["styles"].append(tablestyletitle + "|table|" + tablestyleid) results["table_styles"].append(tablestyletitle + "=" + tablestyleid) if isinstance(self.styles, StringTypes): styles = [] for style in self.styles.split("\n"): if not style: # empty line continue stylefields = style.split("|") styletitle = stylefields[0] if request is not None: styletitle = translate(_(stylefields[0]), context=request) merge = styletitle + "|" + "|".join(stylefields[1:]) styles.append(merge) results["styles"].extend(styles) if parastyles is not None: results["styles"].extend(parastyles) # Get buttons from control panel results["buttons"] = self.getEnabledButtons(context=context) # Filter buttons if allow_buttons is not None: allow_buttons = self.translateButtonsFromKupu(context=context, buttons=allow_buttons) results["buttons"] = filter(lambda x: x in results["buttons"], allow_buttons) if filter_buttons is not None: filter_buttons = self.translateButtonsFromKupu(context=context, buttons=filter_buttons) results["buttons"] = filter(lambda x: x not in filter_buttons, results["buttons"]) # Get valid html elements results["valid_elements"] = self.getValidElements() # Set toolbar_location if self.toolbar_external: results["toolbar_location"] = "external" else: results["toolbar_location"] = "top" if self.autoresize: results["path_location"] = "none" results["resizing_use_cookie"] = False results["resizing"] = False results["autoresize"] = True else: results["path_location"] = "bottom" results["resizing_use_cookie"] = True if self.resizing: results["resizing"] = True else: results["resizing"] = False results["autoresize"] = False if "%" in self.editor_width: results["resize_horizontal"] = False else: results["resize_horizontal"] = True try: results["editor_width"] = int(self.editor_width) except (TypeError, ValueError): results["editor_width"] = 600 try: results["editor_height"] = int(self.editor_height) except (TypeError, ValueError): results["editor_height"] = 400 try: results["toolbar_width"] = int(toolbar_width) except (TypeError, ValueError): results["toolbar_width"] = 440 if self.directionality == "auto": language = context.Language() if not language: portal_properties = getToolByName(context, "portal_properties") site_properties = portal_properties.site_properties language = site_properties.getProperty("default_language", None) directionality = (language[:2] in RIGHT_TO_LEFT) and "rtl" or "ltr" else: directionality = self.directionality results["directionality"] = directionality if self.contextmenu: results["contextmenu"] = True else: results["contextmenu"] = False if self.content_css and self.content_css.strip() != "": results["content_css"] = self.content_css else: results["content_css"] = self.absolute_url() + """/@@tinymce-getstyle""" if self.link_using_uids: results["link_using_uids"] = True else: results["link_using_uids"] = False if self.allow_captioned_images: results["allow_captioned_images"] = True else: results["allow_captioned_images"] = False if self.rooted or rooted: results["rooted"] = True else: results["rooted"] = False results["customplugins"] = [] if self.customplugins is not None: results["customplugins"].extend(self.customplugins.split("\n")) results["entity_encoding"] = self.entity_encoding portal = getUtility(ISiteRoot) results["portal_url"] = aq_inner(portal).absolute_url() nav_root = getNavigationRootObject(context, portal) results["navigation_root_url"] = nav_root.absolute_url() props = getToolByName(self, "portal_properties") livesearch = props.site_properties.getProperty("enable_livesearch", False) if livesearch: results["livesearch"] = True else: results["livesearch"] = False AVAILABLE_LANGUAGES = set( "sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl " "ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa " "pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr tw uk ur cy vi zu".split() ) if "LANGUAGE" in context.REQUEST: results["language"] = context.REQUEST.LANGUAGE[:2] if results["language"] not in AVAILABLE_LANGUAGES: results["language"] = "en" else: results["language"] = "en" try: results["document_url"] = context.absolute_url() parent = aq_parent(aq_inner(context)) if getattr(aq_base(context), "checkCreationFlag", None) and context.checkCreationFlag(): parent = aq_parent(aq_parent(parent)) results["parent"] = parent.absolute_url() + "/" else: if IFolderish.providedBy(context): results["parent"] = context.absolute_url() + "/" else: results["parent"] = parent.absolute_url() + "/" except AttributeError: results["parent"] = results["portal_url"] + "/" results["document_url"] = results["portal_url"] # Get Library options results["libraries_spellchecker_choice"] = self.libraries_spellchecker_choice # init vars specific for "After the Deadline" spellchecker mtool = getToolByName(portal, "portal_membership") member = mtool.getAuthenticatedMember() results["atd_rpc_id"] = "Products.TinyMCE-" + (member.getId() or "") # None when Anonymous User results["atd_rpc_url"] = "%s/@@" % portal.absolute_url() results["atd_show_types"] = self.libraries_atd_show_types.strip().replace("\n", ",") results["atd_ignore_strings"] = self.libraries_atd_ignore_strings.strip().replace("\n", ",") return json.dumps(results)
class ITinyMCEToolbar(Interface): """This interface defines the toolbar properties.""" toolbar_width = schema.TextLine( title=_(u"Toolbar width"), description= _(u"This option gives you the ability to specify the width of the toolbar in pixels." ), required=False) toolbar_external = schema.Bool( title=_(u"External"), description= _(u"This option enables the external toolbar which will be placed at the top of the page." ), required=False) toolbar_save = schema.Bool(title=_(u"Save"), required=False) toolbar_cut = schema.Bool(title=_(u"Cut"), required=False) toolbar_copy = schema.Bool(title=_(u"Copy"), required=False) toolbar_paste = schema.Bool(title=_(u"Paste"), required=False) toolbar_pastetext = schema.Bool(title=_(u"Paste as Plain Text"), required=False) toolbar_pasteword = schema.Bool(title=_(u"Paste from Word"), required=False) toolbar_undo = schema.Bool(title=_(u"Undo"), required=False) toolbar_redo = schema.Bool(title=_(u"Redo"), required=False) toolbar_search = schema.Bool(title=_(u"Find"), required=False) toolbar_replace = schema.Bool(title=_(u"Find/Replace"), required=False) toolbar_style = schema.Bool(title=_(u"Select Style"), required=False) toolbar_bold = schema.Bool(title=_(u"Bold"), required=False) toolbar_italic = schema.Bool(title=_(u"Italic"), required=False) toolbar_underline = schema.Bool(title=_(u"Underline"), required=False) toolbar_strikethrough = schema.Bool(title=_(u"Strikethrough"), required=False) toolbar_sub = schema.Bool(title=_(u"Subscript"), required=False) toolbar_sup = schema.Bool(title=_(u"Superscript"), required=False) toolbar_forecolor = schema.Bool(title=_(u"Forecolor"), required=False) toolbar_backcolor = schema.Bool(title=_(u"Backcolor"), required=False) toolbar_justifyleft = schema.Bool(title=_(u"Align left"), required=False) toolbar_justifycenter = schema.Bool(title=_(u"Align center"), required=False) toolbar_justifyright = schema.Bool(title=_(u"Align right"), required=False) toolbar_justifyfull = schema.Bool(title=_(u"Align full"), required=False) toolbar_bullist = schema.Bool(title=_(u"Unordered list"), required=False) toolbar_numlist = schema.Bool(title=_(u"Ordered list"), required=False) toolbar_definitionlist = schema.Bool(title=_(u"Definition list"), required=False) toolbar_outdent = schema.Bool(title=_(u"Outdent"), required=False) toolbar_indent = schema.Bool(title=_(u"Indent"), required=False) toolbar_tablecontrols = schema.Bool(title=_(u"Table controls"), required=False) toolbar_link = schema.Bool(title=_(u"Insert/edit link"), required=False) toolbar_unlink = schema.Bool(title=_(u"Unlink"), required=False) toolbar_anchor = schema.Bool(title=_(u"Insert/edit anchor"), required=False) toolbar_image = schema.Bool(title=_(u"Insert/edit image"), required=False) toolbar_media = schema.Bool(title=_(u"Insert/edit media"), required=False) toolbar_charmap = schema.Bool(title=_(u"Insert custom character"), required=False) toolbar_hr = schema.Bool(title=_(u"Insert horizontal ruler"), required=False) toolbar_advhr = schema.Bool(title=_(u"Insert advanced horizontal ruler"), required=False) toolbar_insertdate = schema.Bool(title=_(u"Insert date"), required=False) toolbar_inserttime = schema.Bool(title=_(u"Insert time"), required=False) toolbar_emotions = schema.Bool(title=_(u"Emotions"), required=False) toolbar_nonbreaking = schema.Bool( title=_(u"Insert non-breaking space character"), required=False) toolbar_pagebreak = schema.Bool(title=_(u"Insert page break"), required=False) toolbar_print = schema.Bool(title=_(u"Print"), required=False) toolbar_preview = schema.Bool(title=_(u"Preview"), required=False) toolbar_spellchecker = schema.Bool(title=_(u"Spellchecker"), required=False) toolbar_removeformat = schema.Bool(title=_(u"Remove formatting"), required=False) toolbar_cleanup = schema.Bool(title=_(u"Cleanup messy code"), required=False) toolbar_visualaid = schema.Bool( title=_(u"Toggle guidelines/invisible objects"), required=False) toolbar_visualchars = schema.Bool( title=_(u"Visual control characters on/off"), required=False) toolbar_attribs = schema.Bool(title=_(u"Insert/edit attributes"), required=False) toolbar_code = schema.Bool(title=_(u"Edit HTML Source"), required=False) toolbar_fullscreen = schema.Bool(title=_(u"Toggle fullscreen mode"), required=False) customtoolbarbuttons = schema.Text( title=_(u"Custom Toolbar Buttons"), description= _(u"Enter a list of custom toolbar buttons which will be loaded in the editor, one per line." ), required=False)
class ITinyMCELayout(Interface): """This interface defines the layout properties.""" resizing = schema.Bool( title=_(u"Enable resizing the editor window."), description= _(u"This option gives you the ability to enable/disable resizing the editor window. If the editor width is set to a percentage only vertical resizing is enabled." ), required=False) autoresize = schema.Bool( title=_(u"Enable auto resizing of the editor window."), description= _(u"This option gives you the ability to enable/disable auto resizing the editor window depending on the content." ), required=False) editor_width = schema.TextLine( title=_(u"Editor width"), description= _(u"This option gives you the ability to specify the width of the editor in pixels or percent." ), required=False) editor_height = schema.TextLine( title=_(u"Editor height"), description= _(u"This option gives you the ability to specify the height of the editor in pixels. If auto resize is enabled this value is used as minimum height." ), required=False) directionality = schema.Choice( title=_(u"Writing direction"), description= _(u"This option specifies the default writing direction, some languages (Like Hebrew, Arabic, Urdu...) write from right to left instead of left to right." ), missing_value=set(), vocabulary=SimpleVocabulary([ SimpleTerm('auto', 'auto', _(u'Auto detect from content language')), SimpleTerm('ltr', 'ltr', _(u"Left to right")), SimpleTerm('rtl', 'rtl', _(u"Right to left")) ]), required=False) contextmenu = schema.Bool( title=_(u"Enable contextmenu."), description= _(u"This option gives you the ability to enable/disable the use of the contextmenu." ), required=False) content_css = schema.TextLine( title=_(u"Choose the CSS used in WYSIWYG Editor Area"), description= _(u"This option enables you to specify a custom CSS file that replaces the theme content CSS. This CSS file is the one used within the editor (the editable area)." ), required=False) styles = schema.Text( title=_(u"Styles"), description= _(u"Enter a list of styles to appear in the style pulldown. Format is title|tag or title|tag|className, one per line." ), required=False) tablestyles = schema.Text( title=_(u"Table styles"), description= _(u"Enter a list of styles to appear in the table style pulldown. Format is title|class, one per line." ), required=False)
class ITinyMCEResourceTypes(Interface): """This interface defines the resource types properties.""" link_using_uids = schema.Bool( title=_(u"Link using UIDs"), description= _(u"Links to objects on this site can use unique object ids so that the links remain valid even if the target object is renamed or moved elsewhere on the site." ), required=False) allow_captioned_images = schema.Bool( title=_(u"Allow captioned images"), description=_(u"Images will be automatically captioned."), required=False) rooted = schema.Bool( title=_(u"Rooted to current object"), description= _(u"When enabled the user will be rooted to the current object and can't add links and images from other parts of the site." ), required=False) containsobjects = schema.Text( title=_(u"Contains Objects"), description= _(u"Enter a list of content types which can contain other objects. Format is one contenttype per line." ), required=False) containsanchors = schema.Text( title=_(u"Contains Anchors"), description= _(u"Enter a list of content types which can contain anchors. Format is one contenttype per line." ), required=False) linkable = schema.Text( title=_(u"Linkable Objects"), description= _(u"Enter a list of content types which can be linked. Format is one contenttype per line." ), required=False) imageobjects = schema.Text( title=_(u"Image Objects"), description= _(u"Enter a list of content types which can be used as images. Format is one contenttype per line." ), required=False) customplugins = schema.Text( title=_(u"Custom Plugins"), description= _(u"Enter a list of custom plugins which will be loaded in the editor. Format is pluginname or pluginname|location, one per line." ), required=False) entity_encoding = schema.Choice( title=_(u"Entity encoding"), description= _(u"This option controls how entities/characters get processed. Named: Characters will be converted into named entities based on the entities option. Numeric: Characters will be converted into numeric entities. Raw: All characters will be stored in non-entity form except these XML default entities: amp lt gt quot" ), missing_value=set(), vocabulary=SimpleVocabulary([ SimpleTerm('named', 'named', _(u"Named")), SimpleTerm('numeric', 'numeric', _(u"Numeric")), SimpleTerm('raw', 'raw', _(u"Raw")) ]), required=False)
class ITinyMCELibraries(Interface): """This interface defines the libraries properties.""" libraries_spellchecker_choice = schema.Choice( title=_(u"Spellchecker plugin to use"), description=_(u"This option allows you to choose the spellchecker for " u"TinyMCE. If you want the spellchecker button to be " u"visible, make sure it is enabled in the toolbar " u"settings."), missing_value=set(), vocabulary=SimpleVocabulary([ SimpleTerm('browser', 'browser', _(u"Default browser spellchecker")), SimpleTerm('iespell', 'iespell', _(u"ieSpell (free for personal use)")), SimpleTerm('AtD', 'AtD', _(u"After the deadline (FLOSS)")), ]), default='browser', required=False) libraries_atd_ignore_strings = schema.Text( title=_(u"AtD Ignore strings"), description=_( 'label_atd_ignore_strings', default=u"A list of strings which the \"After the Deadline\"" \ u"spellchecker should ignore. " \ u"Note: This option is only applicable when the appropriate " \ "spellchecker has been chosen above."), default=u"Zope\nPlone\nTinyMCE", required=False) libraries_atd_show_types = schema.Text( title=_(u"AtD Error types to show"), description=_( 'help_atderrortypes_to_show', default=u"A list of error types which the " \ u"\"After the Deadline\" spellchecker should check for. " \ u"By default, all the available error type will be listed here."), default=u"Bias Language\nCliches\nComplex Expression\n" \ u"Diacritical Marks\nDouble Negatives\n" \ u"Hidden Verbs\nJargon Language\nPassive voice\n" \ u"Phrases to Avoid\nRedundant Expression", required=False) libraries_atd_service_url = schema.TextLine( title=_(u"AtD Service URL"), description=_( 'help_atd_service_url', default=u"The URL of the \"After the Deadline\" grammar and spell " \ u"checking server. The default value is the public server, " \ u"but ideally you should download and install your own and " \ u"specify its address here."), required=True, default=u"service.afterthedeadline.com",)