Changeset 1087
- Timestamp:
- 03/14/08 04:50:19
- Files:
-
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/configure.zcml (modified) (1 diff)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/kssactions.zcml (modified) (1 diff)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/manage.zcml (added)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py (modified) (6 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css (modified) (3 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.kss (modified) (5 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt (modified) (3 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/autogenerated.pt (modified) (1 diff)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt (modified) (2 diffs)
- qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/plugins/plugin.js (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/configure.zcml
r1082 r1087 2 2 xmlns="http://namespaces.zope.org/zope" 3 3 xmlns:browser="http://namespaces.zope.org/browser"> 4 5 <include file="manage.zcml" /> 4 6 5 7 <include file="kssactions.zcml" /> qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/kssactions.zcml
r1086 r1087 35 35 /> 36 36 37 <browser:page 38 for="plone.app.kss.interfaces.IPortalObject" 39 attribute="editAction" 40 class=".plonetabs.PloneTabsControlPanel" 41 name="plonetabs-editAction" 42 permission="cmf.ManagePortal" 43 /> 44 45 <browser:page 46 for="plone.app.kss.interfaces.IPortalObject" 47 attribute="editCancel" 48 class=".plonetabs.PloneTabsControlPanel" 49 name="plonetabs-editCancel" 50 permission="cmf.ManagePortal" 51 /> 52 37 53 </configure> qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/plonetabs.py
r1086 r1087 1 import copy 2 1 3 from Acquisition import aq_inner 2 4 … … 32 34 return [s.strip() for s in text.split("- ") if s] 33 35 36 ACTION_ATTRS = ["id", "visible", "description", "url_expr", "title", "available_expr"] 34 37 35 38 class PloneTabsControlPanel(PloneKSSView): … … 210 213 #withKssSetup="False") 211 214 215 def validateAction(self, id, category, prefix="tabslist_"): 216 """ If action with given id and category doesn't exist - raise kss exception """ 217 portal_actions = getToolByName(self.context, "portal_actions") 218 219 # remove prefix, added for making ids on configlet unique ("tabslist_") 220 act_id = id[len("tabslist_"):] 221 222 if category not in portal_actions.objectIds(): 223 raise KSSExplicitError, "Unexistent root portal actions category %s" % category 224 225 cat_container = portal_actions[category] 226 if act_id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 227 raise KSSExplicitError, "%s action does not exist in %s category" % (act_id, category) 228 229 return (cat_container, act_id) 230 212 231 @kssaction 213 232 def toggleGeneratedTabs(self, field, checked='0'): … … 233 252 """ Toggle visibility for portal actions """ 234 253 portal_actions = getToolByName(self.context, "portal_actions") 235 236 if category not in portal_actions.objectIds(): 237 raise KSSExplicitError, "Unexistent root portal actions category %s" % category 238 239 # remove prefix, added for making ids on configlet unique ("tabslist_") 240 act_id = id[len("tabslist_"):] 241 242 cat_container = portal_actions[category] 243 if act_id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 244 raise KSSExplicitError, "%s action does not exist in %s category" % (act_id, category) 254 cat_container, act_id = self.validateAction(id, category) 245 255 246 256 if checked == '1': … … 292 302 """ Delete portal action with given id & category """ 293 303 portal_actions = getToolByName(self.context, "portal_actions") 294 295 if category not in portal_actions.objectIds(): 296 raise KSSExplicitError, "Unexistent root portal actions category %s" % category 297 298 # remove prefix, added for making ids on configlet unique ("tabslist_") 299 act_id = id[len("tabslist_"):] 300 301 cat_container = portal_actions[category] 302 if act_id not in map(lambda x: x.id, filter(lambda x: IAction.providedBy(x), cat_container.objectValues())): 303 raise KSSExplicitError, "%s action does not exist in %s category" % (act_id, category) 304 cat_container, act_id = self.validateAction(id, category) 304 305 305 306 cat_container.manage_delObjects(ids=[act_id,]) … … 320 321 self.updateGlobalSections(ksscore) 321 322 322 323 324 325 326 327 328 323 @kssaction 324 def editAction(self, id, category): 325 """ Show edit form for given action """ 326 cat_container, act_id = self.validateAction(id, category) 327 328 # collect data 329 action_info = self.copyAction(cat_container[act_id]) 330 action_info["editing"] = True 331 332 ksscore = self.getCommandSet("core") 333 content = self.actionslist_template(tabs=[action_info,]) 334 replace_id = id 335 336 ksscore.replaceHTML(ksscore.getHtmlIdSelector(replace_id), content) 337 338 # focus name field 339 ksscore.focus(ksscore.getCssSelector("#%s input[name=name_%s]" % (id, act_id))) 340 341 @kssaction 342 def editCancel(self, id, category): 343 """ Hide edit form for given action """ 344 cat_container, act_id = self.validateAction(id, category) 345 346 ksscore = self.getCommandSet("core") 347 content = self.actionslist_template(tabs=[cat_container[act_id],]) 348 replace_id = id 349 350 ksscore.replaceHTML(ksscore.getHtmlIdSelector(replace_id), content) 351 352 353 # Methods for processing configlet actions without javascript/ajax 354 355 def manage_setAutogeneration(self, generated_tabs="0", nonfolderish_tabs="0"): 356 """ Process managing autogeneration settings """ 357 358 # set excludeFromNav property for root objects 359 portal = getMultiAdapter((aq_inner(self.context), self.request), name='plone_portal_state').portal() 360 form = self.request.form 361 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 property 372 changeProperties = getToolByName(self.context, "portal_properties").site_properties.manage_changeProperties 373 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 property 380 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" % search 397 398 if hash != "": 399 hash = "#%s" % hash 400 401 self.request.response.redirect("%s%s%s" % (url, search, hash)) 402 403 404 # Utility Methods 405 406 def copyAction(self, action): 407 """ Copyt action to dictionary """ 408 action_info = {} 409 for attr in ACTION_ATTRS: 410 action_info[attr] = getattr(action, attr) 411 return action_info 412 413 414 415 416 417 418 419 420 421 422 qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.css
r1082 r1087 47 47 #app.viewing li.editing .tab-title, 48 48 #app .drag-handle, 49 #app .delete,50 #app .visibility,49 #app.kssActive .delete, 50 #app.kssActive .visibility, 51 51 #app .editform, 52 52 #app.sorting #addaction, … … 73 73 74 74 /**********************************************************/ 75 /* Additional style for functionality withou javascript */ 76 #app.kssActive #autogeneration_controls { 77 display: none; 78 } 79 80 81 82 83 /**********************************************************/ 75 84 76 85 #app.sorting #tabslist img.drag-handle { … … 291 300 } 292 301 293 dl.expandedBlock dt.headerAdvanced {302 #app dl.expandedBlock dt.headerAdvanced { 294 303 padding: 0 6px 0 22px; 295 background: url(++resource++treeExpanded.gif) no-repeat 6px 50%;296 } 297 298 dl.collapsedBlock dt.headerAdvanced {304 background: transparent url(++resource++treeExpanded.gif) no-repeat 6px 50%; 305 } 306 307 #app dl.collapsedBlock dt.headerAdvanced { 299 308 padding: 0 0 0 22px; 300 background: url(++resource++treeCollapsed.gif) no-repeat 6px 50%;309 background: transparent url(++resource++treeCollapsed.gif) no-repeat 6px 50%; 301 310 } 302 311 303 312 #app dl.advanced { 304 313 clear: both; 314 } 315 316 #app dl.expandedBlock dd.contentAdvanced { 317 display: block; 318 } 319 320 #app dl.collapsedBlock dd.contentAdvanced { 321 display: none; 305 322 } 306 323 qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/resources/plonetabs.kss
r1086 r1087 23 23 24 24 /*Hovering for IE especially */ 25 #app li:mouseover {25 /*#app li:mouseover { 26 26 action-client: addClass; 27 27 addClass-value: onHover; … … 31 31 action-client: removeClass; 32 32 removeClass-value: onHover; 33 } 33 }*/ 34 34 35 35 … … 48 48 49 49 /* Visibility switching */ 50 #tabslist .visibility:click {50 #tabslist input.visibility:click { 51 51 action-server: plonetabs-toggleActionsVisibility; 52 52 plonetabs-toggleActionsVisibility-id: nodeAttr(id, true); … … 63 63 /* Delete action link */ 64 64 #tabslist .delete:click { 65 evt-click-preventdefault: True; 66 evt-click-allowbubbling: True; 65 evt-click-preventdefault: true; 67 66 action-server: plonetabs-deleteAction; 68 67 plonetabs-deleteAction-id: nodeAttr(id, true); … … 70 69 } 71 70 71 /* Actions edit */ 72 #tabslist .tab-title:click { 73 action-server: plonetabs-editAction; 74 plonetabs-editAction-id: nodeAttr(id, true); 75 plonetabs-editAction-category: stateVar(plonetabs-category); 76 } 72 77 78 /*#tabslist .url-helper:click { 79 action-client: executeCommand; 80 executeCommand-name: addClass; 81 executeCommand-selector: #tabslist li; 82 executeCommand-selectorType: parentnode; 83 executeCommand-value: editing; 84 }*/ 85 86 /* Edit cancel button */ 87 #tabslist .editcancel:click { 88 evt-click-preventdefault: true; 89 action-server: plonetabs-editCancel; 90 plonetabs-editCancel-id: nodeAttr(id, true); 91 plonetabs-editCancel-category: stateVar(plonetabs-category); 92 } 93 94 /* Edit save button */ 95 #tabslist .editsave:click { 96 evt-click-preventdefault: true; 97 action-server: plonetabs-editSave; 98 plonetabs-editSave-id: nodeAttr(id, true); 99 100 plonetabs-editSave-category: stateVar(plonetabs-category); 101 } 102 103 /* Collapsible sections */ 104 .collapseAdvanced .headerAdvanced:click { 105 action-client: plonetabs-toggleCollapsible; 106 } 107 108 109 qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/actionslist.pt
r1082 r1087 2 2 dummy python:request.RESPONSE.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT'); 3 3 category python:options.get('category', None) or 'portal_tabs'" 4 tal:repeat="tab python:view.getPortalActions(category)">4 tal:repeat="tab options/tabs|python:view.getPortalActions(category)"> 5 5 <li tal:define="id tab/id; 6 6 visible tab/visible; 7 index repeat/tab/index" 7 editing tab/editing|nothing; 8 klass python:test(visible, [], ['invisible']); 9 klass python:test(editing, klass + ['editing'], klass)" 8 10 tal:attributes="id string:tabslist_${id}; 9 11 title tab/description; 10 class python:test(visible, '', 'invisible')"> 12 class python:' '.join(klass)"> 13 11 14 <img class="drag-handle" src="++resource++drag.gif" alt="" height="11" width="25" /> 15 12 16 <div class="bridge"> 13 <input type="checkbox" class="visibility" value="1" name="visib ility" title="visibility"17 <input type="checkbox" class="visibility" value="1" name="visible" title="visibility" 14 18 tal:attributes="checked python:test(visible, 'checked', None); 15 name string: i${index}_${attrs/name}" />19 name string:${attrs/name}_${id}" /> 16 20 </div> 21 17 22 <a class="delete" href="#">Delete</a> 18 23 <span class="url-helper" tal:content="tab/url_expr">Tab Action</span> 19 24 <span class="tab-title" tal:content="tab/title">Tab Name</span> 25 20 26 <form class="editform" 21 27 method="post" 22 28 action="@@plonetabs-controlpanel" 29 name="edit_form" 23 30 tal:attributes="action string:${context/portal_url}/${attrs/action}; 24 name string: f$index">25 <input type="hidden" name="idx" tal:attributes="value index" /> 31 name string:${attrs/name}_${id}"> 32 26 33 <dl> 27 34 <dt><label>Name</label></dt> 28 <dd><input type="text" value="" name=" name"35 <dd><input type="text" value="" name="title" 29 36 tal:attributes="value tab/title; 30 name string: i${index}_${attrs/name}"/></dd>37 name string:${attrs/name}_${id}" /></dd> 31 38 </dl> 32 <dl class="collapseAdvanced expandedBlock"> 39 40 <dl class="collapseAdvanced collapsedBlock"> 33 41 <dt class="headerAdvanced">Advanced</dt> 34 42 <dd class="contentAdvanced"> 35 43 <dl> 36 44 <dt><label>URL (Expression)</label></dt> 37 <dd><input type="text" value="" name=" action" size="30"45 <dd><input type="text" value="" name="url_expr" size="30" 38 46 tal:attributes="value tab/url_expr; 39 name string: i${index}_${attrs/name}" /></dd>47 name string:${attrs/name}_${id}" /></dd> 40 48 </dl> 41 49 <dl> … … 43 51 <dd><input type="text" value="" name="id" 44 52 tal:attributes="value tab/id; 45 name string: i${index}_${attrs/name}" /></dd>53 name string:${attrs/name}_${id}" /></dd> 46 54 </dl> 47 55 <dl> … … 49 57 <dd><input type="text" value="" name="condition" size="30" 50 58 tal:attributes="value tab/available_expr; 51 name string: i${index}_${attrs/name}" /></dd>59 name string:${attrs/name}_${id}" /></dd> 52 60 </dl> 53 61 <div class="visualClear"><!-- --></div> 54 62 </dd> 55 63 </dl> 64 56 65 <div> 57 66 <input type="submit" class="editsave" i18n:attributes="value" value="Save" /> 58 67 <input type="submit" class="editcancel" i18n:attributes="value" value="Cancel" /> 59 68 </div> 69 60 70 </form> 71 61 72 </li> 62 73 </tal:tabs> qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/autogenerated.pt
r1084 r1087 11 11 tal:repeat="tab view/getRootTabs"> 12 12 <li tal:define="id tab/id; 13 visible python:not tab['exclude_from_nav']"13 visible not: tab/exclude_from_nav" 14 14 tal:attributes="id string:roottabs_${id}; 15 15 title tab/description|nothing; 16 16 class python:view.test(visible, '', 'invisible')"> 17 17 <div class="bridge"> 18 <input type="checkbox" class="visibility" value="1" name=" rootvis" title="visibility"19 tal:attributes="name string:i${repeat/tab/index}_${attrs/name};18 <input type="checkbox" class="visibility" value="1" name="id" title="visibility" 19 tal:attributes="name id; 20 20 checked python:view.test(visible, 'checked', None)" /> 21 21 </div> 22 <span class="url-helper" tal:content=" python:tab['url']">Tab Action</span>22 <span class="url-helper" tal:content="tab/url">Tab Action</span> 23 23 <span class="tab-title" tal:content="tab/name">Tab Name</span> 24 24 </li> qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/browser/templates/plonetabs.pt
r1082 r1087 67 67 <form id="addaction" 68 68 method="post" 69 action="@@plonetabs _controlpanel"69 action="@@plonetabs-controlpanel" 70 70 tal:attributes="action string:${portal_url}/${attrs/action}"> 71 71 <dl class="field-visible bridge"> … … 123 123 <tal:autogeneration condition="python:category == 'portal_tabs'"> 124 124 125 <div class="field" 126 tal:define="generated_tabs request/generated_tabs|view/isGeneratedTabs; 127 error errors/generated_tabs|nothing" 128 tal:attributes="class python:test(error, 'field error', 'field')"> 129 <input type="checkbox" 130 id="generated_tabs" 131 name="generated_tabs" 132 value="1" 133 tal:attributes="checked python:test(generated_tabs, 'checked', None)" /> 134 <label for="generated_tabs" i18n:translate="label_generated_tabs_enable">Automatically generate tabs</label> 135 <div class="formHelp" i18n:translate="help_generated_tabs"> 136 By default, all folders created at the root level will have global section 137 navigation generated. You can turn this off if you prefer manually constructing 138 this part of the navigation. 125 <form name="generated_tabs_form" 126 action="@@manage-setAutogeneration" 127 method="post" 128 tal:attributes="action string:${portal_url}/${attrs/action}"> 129 130 <div class="field" 131 tal:define="generated_tabs request/generated_tabs|view/isGeneratedTabs; 132 error errors/generated_tabs|nothing" 133 tal:attributes="class python:test(error, 'field error', 'field')"> 134 <input type="checkbox" 135 id="generated_tabs" 136 name="generated_tabs" 137 value="1" 138 tal:attributes="checked python:test(generated_tabs, 'checked', None)" /> 139 <label for="generated_tabs" i18n:translate="label_generated_tabs_enable">Automatically generate tabs</label> 140 <div class="formHelp" i18n:translate="help_generated_tabs"> 141 By default, all folders created at the root level will have global section 142 navigation generated. You can turn this off if you prefer manually constructing 143 this part of the navigation. 144 </div> 139 145 </div> 140 </div>141 146 142 <div class="field" 143 tal:define="nonfolderish_tabs request/nonfolderish_tabs|view/isNotFoldersGenerated; 144 error errors/nonfolderish_tabs|nothing" 145 tal:attributes="class python:test(error, 'field error', 'field')"> 146 <input type="checkbox" 147 id="nonfolderish_tabs" 148 name="nonfolderish_tabs" 149 value="1" 150 tal:attributes="checked python:test(nonfolderish_tabs, 'checked', None)" /> 151 <label for="nonfolderish_tabs" i18n:translate="label_nonfolderish_tabs_enable">Generate tabs for items other than folders</label> 152 <div class="formHelp" i18n:translate="help_nonfolderish_tabs"> 153 By default, any content item in the root of the portal will be shown as 154 a global section. If you turn this option off, only folders will be shown. 155 This only has an effect if "Automatically generate tabs" is enabled 147 <div class="field" 148 tal:define="nonfolderish_tabs request/nonfolderish_tabs|view/isNotFoldersGenerated; 149 error errors/nonfolderish_tabs|nothing" 150 tal:attributes="class python:test(error, 'field error', 'field')"> 151 <input type="checkbox" 152 id="nonfolderish_tabs" 153 name="nonfolderish_tabs" 154 value="1" 155 tal:attributes="checked python:test(nonfolderish_tabs, 'checked', None)" /> 156 <label for="nonfolderish_tabs" i18n:translate="label_nonfolderish_tabs_enable">Generate tabs for items other than folders</label> 157 <div class="formHelp" i18n:translate="help_nonfolderish_tabs"> 158 By default, any content item in the root of the portal will be shown as 159 a global section. If you turn this option off, only folders will be shown. 160 This only has an effect if "Automatically generate tabs" is enabled 161 </div> 156 162 </div> 157 </div>158 163 159 <ul class="csshover" id="roottabs" 160 tal:content="structure view/getGeneratedTabs" /> 164 <ul class="csshover" id="roottabs" 165 tal:content="structure view/getGeneratedTabs" /> 166 167 <div id="autogeneration_controls"> 168 <input class="submit-button" type="submit" name="generated_roots_button" value="Save" /> 169 </div> 170 171 </form> 161 172 162 173 </tal:autogeneration> qPloneTabs/branches/quintagroup.plonetabs/trunk/quintagroup/plonetabs/plugins/plugin.js
r1086 r1087 4 4 /* Base kukit plugins for plonetabs */ 5 5 6 kukit.actionsGlobalRegistry.register( 'plonetabs-redirectTo', function(oper) {7 ;;; oper.componentName = '[plonetabs-redirectTo] action';6 kukit.actionsGlobalRegistry.register("plonetabs-redirectTo", function(oper) { 7 ;;; oper.componentName = "[plonetabs-redirectTo] action"; 8 8 var wl = window.location; 9 oper.evaluateParameters([], { 'protocol': wl.protocol,10 'host': wl.host,11 'pathname': wl.pathname,12 'search': wl.search,13 'hash': wl.hash});9 oper.evaluateParameters([], {"protocol" : wl.protocol, 10 "host" : wl.host, 11 "pathname" : wl.pathname, 12 "search" : wl.search, 13 "hash" : wl.hash}); 14 14 15 15 // normalize parameters … … 25 25 }); 26 26 27 kukit.commandsGlobalRegistry.registerFromAction( 'plonetabs-redirectTo', kukit.cr.makeSelectorCommand);27 kukit.commandsGlobalRegistry.registerFromAction("plonetabs-redirectTo", kukit.cr.makeSelectorCommand); 28 28 29 kukit.actionsGlobalRegistry.register("plonetabs-toggleCollapsible", function(oper) { 30 ;;; oper.componentName = "[plonetabs-toggleCollapsible] action"; 31 oper.evaluateParameters([], {"collapsed" : "collapsedBlock", "expanded" : "expandedBlock"}); 32 33 var node = oper.node.parentNode; // collapsible section 34 35 if (hasClassName(node, oper.parms.collapsed)) { 36 removeClassName(node, oper.parms.collapsed); 37 addClassName(node, oper.parms.expanded); 38 } else { 39 removeClassName(node, oper.parms.expanded); 40 addClassName(node, oper.parms.collapsed); 41 } 42 43 }); 44 45 kukit.commandsGlobalRegistry.registerFromAction("plonetabs-toggleCollapsible", kukit.cr.makeSelectorCommand); 46 47
