Changeset 1092
- Timestamp:
- 03/17/08 11:41:23
- Files:
-
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/configure.zcml (modified) (1 diff)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/manage.zcml (modified) (1 diff)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py (modified) (5 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css (modified) (6 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.kss (modified) (1 diff)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt (modified) (2 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/configure.zcml
r1087 r1092 13 13 for="Products.CMFPlone.interfaces.IPloneSiteRoot" 14 14 class=".plonetabs.PloneTabsControlPanel" 15 template="./templates/plonetabs.pt"16 15 permission="cmf.ManagePortal" 17 16 allowed_interface = ".interfaces.IPloneTabsControlPanel" qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/manage.zcml
r1087 r1092 3 3 xmlns:browser="http://namespaces.zope.org/browser"> 4 4 5 <browser:page5 <!-- <browser:page 6 6 for="plone.app.kss.interfaces.IPortalObject" 7 attribute="manage_ setAutogeneration"7 attribute="manage_deleteAction" 8 8 class=".plonetabs.PloneTabsControlPanel" 9 name="manage- setAutogeneration"9 name="manage-deleteAction" 10 10 permission="cmf.ManagePortal" 11 /> 11 />--> 12 12 13 13 <!-- <browser:page 14 14 for="plone.app.kss.interfaces.IPortalObject" 15 attribute="manage_ toggleGeneratedTabs"15 attribute="manage_addAction" 16 16 class=".plonetabs.PloneTabsControlPanel" 17 name="manage-toggleGeneratedTabs" 18 permission="cmf.ManagePortal" 19 /> 20 21 <browser:page 22 for="plone.app.kss.interfaces.IPortalObject" 23 attribute="manage_toggleNonFolderishTabs" 24 class=".plonetabs.PloneTabsControlPanel" 25 name="manage-toggleNonFolderishTabs" 17 name="manage-addAction" 26 18 permission="cmf.ManagePortal" 27 19 />--> 28 29 20 30 21 <!-- <browser:page qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py
r1087 r1092 7 7 from zope.i18n import translate 8 8 from zope.schema.interfaces import IVocabularyFactory 9 10 from Acquisition import aq_inner 9 from zope.exceptions import UserError 11 10 12 11 from Products.CMFCore.utils import getToolByName 13 from Products.CMFCore.interfaces import IAction 12 from Products.CMFCore.interfaces import IAction, IActionCategory 13 from Products.CMFCore.ActionInformation import Action, ActionCategory 14 14 from Products.CMFEditions.setuphandlers import DEFAULT_POLICIES 15 15 from Products.CMFPlone import PloneMessageFactory as _ … … 19 19 from Products.Five.browser import BrowserView 20 20 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile 21 from Products.statusmessages.interfaces import IStatusMessage 21 22 22 23 from plone.app.layout.navigation.root import getNavigationRoot … … 29 30 from interfaces import IPloneTabsControlPanel 30 31 31 def format_description(text, request=None):32 # We expect the workflow to be a text of "- " divided bullet points.33 text = translate(text.strip(), domain="plone", context=request)34 return [s.strip() for s in text.split("- ") if s]35 36 32 ACTION_ATTRS = ["id", "visible", "description", "url_expr", "title", "available_expr"] 37 33 … … 40 36 implements(IPloneTabsControlPanel) 41 37 38 template = ViewPageTemplateFile("templates/plonetabs.pt") 42 39 actionslist_template = ViewPageTemplateFile("templates/actionslist.pt") 43 40 autogenerated_template = ViewPageTemplateFile("templates/autogenerated.pt") 44 41 sections_template = ViewPageTemplateFile("templates/sections.pt") 42 43 def __call__(self): 44 """ Perform the update and redirect if necessary, or render the page """ 45 postback = True 46 errors = {} 47 context = aq_inner(self.context) 48 49 form = self.request.form 50 action = form.get("action", "") 51 submitted = form.get('form.submitted', False) 52 53 # action handler def handler(self, form) 54 if action == "add_action": 55 if submitted: 56 postback = self.manage_addAction(form, errors) 57 elif action == "edit_action": 58 if submitted: 59 pass 60 elif action == "delete_action": 61 postback = self.manage_deleteAction(self.request, errors) 62 #elif action == "visible_action": 63 #pass 64 elif action == "move_action": 65 pass 66 elif action == "set_autogeneration": 67 if submitted: 68 postback = self.manage_setAutogeneration(form, errors) 69 70 if postback: 71 return self.template(errors=errors) 72 73 ######################################## 74 # Methods for processing configlet posts 75 ######################################## 76 77 def manage_setAutogeneration(self, form, errors): 78 """ Process managing autogeneration settings """ 79 80 # set excludeFromNav property for root objects 81 portal = getMultiAdapter((aq_inner(self.context), self.request), name='plone_portal_state').portal() 82 generated_tabs = form.get("generated_tabs", '0') 83 nonfolderish_tabs = form.get("nonfolderish_tabs", '0') 84 85 for item in self.getRootTabs(): 86 obj = getattr(portal, item['id'], None) 87 if obj is not None: 88 checked = form.get(item['id'], None) 89 if checked == '1': 90 obj.update(excludeFromNav=False) 91 else: 92 obj.update(excludeFromNav=True) 93 94 # set disable_folder_sections property 95 changeProperties = getToolByName(self.context, "portal_properties").site_properties.manage_changeProperties 96 97 if int(generated_tabs) == 1: 98 changeProperties(disable_folder_sections=False) 99 else: 100 changeProperties(disable_folder_sections=True) 101 102 # set disable_nonfolderish_sections property 103 if int(nonfolderish_tabs) == 1: 104 changeProperties(disable_nonfolderish_sections=False) 105 else: 106 changeProperties(disable_nonfolderish_sections=True) 107 108 self.redirect() 109 110 return False 111 112 def manage_addAction(self, form, errors): 113 """ Add a new action to given category, if category doesn't exist, create it """ 114 115 # extract data from request's form 116 id = form.get("id") 117 category = form.get("category") 118 119 # before checking for existence category we will validate all input data 120 # and issue errors if needed 121 122 # create and validate action 123 if not id: 124 errors["id"] = _(u"Id field is required") 125 if not form.get("title"): 126 errors["title"] = _(u"Title field is required") 127 128 action = Action(id) 129 for prop in ACTION_ATTRS: 130 if prop != "id": 131 try: 132 if prop == "visible": 133 value = int(form.get(prop, '0')) 134 else: 135 value = form.get(prop) 136 137 action._setPropValue(prop, value) 138 except Exception, e: 139 errors[prop] = _(u"%s" % str(e)) 140 141 # if not errors find (or create) category and set action to it 142 if not errors: 143 portal_actions = getToolByName(self.context, "portal_actions") 144 cat_container = None 145 146 if category not in map(lambda x: x.id, filter(lambda x: IActionCategory.providedBy(x), portal_actions.objectValues())): 147 try: 148 portal_actions._setObject(category, ActionCategory(category)) 149 except Exception, e: 150 errors["select_category"] = _(u"%s" % str(e)) 151 else: 152 cat_container = portal_actions[category] 153 else: 154 cat_container = portal_actions[category] 155 156 if cat_container is not None: 157 try: 158 cat_container._setObject(id, action) 159 except Exception, e: 160 errors["id"] = _(u"%s" % str(e)) 161 162 if not errors: 163 self.redirect(search="category=%s" % category) 164 return False 165 else: 166 IStatusMessage(self.request).addStatusMessage(_(u"Please correct the indicated errors."), type="error") 167 return True 168 169 def manage_deleteAction(self, request, errors): 170 """ Server view for deletign action with given id/category """ 171 portal_actions = getToolByName(self.context, "portal_actions") 172 173 id = request.get("id", "") 174 category = request.get("category", "") 175 176 if category not in portal_actions.objectIds(): 177 IStatusMessage(self.request).addStatusMessage(_(u"Unexistent root portal actions category '%s'" % category), type="error") 178 else: 179 cat_container = portal_actions[category] 180 if id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 181 IStatusMessage(self.request).addStatusMessage(_(u"'%s' action does not exist in '%s' category" % (id, category)), type="error") 182 else: 183 cat_container.manage_delObjects(ids=[id,]) 184 IStatusMessage(self.request).addStatusMessage(_(u"'%s' action in '%s' category successfuly deleted" % (id, category)), type="info") 185 186 self.redirect(search="category=%s" % category) 187 return False 188 189 def redirect(self, url="", search="", hash=""): 190 """ Redirect to @@plonetabs-controlpanel configlet """ 191 192 if url == "": 193 portal_url = getMultiAdapter((self.context, self.request), name=u"plone_portal_state").portal_url() 194 url = "%s/%s" % (portal_url, "@@plonetabs-controlpanel") 195 196 if search != "": 197 search = "?%s" % search 198 199 if hash != "": 200 hash = "#%s" % hash 201 202 self.request.response.redirect("%s%s%s" % (url, search, hash)) 203 204 205 ################################### 206 ## Methods - providers for templates 207 ################################### 45 208 46 209 def getPageTitle(self, category="portal_tabs"): … … 350 513 ksscore.replaceHTML(ksscore.getHtmlIdSelector(replace_id), content) 351 514 352 353 # Methods for processing configlet actions without javascript/ajax354 355 def manage_setAutogeneration(self, generated_tabs="0", nonfolderish_tabs="0"):356 """ Process managing autogeneration settings """357 358 # set excludeFromNav property for root objects359 portal = getMultiAdapter((aq_inner(self.context), self.request), name='plone_portal_state').portal()360 form = self.request.form361 362 for item in self.getRootTabs():363 obj = getattr(portal, item['id'], None)364 if obj is not None:365 checked = form.get(item['id'], None)366 if checked == '1':367 obj.update(excludeFromNav=False)368 else:369 obj.update(excludeFromNav=True)370 371 # set disable_folder_sections property372 changeProperties = getToolByName(self.context, "portal_properties").site_properties.manage_changeProperties373 374 if int(generated_tabs) == 1:375 changeProperties(disable_folder_sections=False)376 else:377 changeProperties(disable_folder_sections=True)378 379 # set disable_nonfolderish_sections property380 if int(nonfolderish_tabs) == 1:381 changeProperties(disable_nonfolderish_sections=False)382 else:383 changeProperties(disable_nonfolderish_sections=True)384 385 self.redirect()386 387 388 def redirect(self, url="", search="", hash=""):389 """ Redirect to @@plonetabs-controlpanel configlet """390 391 if url == "":392 portal_url = getMultiAdapter((self.context, self.request), name=u"plone_portal_state").portal_url()393 url = "%s/%s" % (portal_url, "@@plonetabs-controlpanel")394 395 if search != "":396 search = "?%s" % search397 398 if hash != "":399 hash = "#%s" % hash400 401 self.request.response.redirect("%s%s%s" % (url, search, hash))402 403 404 515 # Utility Methods 405 516 qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css
r1087 r1092 26 26 */ 27 27 28 #app.viewing.reorder-controls,29 #app.sorting.sort-controls,28 .kssTabsActive #app.viewing .reorder-controls, 29 .kssTabsActive #app.sorting .sort-controls, 30 30 #app.viewing li.editing .editform, 31 31 #app #addaction.adding .field-visible, 32 32 #app #addaction.adding .field-name dt, 33 33 #app #addaction.adding .field-action, 34 #app #addaction.adding .field-action label, 34 /* fix for 'non js' version 35 #app #addaction.adding .field-action label,*/ 36 #app #addaction .field-action label, 35 37 #app #addaction.adding .advanced, 36 38 #app #addaction.adding .field-id, … … 47 49 #app.viewing li.editing .tab-title, 48 50 #app .drag-handle, 49 #app.kssActive.delete,50 #app.kssActive.visibility,51 .kssTabsActive #app .delete, 52 .kssTabsActive #app .visibility, 51 53 #app .editform, 52 54 #app.sorting #addaction, 53 #app .field-visible, 54 #app .field-name dt, 55 #app .field-action, 56 #app .advanced, 57 #app .field-id, 58 #app .field-condition, 59 #app .add-controls { 55 .kssTabsActive #app .field-visible, 56 .kssTabsActive #app .field-name dt, 57 .kssTabsActive #app .field-action, 58 .kssTabsActive #app .advanced, 59 .kssTabsActive #app .field-id, 60 .kssTabsActive #app .field-condition, 61 .kssTabsActive #app .add-controls, 62 .kssTabsActive #app .change-button { 60 63 display: none; 61 64 } … … 74 77 /**********************************************************/ 75 78 /* Additional style for functionality withou javascript */ 76 #app.kssActive #autogeneration_controls { 77 display: none; 78 } 79 80 81 79 .kssTabsActive #autogeneration_controls { 80 display: none; 81 } 82 83 #app dl.collapseAdvanced dt.headerAdvanced { 84 display: none; 85 } 86 87 .kssTabsActive #app dl.collapseAdvanced dt.headerAdvanced { 88 display: block; 89 } 90 91 #app input#buttoncancel { 92 display: none; 93 } 94 95 .kssTabsActive #app #buttoncancel { 96 display: block; 97 } 82 98 83 99 /**********************************************************/ … … 92 108 93 109 /*common***************************************************/ 110 111 #app input.change-button { 112 float: none; 113 } 114 115 #app #autogeneration_section { 116 margin-top: 1em; 117 } 94 118 95 119 div.reorder-controls, … … 285 309 position:absolute; 286 310 padding-right:0.5em; 287 display:block; 311 /* display:block; */ 288 312 margin:0; 289 313 top:0; … … 334 358 } 335 359 336 #app #addaction.adding .field-action label { 360 /* fixed for work in 'without js' version 361 removed .adding class from selector 362 #app #addaction.adding .field-action label { */ 363 364 #app #addaction .field-action label { 337 365 position:absolute; 338 366 line-height:2.1em; qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.kss
r1087 r1092 10 10 11 11 /* Add class to body to allow conditional styling when kss is available */ 12 13 #plonetabs_form:load { 14 action-client: addClass; 15 addClass-value: kssTabsActive; 16 } 12 17 13 18 #actions_category:load { qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt
r1087 r1092 20 20 </div> 21 21 22 <a class="delete" href="#">Delete</a> 22 <a class="delete" href="#" 23 tal:attributes="href string:${context/portal_url}/@@plonetabs-controlpanel?action=delete_action&category=${category}&id=${id}">Delete</a> 23 24 <span class="url-helper" tal:content="tab/url_expr">Tab Action</span> 24 25 <span class="tab-title" tal:content="tab/title">Tab Name</span> … … 30 31 tal:attributes="action string:${context/portal_url}/${attrs/action}; 31 32 name string:${attrs/name}_${id}"> 33 34 <input type="hidden" name="action" value="edit_action" /> 35 <input type="hidden" name="form.submitted:boolean" value="True" /> 32 36 33 37 <dl> qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt
r1087 r1092 15 15 tal:define="test nocall:view/test; 16 16 category here/REQUEST/category|nothing; 17 category python:test(category and category != '', category, 'portal_tabs');"> 17 category python:test(category and category != '', category, 'portal_tabs'); 18 errors options/errors|nothing"> 19 20 <div id="plonetabs_form"> 18 21 19 22 <div id="app" class="viewing"> … … 34 37 </a> 35 38 36 <p i18n:translate="description_plonetabs"> 37 Select category to manage: 38 <select name="select_category" 39 id="select_category" 40 tal:define="categories view/getCategories"> 41 <tal:options repeat="cat categories"> 42 <option tal:attributes="value string:category=${cat}; 43 selected python:test(category == cat, 'selected', None)" 44 tal:content="cat" /> 45 </tal:options> 46 </select> 47 </p> 39 <div i18n:translate="description_plonetabs"> 40 <form id="selectcategory_form" 41 name="selectcategory_form" 42 method="post" 43 action="@@plonetabs-controlpanel" 44 tal:attributes="action string:${portal_url}/${attrs/action}"> 45 <div class="field" 46 tal:define="error errors/select_category|nothing" 47 tal:attributes="class python:test(error, 'field error', 'field')"> 48 <div tal:replace="error">Error output</div> 49 <label for="select_category" i18n:translate="label_select_category">Select category to manage</label> 50 <select name="category" 51 id="select_category" 52 tal:define="categories view/getCategories"> 53 <option value="current_category" selected="selected" 54 tal:attributes="value category" 55 tal:content="category" /> 56 <tal:options repeat="cat categories"> 57 <option tal:attributes="value cat" 58 tal:content="cat" 59 tal:condition="python: cat != category" /> 60 </tal:options> 61 </select> 62 <input class="change-button" type="submit" name="selectcategory_button" value="Change" /> 63 </div> 64 </form> 65 </div> 48 66 49 67 <input type="hidden" name="category" value="portal_tabs" id="actions_category" … … 66 84 67 85 <form id="addaction" 86 name="addaction_form" 68 87 method="post" 69 88 action="@@plonetabs-controlpanel" 70 89 tal:attributes="action string:${portal_url}/${attrs/action}"> 90 <input type="hidden" name="action" value="add_action" /> 91 <input type="hidden" name="form.submitted:boolean" value="True" /> 92 <input type="hidden" name="category" value="category" tal:attributes="value category" /> 71 93 <dl class="field-visible bridge"> 72 94 <dt> … … 74 96 </dt> 75 97 <dd> 76 <input id="actvisible" type="checkbox" value="1" checked="checked" title="visibility" name="visible" /> 77 </dd> 78 </dl> 79 <dl class="field-name"> 98 <input id="actvisible" type="checkbox" value="1" checked="checked" title="visibility" name="visible" 99 tal:attributes="checked request/visible|string:checked" /> 100 </dd> 101 </dl> 102 <dl class="field-name" 103 tal:define="error errors/title|nothing" 104 tal:attributes="class python:test(error, 'field-name error', 'field-name')"> 80 105 <dt> 81 106 <label>Name</label> 82 107 </dt> 83 108 <dd> 84 <input id="actname" type="text" value="" name="name" /> 85 </dd> 86 </dl> 87 <dl class="field-action"> 109 <span tal:content="error">Validation error output</span> 110 <input id="actname" type="text" value="" name="title" 111 tal:attributes="value request/title|nothing"/> 112 </dd> 113 </dl> 114 <dl class="field-action" 115 tal:define="error errors/url_expr|nothing" 116 tal:attributes="class python:test(error, 'field-action error', 'field-action')"> 88 117 <dt> 89 118 <label>URL (Expression)</label> 90 119 </dt> 91 120 <dd> 92 <input id="actaction" type="text" value="" size="30" name="action" /> 121 <span tal:content="error">Validation error output</span> 122 <input id="actaction" type="text" value="" size="30" name="url_expr" 123 tal:attributes="value request/url_expr|nothing"/> 93 124 </dd> 94 125 </dl> … … 96 127 <dt class="headerAdvanced">Advanced</dt> 97 128 <dd class="contentAdvanced"> 98 <dl class="field-id"> 129 <dl class="field-id" 130 tal:define="error errors/id|nothing" 131 tal:attributes="class python:test(error, 'field-id error', 'field-id')"> 99 132 <dt> 100 133 <label>Id</label> 101 134 </dt> 102 135 <dd> 103 <input id="actid" type="text" value="" name="id" /> 136 <span tal:content="error">Validation error output</span> 137 <input id="actid" type="text" value="" name="id" 138 tal:attributes="value request/id|nothing" /> 104 139 </dd> 105 140 </dl> 106 <dl class="field-condition"> 141 <dl class="field-condition" 142 tal:define="error errors/available_expr|nothing" 143 tal:attributes="class python:test(error, 'field-condition error', 'field-condition')"> 107 144 <dt> 108 145 <label>Condition (Expression)</label> 109 146 </dt> 110 147 <dd> 111 <input id="actcondition" type="text" value="" size="30" name="condition" /> 148 <span tal:content="error">Validation error output</span> 149 <input id="actcondition" type="text" value="" size="30" name="available_expr" 150 tal:attributes="value request/available_expr|nothing" /> 112 151 </dd> 113 152 </dl> … … 121 160 </form> 122 161 123 < tal:autogenerationcondition="python:category == 'portal_tabs'">162 <div id="autogeneration_section" tal:condition="python:category == 'portal_tabs'"> 124 163 125 164 <form name="generated_tabs_form" 126 action="@@ manage-setAutogeneration"165 action="@@plonetabs-controlpanel" 127 166 method="post" 128 167 tal:attributes="action string:${portal_url}/${attrs/action}"> 168 169 <input type="hidden" name="action" value="set_autogeneration" /> 170 <input type="hidden" name="form.submitted:boolean" value="True" /> 129 171 130 172 <div class="field" … … 171 213 </form> 172 214 173 </tal:autogeneration> 174 215 </div> 216 217 </div> 175 218 176 219 </div>
