diff --git a/bobtemplates/plone/base.py b/bobtemplates/plone/base.py index df2ff6c8..ee821478 100644 --- a/bobtemplates/plone/base.py +++ b/bobtemplates/plone/base.py @@ -75,6 +75,17 @@ def is_string_in_file(configurator, file_path, match_str): return False +def write_xml_tree_to_file(tree, file_path): + with open(file_path, 'wb') as xml_file: + tree.write( + xml_file, + pretty_print=True, + xml_declaration=True, + encoding='utf-8', + ) + return + + def update_file(configurator, file_path, match_str, insert_str): """Insert insert_str into given file, by match_str.""" changed = False @@ -104,6 +115,13 @@ def update_file(configurator, file_path, match_str, insert_str): print(insert_str) +def create_file_if_not_exists(file_path, example_file_path): + file_list = os.listdir(os.path.dirname(file_path)) + file_name = os.path.basename(file_path) + if file_name not in file_list: + os.rename(example_file_path, file_path) + return + def _get_package_root_folder(configurator): file_name = 'setup.py' root_folder = None @@ -122,6 +140,20 @@ def _get_package_root_folder(configurator): return root_folder +def get_file_path(configurator, dir_name, file_name): + file_path = os.path.join( + os.path.join(configurator.target_directory, dir_name), + file_name + ) + return file_path + + +def get_example_file_path(configurator, dir_name, file_name): + example_file_name = file_name + '.example' + example_file_path = get_file_path(configurator, dir_name, example_file_name) + return example_file_path + + def check_root_folder(configurator, question): """Check if we are in a package. @@ -143,6 +175,16 @@ def dottedname_to_path(dottedname): return path +def get_klass_name(name): + klass_name = name.title().replace(' ','') + return klass_name + + +def get_normalized_name(name): + normalized_name = name.replace(' ', '_').lower() + return normalized_name + + def base_prepare_renderer(configurator): """generic rendering before template specific rendering.""" configurator.variables['package.root_folder'] = _get_package_root_folder( @@ -188,3 +230,10 @@ def subtemplate_warning_post_question(configurator, question, answer): print('Abort!') sys.exit(0) return answer + +def prepare_renderer_for_subtemplate(configurator, subtemplate): + configurator = base_prepare_renderer(configurator) + configurator.variables['template_id'] = subtemplate + configurator.target_directory = configurator.variables['package_folder'] + return configurator + diff --git a/bobtemplates/plone/view.py b/bobtemplates/plone/view.py new file mode 100644 index 00000000..7ddda8c5 --- /dev/null +++ b/bobtemplates/plone/view.py @@ -0,0 +1,78 @@ +from bobtemplates.plone.base import prepare_renderer_for_subtemplate +from bobtemplates.plone.base import get_klass_name +from bobtemplates.plone.base import get_normalized_name +from bobtemplates.plone.base import create_file_if_not_exists +from bobtemplates.plone.base import update_file +from bobtemplates.plone.base import get_file_path +from bobtemplates.plone.base import get_example_file_path +from bobtemplates.plone.base import write_xml_tree_to_file +from lxml import etree + +import os + +def _update_views_py(configurator): + views_file_name = u'views.py' + views_dir = u'browser' + + views_file_path = get_file_path(configurator, views_dir, views_file_name) + views_example_file_path = get_example_file_path(configurator, views_dir, views_file_name) + create_file_if_not_exists(views_file_path, views_example_file_path) + + match_str = '-*- Extra views go here -*-' + insert_str = """ +class {0}View(BrowserView): + \"\"\" {1} \"\"\" + + def the_title(): + return u'{2}' + """ + insert_str = insert_str.format( + configurator.variables['view_name_klass'], + configurator.variables['description'], + configurator.variables['title'] + ) + + update_file(configurator, views_file_path, insert_str, match_str) + return + + +def _update_configure_zcml(configurator): + file_name = u'configure.zcml' + dir_name = u'browser' + + file_path = get_file_path(configurator, dir_name, file_name) + example_file_path = get_example_file_path(configurator, dir_name, file_name) + + with open(file_path, 'r') as xml_file: + tree = get_xml_tree(xml_file) + configure_tag = tree.getroot() + + attributes = { + 'name' : configurator.variables['view_name'] , + 'for' : '*', + 'class' : \ + '.views.' + configurator.variables['view_name_klass'] + 'View', + 'template' : 'templates/' + configurator.variables['view_name'], + 'permission' : 'zope2.View' + } + + _ = etree.SubElement(configure_tag, + '{http://namespaces.zope.org/browser}page', + attrib=attributes) + + write_xml_tree_to_file(tree, file_path) + return + + +def prepare_renderer(configurator): + configurator = prepare_renderer_for_subtemplate(configurator, + subtemplate='view') + view_name = configurator.variables['view_name'] + configurator.variables['view_name_klass'] = get_klass_name(view_name) + configurator.variables['view_name_normalized'] = \ + get_normalized_name(view_name) + return configurator + +def post_renderer(configurator): + _update_views_py(configurator) + _update_configure_zcml(configurator) diff --git a/bobtemplates/plone/view/.mrbob.ini b/bobtemplates/plone/view/.mrbob.ini new file mode 100644 index 00000000..439a4548 --- /dev/null +++ b/bobtemplates/plone/view/.mrbob.ini @@ -0,0 +1,27 @@ +[questions] +subtemplate_warning.question = Still want to run this subtemplate? +subtemplate_warning.required = True +subtemplate_warning.default = No +subtemplate_warning.pre_ask_question = bobtemplates.plone.base:subtemplate_warning +subtemplate_warning.post_ask_question = mrbob.hooks:validate_choices + bobtemplates.plone.base:subtemplate_warning_post_question +subtemplate_warning.choices = Yes|No +subtemplate_warning.choices_delimiter = | + +view_name.question = View Name +view_name.required = True +view_name.default = training +view_name.help = Should be something like 'Training' + +title.question = Title +title.default = Welcome +title.required = True + +description.question = Description +description.default = A generic webpage +description.required = True + +[template] +pre_render = bobtemplates.plone.view:prepare_renderer +post_render = bobtemplates.plone.view:post_renderer +post_ask = bobtemplates.plone.base:set_global_vars diff --git a/bobtemplates/plone/view/browser/configure.zcml.bob b/bobtemplates/plone/view/browser/configure.zcml.bob new file mode 100644 index 00000000..0fbaa7d1 --- /dev/null +++ b/bobtemplates/plone/view/browser/configure.zcml.bob @@ -0,0 +1,5 @@ + + + diff --git a/bobtemplates/plone/view/browser/templates/+view_name+.pt b/bobtemplates/plone/view/browser/templates/+view_name+.pt new file mode 100644 index 00000000..4d062287 --- /dev/null +++ b/bobtemplates/plone/view/browser/templates/+view_name+.pt @@ -0,0 +1,10 @@ + + + +

+ + + diff --git a/bobtemplates/plone/view/browser/views.py.example.bob b/bobtemplates/plone/view/browser/views.py.example.bob new file mode 100644 index 00000000..2adfe14c --- /dev/null +++ b/bobtemplates/plone/view/browser/views.py.example.bob @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from Products.Five.browser import BrowserView +# -*- Extra imports go here -*- + + +# -*- Extra views go here -*-