Permalink
Browse files

created a templates directory and moved all the .tmpl template from t…

…he browser

directory to the templates directory, updated the browser/export.py form code
to grab templates from the new location. 

fixed the popup export form (removed formselector in themeeditor.js) so that the theme
actually downloads. 


svn path=/plone.app.themeeditor/trunk/; revision=38772
  • Loading branch information...
1 parent 41e51dd commit e849580b67b7ed2c2151edbe6e101eece15ae3ed @pigeonflight pigeonflight committed Aug 16, 2010
View
@@ -2,6 +2,18 @@ Changelog
=========
1.0a2
-------------------
+- created a templates directory and moved all the .tmpl template from the browser
+ directory to the templates directory, updated the browser/export.py form code
+ to grab templates from the new location [pigeonflight]
+
+- fixed the popup export form (removed formselector in themeeditor.js) so that the theme
+ actually downloads [pigeonflight]
+
+- added validator to checks to see that themes are named with proper dotted named [pigeonflight]
+
+- ensure that themeeditor doesn't break if the active theme declares nonexistent
+ filesystem skin folders [pigeonflight]
+
- removed redundant export.py file [pigeonflight]
- update tests including a windmill based test of the exporter [pigeonflight]
@@ -47,5 +47,9 @@
class=".export.ThemeEditorExportView"
permission="zope2.View"
/>
+ <adapter
+ factory=".validator.DottedNameValidator"
+ provides="z3c.form.interfaces.IValidator"
+ />
</configure>
@@ -5,8 +5,8 @@
import tarfile
from os.path import basename
from zope import interface, schema
-from z3c.form import form, field, button
-from plone.z3cform.layout import FormWrapper
+from z3c.form import form, field, button, validator
+from plone.z3cform.layout import FormWrapper
from plone.app.themeeditor.interfaces import _
from plone.app.themeeditor.interfaces import IResourceRetriever
from five.customerize.interfaces import IViewTemplateContainer
@@ -19,6 +19,8 @@
import tempfile
import logging
JBOTCOMPATIBLE = ('portlet','view','viewlet')
+_templates_dir = os.path.join(os.path.dirname(__file__))
+_templates_dir = os.path.join(_templates_dir,'..','templates')
LOGGER="plone.app.themeeditor"
@@ -42,12 +44,15 @@ class ThemeEditorExportForm(form.Form):
@button.buttonAndHandler(_(u'Export Customizations'))
def handleApply(self, action):
data, errors = self.extractData()
+ if errors:
+ return
output_dir,namespace_package,name,package_name = self.theme_skel(data)
self.theme_populate(output_dir,namespace_package,name,data['version'])
self.write_setuppy(data,namespace_package,package_name,output_dir)
tarball = self.theme_tarball(output_dir,namespace_package,name,data['version'])
self.theme_download(tarball)
shutil.rmtree(output_dir)
+ return "hello universe"
def theme_skel(self,data):
name = data.pop('name')
@@ -105,7 +110,6 @@ def write_setuppy(self,data,namespace_package,package_name,output_dir):
'author':data['author'],
'author_email':data['author_email'],
}
- _templates_dir = os.path.join(os.path.dirname(__file__))
template = os.path.join(_templates_dir,'setup.py.tmpl')
output_file = os.path.join(output_dir,package_name,'setup.py')
self.write_tmpl(template,output_file,vars=setup_vars)
@@ -170,30 +174,26 @@ def write_zcml_and_generic_setup(self,output_dir,namespace_package,name,base_the
# custom skins.zcml
- _templates_dir = os.path.join(os.path.dirname(__file__))
template = os.path.join(_templates_dir,'skins.zcml.tmpl')
output_file = os.path.join(output_dir,package_name,
namespace_package,name,'skins.zcml')
self.write_tmpl(template,output_file,vars=skin_vars)
# custom skins.xml
- _templates_dir = os.path.join(os.path.dirname(__file__))
template = os.path.join(_templates_dir,'skins.xml.tmpl')
output_file = os.path.join(output_dir,package_name,
namespace_package,name,'profiles',
'default','skins.xml')
self.write_tmpl(template,output_file,vars=skin_vars)
# custom viewlets.xml
- _templates_dir = os.path.join(os.path.dirname(__file__))
template = os.path.join(_templates_dir,'viewlets.xml.tmpl')
output_file = os.path.join(output_dir,package_name,
namespace_package,name,'profiles',
'default','viewlets.xml')
self.write_tmpl(template,output_file,vars=skin_vars)
# custom metadata.xml
- _templates_dir = os.path.join(os.path.dirname(__file__))
template = os.path.join(_templates_dir,'metadata.xml.tmpl')
output_file = os.path.join(output_dir,package_name,
namespace_package,name,'profiles',
@@ -243,7 +243,6 @@ def resource_to_jbot(self,resource,output_dir,namespace_package,name):
def create_jbot_zcml(self,output_dir,namespace_package,name):
package_name = "%s.%s" % (namespace_package,name)
jbot_vars = {'package_name':package_name}
- _templates_dir = os.path.join(os.path.dirname(__file__))
template = os.path.join(_templates_dir,'jbot.zcml.tmpl')
output_file = os.path.join(output_dir,package_name,
namespace_package,name,'jbot.zcml')
@@ -275,9 +274,9 @@ def jbot_resource_info(self,resource):
#ThemeEditorExportView = wrap_form(ThemeEditorExportForm)
class ThemeEditorExportView(FormWrapper):
-
+
form = ThemeEditorExportForm
-
+
def __init__(self, context, request):
FormWrapper.__init__(self, context, request)
request.set('disable_border', 1)
@@ -11,7 +11,7 @@ jq(function() {
jq('a[href*=/@@plone.app.themeeditor.export]', this).prepOverlay({
subtype: 'ajax',
filter: '#content',
- formselector: 'form'
+ //formselector: 'form',
});
jq('a[href*=/manage_main],a[href*=/@@customizezpt]', this).prepOverlay({
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+from z3c.form import validator
+from z3c.form.interfaces import IValidator
+from zope.component import adapts
+from plone.app.themeeditor.browser.export import IThemeEditorExportForm
+from zope.interface import implements, Interface, Invalid
+
+class DottedNameValidator(validator.SimpleFieldValidator):
+ implements(IValidator)
+ adapts(Interface, IThemeEditorExportForm)
+
+ def validate(self, value):
+ super(DottedNameValidator, self).validate(value)
+
+
+ names = value.split(".")
+ if len(names) < 2:
+ raise Invalid('''Not a valid theme name. There are no dots, the theme name must have a single dot
+ separating two words e.g. "plonetheme.mytheme".''')
+ if len(names) > 2:
+ raise Invalid('''Not a valid dotted theme name. There
+ should be no more than one dot in the theme name
+ separating two words e.g. "plonetheme.mytheme".''')
+
+ for name in names:
+ # Check if Python identifier,
+ # http://code.activestate.com/recipes/413487/
+ try:
+ class test(object): __slots__ = [name]
+ except TypeError:
+ raise Invalid('''Not a valid dotted theme name. %s
+ should be a simple word with no special
+ characters
+ e.g. "plonetheme.mytheme".''' % name)
+ return True
+
+# Register DottedName validator for the name field in the IThemeEditorExportForm
+validator.WidgetValidatorDiscriminators(DottedNameValidator,
+ field=IThemeEditorExportForm['name'])
@@ -47,7 +47,12 @@ def __iter__(self):
if skin_path is None:
return
for layer_path in skin_path.split(','):
- layer_folder = self.skins_tool.unrestrictedTraverse(layer_path)
+ try:
+ layer_folder = self.skins_tool.unrestrictedTraverse(layer_path)
+ except KeyError:
+ # Sometimes the active theme declares nonexistent folders
+ # this is not themeeditors fault, so we skip the error
+ continue
for name, obj in layer_folder.items():
res = CMFResourceRegistration()
res.base_skin = self.skin
@@ -62,7 +62,8 @@ def test_exporter(self):
client.waits.forPageLoad(timeout=u'20000')
client.click(link=u'Theme Editor')
client.click(link=u'Export')
- client.waits.forPageLoad(timeout=u'20000')
+ # client.waits.forPageLoad(timeout=u'20000')
+ client.waits.forElement(timeout=u'', id=u'form-widgets-name')
# fill out the form
client.type(text=u'plonetheme.test', id=u'form-widgets-name')
client.type(text=u'1.0', id=u'form-widgets-version')
@@ -72,7 +73,7 @@ def test_exporter(self):
# export the theme
# XXX not sure why it doesn't actually generate the download
client.click(id=u'form-buttons-4578706f727420437573746f6d697a6174696f6e73')
- client.waits.forPageLoad(timeout=u'220000')
+ # client.waits.forPageLoad(timeout=u'200')
client.click(xpath=u"//div[@id='pb_2']/div[1]")
def test_suite():

0 comments on commit e849580

Please sign in to comment.