def handleApply(self, action): """ Save (create or update) a tag """ data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return ajax = 'ajax' in self.request.form manager = IImageTagsManager(self.context) id, tag, new_tag = manager.save_tag(data) if not errors: # Special treatment for ajax/non-ajax save if not ajax: if new_tag: message = _(u"Tag '${title}' added.", mapping={u'title': tag['title']}) else: message = _(u"Tag '${title}' updated.", mapping={u'title': tag['title']}) self.request.response.redirect('%s/@@imagetags-manage' % self.context.absolute_url()) IStatusMessage(self.request).addStatusMessage(message, type='info') else: # Return XML response self.request.response.redirect( '%s/@@imagetags-newtag?id=%s' % (self.context.absolute_url(), id))
def __call__(self): """ This browser view can be called in a get/post request to remove existing tags. """ request = self.request if 'form.widgets.remove' in request.form: ids = request.form['form.widgets.remove'] removed = self.manager.remove_tags(ids=ids) if 'ajax' in request.form: request.response.setHeader('content-type', 'application/json; charset=utf-8') response_body = {'removed': [id.encode('utf-8') for id in ids]} response_http = json.dumps(response_body) request.response.setHeader('content-length', len(response_http)) return response_http else: count_removed = len(removed) if count_removed==1: message = _(u'${count} tag removed.', mapping={u'count': count_removed}) elif count_removed>1: message = _(u'${count} tags removed.', mapping={u'count': count_removed}) if count_removed>0: IStatusMessage(self.request).addStatusMessage(message, type='info') return self.index() else: return self.index()
def __call__(self): """ This browser view can be called in a get/post request to remove existing tags. """ request = self.request if 'form.widgets.remove' in request.form: ids = request.form['form.widgets.remove'] removed = self.manager.remove_tags(ids=ids) if 'ajax' in request.form: request.response.setHeader('content-type', 'application/json; charset=utf-8') response_body = {'removed': [id.encode('utf-8') for id in ids]} response_http = json.dumps(response_body) request.response.setHeader('content-length', len(response_http)) return response_http else: count_removed = len(removed) if count_removed == 1: message = _(u'${count} tag removed.', mapping={u'count': count_removed}) elif count_removed > 1: message = _(u'${count} tags removed.', mapping={u'count': count_removed}) if count_removed > 0: IStatusMessage(self.request).addStatusMessage(message, type='info') return self.index() else: return self.index()
class IAddTag(Interface): """ Form to add a new image tag """ id = schema.TextLine(title=_(u"Id"), required=False) field = schema.Choice( title=_(u"Image field"), description=_(u"Image field you want to add this tag"), vocabulary='collective.imagetags.imagefields', required=True) title = schema.TextLine(title=_(u"Title displayed in the tag"), required=True) url = schema.URI(title=_(u"Link for the tag"), required=False) x = schema.Float( title=_(u"X position"), description=_( u"Position in the X axis of the center of the box (0-100%)"), min=0.0, max=100.0) y = schema.Float( title=_(u"Y position"), description=_( u"Position in the Y axis of the center of the box (0-100%)"), min=0.0, max=100.0)
def handleSave(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return changes = self.applyChanges(data) # Special skin management for improved_templates field templates = data['improved_templates'] if isinstance(templates, basestring): templates = [templates] available_templates = getUtility( IVocabularyFactory, name='collective.imagetags.templates')(self.context) skins = getToolByName(self.context, 'portal_skins') skinpaths = skins.getSkinSelections() for skin in skinpaths: path = skins.getSkinPath(skin) paths = [i.strip() for i in path.split(',')] # First I got the list of skin layers (paths) of this skin for template in available_templates.by_value: if template in templates: # If template is well positioned, make sure to add it into paths before 'plone_content' if template in paths: if 'plone_content' in paths: if paths.index(template) > paths.index( 'plone_content'): paths.remove(template) paths.insert(paths.index('plone_content'), template) else: # template not in paths, add it if 'plone_content' in paths: paths.insert(paths.index('plone_content'), template) else: # Template isn't selected, make sure to remove it from paths if template in paths: paths.remove(template) path = ','.join(paths) skins.addSkinSelection(skin, path) # Notify the user if changes: IStatusMessage(self.request).addStatusMessage( _(u"Changes saved"), "info") self.request.response.redirect( "%s/%s" % (self.context.absolute_url(), self.control_panel_view))
def handleApply(self, action): """ Save (create or update) a tag """ data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return ajax = 'ajax' in self.request.form manager = IImageTagsManager(self.context) id, tag, new_tag = manager.save_tag(data) if not errors: # Special treatment for ajax/non-ajax save if not ajax: if new_tag: message = _(u"Tag '${title}' added.", mapping={u'title': tag['title']}) else: message = _(u"Tag '${title}' updated.", mapping={u'title': tag['title']}) self.request.response.redirect('%s/@@imagetags-manage' % self.context.absolute_url()) IStatusMessage(self.request).addStatusMessage(message, type='info') else: # Return XML response self.request.response.redirect('%s/@@imagetags-newtag?id=%s' % (self.context.absolute_url(), id))
def __call__(self, *args, **kw): # Change content-type header for JavaScript response = self.request.response response.setHeader('Content-Type', 'application/x-javascript') # Create handy translate function td = queryUtility(ITranslationDomain, name='collective.imagetags') if td: tx = td.translate else: # Workaround for non-registered translation domain to prevent breaking tx = lambda (x): x # Get locales for decimalSeparator portal_state = getMultiAdapter((self.context, self.request), name="plone_portal_state") locale = portal_state.locale() # Return JSON object as JavaScript source return """ /* Internationalized labels used for imagetags JavaScript interactions */ ImageTagsLabels = { tagFormTitle: '%s', removeLinkText: '%s', removeConfirmText: '%s', editLinkText: '%s', yesButtonText: '%s', noButtonText: '%s', saveButtonText: '%s', hyphenLabel: '%s', decimalSeparator: '%s' }; """ % ( tx(_(u"Tag details")), tx(_(u"Remove")), tx(_(u"Are you sure you want to remove this tag?")), tx(_(u"Edit")), tx(_(u"Yes")), tx(_(u"No")), tx(_(u'Save')), tx(_(u"imagetags.hyphen", default=u"-")), locale.numbers.symbols['decimal'], )
def __call__(self, *args, **kw): # Change content-type header for JavaScript response = self.request.response response.setHeader("Content-Type", "application/x-javascript") # Create handy translate function td = queryUtility(ITranslationDomain, name="collective.imagetags") if td: tx = td.translate else: # Workaround for non-registered translation domain to prevent breaking tx = lambda (x): x # Get locales for decimalSeparator portal_state = getMultiAdapter((self.context, self.request), name="plone_portal_state") locale = portal_state.locale() # Return JSON object as JavaScript source return """ /* Internationalized labels used for imagetags JavaScript interactions */ ImageTagsLabels = { tagFormTitle: '%s', removeLinkText: '%s', removeConfirmText: '%s', editLinkText: '%s', yesButtonText: '%s', noButtonText: '%s', saveButtonText: '%s', hyphenLabel: '%s', decimalSeparator: '%s' }; """ % ( tx(_(u"Tag details")), tx(_(u"Remove")), tx(_(u"Are you sure you want to remove this tag?")), tx(_(u"Edit")), tx(_(u"Yes")), tx(_(u"No")), tx(_(u"Save")), tx(_(u"imagetags.hyphen", default=u"-")), locale.numbers.symbols["decimal"], )
def handleSave(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return changes = self.applyChanges(data) # Special skin management for improved_templates field templates = data['improved_templates'] if isinstance(templates, basestring): templates = [templates] available_templates = getUtility(IVocabularyFactory, name='collective.imagetags.templates')(self.context) skins = getToolByName(self.context, 'portal_skins') skinpaths = skins.getSkinSelections() for skin in skinpaths: path = skins.getSkinPath(skin) paths = [i.strip() for i in path.split(',')] # First I got the list of skin layers (paths) of this skin for template in available_templates.by_value: if template in templates: # If template is well positioned, make sure to add it into paths before 'plone_content' if template in paths: if 'plone_content' in paths: if paths.index(template)>paths.index('plone_content'): paths.remove(template) paths.insert(paths.index('plone_content'), template) else: # template not in paths, add it if 'plone_content' in paths: paths.insert(paths.index('plone_content'), template) else: # Template isn't selected, make sure to remove it from paths if template in paths: paths.remove(template) path = ','.join(paths) skins.addSkinSelection(skin, path) # Notify the user if changes: IStatusMessage(self.request).addStatusMessage(_(u"Changes saved"), "info") self.request.response.redirect("%s/%s" % (self.context.absolute_url(), self.control_panel_view))
def handleCancel(self, action): IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"), "info") self.request.response.redirect("%s/%s" % (self.context.absolute_url(), self.control_panel_view))
def handleCancel(self, action): IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"), "info") self.request.response.redirect( "%s/%s" % (self.context.absolute_url(), self.control_panel_view))
class AdminRulesForm(controlpanel.RegistryEditForm): """ A configlet form for IImageSettings based on plone.app.registry.controlpanel """ schema = IImageTagsSettings label = _(u"Image tags settings") # Copy and adaptation of controlpanel.RegistryEditForm @button.buttonAndHandler(_('Save'), name='save') def handleSave(self, action): data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return changes = self.applyChanges(data) # Special skin management for improved_templates field templates = data['improved_templates'] if isinstance(templates, basestring): templates = [templates] available_templates = getUtility( IVocabularyFactory, name='collective.imagetags.templates')(self.context) skins = getToolByName(self.context, 'portal_skins') skinpaths = skins.getSkinSelections() for skin in skinpaths: path = skins.getSkinPath(skin) paths = [i.strip() for i in path.split(',')] # First I got the list of skin layers (paths) of this skin for template in available_templates.by_value: if template in templates: # If template is well positioned, make sure to add it into paths before 'plone_content' if template in paths: if 'plone_content' in paths: if paths.index(template) > paths.index( 'plone_content'): paths.remove(template) paths.insert(paths.index('plone_content'), template) else: # template not in paths, add it if 'plone_content' in paths: paths.insert(paths.index('plone_content'), template) else: # Template isn't selected, make sure to remove it from paths if template in paths: paths.remove(template) path = ','.join(paths) skins.addSkinSelection(skin, path) # Notify the user if changes: IStatusMessage(self.request).addStatusMessage( _(u"Changes saved"), "info") self.request.response.redirect( "%s/%s" % (self.context.absolute_url(), self.control_panel_view)) # Copy of the original Cancel button @button.buttonAndHandler(_('Cancel'), name='cancel') def handleCancel(self, action): IStatusMessage(self.request).addStatusMessage(_(u"Edit cancelled"), "info") self.request.response.redirect( "%s/%s" % (self.context.absolute_url(), self.control_panel_view)) def updateFields(self): """ Changes in form widgets """ super(AdminRulesForm, self).updateFields() self.fields['improved_templates'].widgetFactory = CheckBoxFieldWidget self.fields['iframe_enabled'].widgetFactory = SingleCheckBoxFieldWidget self.fields['js_enabled'].widgetFactory = SingleCheckBoxFieldWidget self.fields['inline_images'].widgetFactory = SingleCheckBoxFieldWidget def updateWidgets(self): """ Set value for improved_templates field according to actual skin layers configuration """ super(AdminRulesForm, self).updateWidgets() available_templates = getUtility( IVocabularyFactory, name='collective.imagetags.templates')(self.context) skins = getToolByName(self.context, 'portal_skins') path = skins.getSkinPath(skins.getDefaultSkin()) paths = [i.strip() for i in path.split(',')] include = False improved_templates = [] for template in available_templates.by_value: # If template directory is available and (is before 'plone_content' or 'plone_content' isn't available)... include = (template in paths and 'plone_content' in paths and paths.index(template)<paths.index('plone_content')) or \ (template in paths and not 'plone_conent' in paths) # ... then check it if include: term = available_templates.getTerm(template) improved_templates.append(term.token) for template in self.widgets['improved_templates'].items: template['checked'] = template['value'] in improved_templates
class AddTagForm(form.EditForm): """ Add / Update tag form """ fields = field.Fields(IAddTag) label = _(u"Tag details") ignoreContext = True ignoreRequest = False def __init__(self, context, request): super(form.EditForm, self).__init__(context, request) self.helper = getMultiAdapter((self.context, request), name="imagetags-helper") def _updateWidgets(self): """ Hide some widgets and set value for 'field' widget """ self.widgets['id'].mode = HIDDEN_MODE fields = self.widgets['field'].terms.terms._terms if len(fields) == 1: self.widgets['field'].value = fields[0].value self.widgets['field'].mode = HIDDEN_MODE elif len(fields) == 0: self.widgets['field'].mode = HIDDEN_MODE def updateWidgets(self): """ If 'id' parameter is in the request set values for widgets based on the chosen tag. """ super(form.EditForm, self).updateWidgets() self._updateWidgets() request = self.request id_field = 'id' if id_field in request.form: id = request.form[id_field] manager = IImageTagsManager(self.context) tag = manager.get_tag(id) if not tag is None: for x in tag: self.widgets[x].value = tag[x] self.widgets['id'].value = id @button.buttonAndHandler(_(u'Save'), name='save') def handleApply(self, action): """ Save (create or update) a tag """ data, errors = self.extractData() if errors: self.status = self.formErrorsMessage return ajax = 'ajax' in self.request.form manager = IImageTagsManager(self.context) id, tag, new_tag = manager.save_tag(data) if not errors: # Special treatment for ajax/non-ajax save if not ajax: if new_tag: message = _(u"Tag '${title}' added.", mapping={u'title': tag['title']}) else: message = _(u"Tag '${title}' updated.", mapping={u'title': tag['title']}) self.request.response.redirect('%s/@@imagetags-manage' % self.context.absolute_url()) IStatusMessage(self.request).addStatusMessage(message, type='info') else: # Return XML response self.request.response.redirect( '%s/@@imagetags-newtag?id=%s' % (self.context.absolute_url(), id))
class IImageTagsSettings(Interface): """ ImageTags admin schema for control panel settings """ improved_templates = schema.List( title=_(u"Improved templates"), description=_( u"Default Plone templates to be overriden with tagged-images."), required=False, value_type=schema.Choice(title=_(u"Template"), vocabulary='collective.imagetags.templates')) iframe_enabled = schema.Bool( title=_(u"Use <iframe />"), description= _(u"Show 'Embed code (HTML)' code snippets in 'Tags' tab. Don't forget to add 'iframe' " "as a valid tag in safe_html of portal_transforms. " "Notice that this setting won't prevent displaying iframes in documents." ), required=False, default=True) iframe_taglist_height = schema.Int( title=_(u"Tag list height"), description= _(u"Number of pixels assigned to the 'Tagged' box when calculating iframe height." ), required=True, default=20) inline_images = schema.Bool( title=_(u"Replace inline images"), description= _(u"Replace all inline images (inside text content or portlets) styled with 'imagetags-show' class attribute." ), required=False, default=False) js_enabled = schema.Bool( title=_(u"Enable JavaScript replacement rules"), description= _(u"help_imagetags_settings_editform", default= u"Use these CSS rules below to replace standard images -in content types- with tagged images.\n" "These replacement will be made via JavaScript. Providing a non-JavaScript option is better.\n" "If you prefer to us a non-JavaScript option you will have to modify the view templates of the target " "content types by changing context.tag() call for context.@@imagetags-img(name='image_mini')." "You can use any available scale in image or the full image itself. " "Alternatively you can enable any of the default Plone 'Improved templates' above." ), required=False, default=False) rules = schema.List( title=_(u"JavaScript replacement rules"), description= _(u"Add a replacement rule in each line with this format: 'Portal type|CSS img selector'." ), required=False, default=[ u'News Item|.newsImageContainer>a>img', u'Image|#content-core>a>img', ], value_type=schema.TextLine(title=_(u"Rule")))