From 5168df3527056a01fa0ba11d4f40e9039350808f Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Wed, 19 Dec 2012 14:32:58 +0100 Subject: [PATCH] fix prelude/requirements system --- engine/composite.py | 2 +- engine/plugin.py | 45 ++++++++++++++++++++++------ engine/prelude.py | 27 +++++++++++++++-- engine/templates/header-prelude.html | 12 ++++++++ engine/views.py | 14 +++++---- plugins/simplelist.py | 19 ++++++++++-- plugins/slicelist.py | 21 +++++++++++++ plugins/templates/simplelist.html | 4 +-- static/js/need-datatables.js | 2 -- static/js/with-datatables.js | 2 ++ templates/layout-myslice.html | 7 +---- 11 files changed, 125 insertions(+), 30 deletions(-) create mode 100644 engine/templates/header-prelude.html create mode 100644 plugins/slicelist.py delete mode 100644 static/js/need-datatables.js create mode 100644 static/js/with-datatables.js diff --git a/engine/composite.py b/engine/composite.py index c89abc17..71f358da 100644 --- a/engine/composite.py +++ b/engine/composite.py @@ -3,8 +3,8 @@ from engine.plugin import Plugin class Composite (Plugin): def __init__ (self, sons=[], *args, **kwds): - self.sons=sons Plugin.__init__ (self, *args, **kwds) + self.sons=sons def insert (self, plugin): self.sons.append(plugin) diff --git a/engine/plugin.py b/engine/plugin.py index 5de2d768..3b52c804 100644 --- a/engine/plugin.py +++ b/engine/plugin.py @@ -8,6 +8,13 @@ from django.template.loader import render_to_string from engine.prelude import Prelude +# set to +# . False : silent +# [ 'SliceList', 'TabbedView' ] : to debug these classes +# True : to debug all slices + +DEBUG= [ 'SliceList' ] + class Plugin: uid=0 @@ -23,7 +30,14 @@ class Plugin: # e.g. SimpleList (list=[1,2,3]) => _settings = { 'list':[1,2,3] } # our own settings are not made part of _settings but could be.. self._settings=settings -# print "Created plugin with settings %s"%self._settings.keys() + if self.need_debug(): + print "Plugin.__init__ Created plugin with settings %s"%self._settings.keys() + + # subclasses might handle some fields in their own way, + # in which case this call is needed to capture that setting + # see e.g. SimpleList or SliceList for an example of that + def add_to_settings (self, setting_name): + self._settings[setting_name]=getattr(self,setting_name) def classname (self): try: return self.__class__.__name__ @@ -38,6 +52,12 @@ class Plugin: def is_hidable (self): return self.hidable def is_hidden_by_default (self): return self.hidden_by_default + ########## + def need_debug (self): + if not DEBUG: return False + if DEBUG is True: return True + else: return self.classname() in DEBUG + # returns the html code for that plugin # in essence, wraps the results of self.render_content () def render (self, request): @@ -49,10 +69,11 @@ class Plugin: # call render_content plugin_content = self.render_content (request) # expose _settings in json format to js - settings_json = json.dumps(self._settings, separators=(',',':')) + settings_json = json.dumps (self._settings, separators=(',',':')) result = render_to_string ('widget-plugin.html', - {'uuid':uuid, 'classname':classname, + {'uuid':uuid, + 'classname':classname, 'visible':self.is_visible(), 'hidable':self.is_hidable(), 'hidden':self.is_hidden_by_default(), @@ -63,7 +84,10 @@ class Plugin: # handle requirements() if defined on this class try: self.handle_requirements (request, self.requirements()) - except: + except AttributeError: + # most likely the object does not have that method defined, which is fine + pass + except: import traceback traceback.print_exc() pass @@ -83,10 +107,12 @@ class Plugin: # xxx we might need to check that this does not overwrite env.. env.update(self._settings) result=render_to_string (template, env) - print "%s.render_content: BEG --------------------"%self.classname() - print "env=%s"%env.keys() - print result - print "%s.render_content: END --------------------"%self.classname() + if self.need_debug(): + print "%s.render_content: BEG --------------------"%self.classname() + print "template=%s"%template + print "env=%s"%env.keys() + # print result + print "%s.render_content: END --------------------"%self.classname() return result #################### requirements/prelude management @@ -116,7 +142,8 @@ class Plugin: # or from the result of self.requirements() def handle_requirements (self, request, d): for (k,v) in d.iteritems(): - print "%s: handling requirement %s"%(self.classname(),v) + if self.need_debug(): + print "%s: handling requirement %s"%(self.classname(),v) method_name='add_'+k method=Plugin.__dict__[method_name] method(self,request,v) diff --git a/engine/prelude.py b/engine/prelude.py index 6be64415..bf5e0a91 100644 --- a/engine/prelude.py +++ b/engine/prelude.py @@ -1,5 +1,7 @@ from types import StringTypes, ListType +from django.template.loader import render_to_string + class Prelude: """A class for collecting dependencies on js/css files or fragments""" @@ -29,10 +31,29 @@ class Prelude: def add_css_chunks (self, x): self.css_chunks += Prelude._normalize (x) + # first attempt was to use a simple dict like this + # env={} + # env['js_files']= self.js_files + # env['css_files']= self.css_files + # env['js_chunks']= '\n'.join(self.js_chunks) + # env['css_chunks']='\n'.join(self.css_chunks) + # return env + # together with this in layout-myslice.html + # {% for js_file in js_files %} {% insert_str prelude js_file %} {% endfor %} + # {% for css_file in css_files %} {% insert_str prelude css_file %} {% endfor %} + # somehow however this would not work too well, + # probably insert_above is not powerful enough to handle that + # + # so a much simpler and safer approach is for use to compute the html header directly def render_env (self): env={} env['js_files']= self.js_files env['css_files']= self.css_files - env['js_chunks']= '\n'.join(self.js_chunks) - env['css_chunks']='\n'.join(self.css_chunks) - return env + env['js_chunks']= self.js_chunks + env['css_chunks']=self.css_chunks + # not sure how this should be done more cleanly + from myslice.settings import STATIC_URL + env ['STATIC_URL'] = STATIC_URL + # render this with prelude.html and put the result in header_prelude + header_prelude = render_to_string ('header-prelude.html',env) + return { 'header_prelude' : header_prelude } diff --git a/engine/templates/header-prelude.html b/engine/templates/header-prelude.html new file mode 100644 index 00000000..e75c7c5a --- /dev/null +++ b/engine/templates/header-prelude.html @@ -0,0 +1,12 @@ +{% for js_file in js_files %} + +{% endfor %} +{% for css_file in css_files %} + +{% endfor %} + + diff --git a/engine/views.py b/engine/views.py index 7b05cc7c..b67197d0 100644 --- a/engine/views.py +++ b/engine/views.py @@ -7,6 +7,7 @@ from django.shortcuts import render_to_response from plugins.verticallayout import VerticalLayout from plugins.simplelist import SimpleList +from plugins.slicelist import SliceList from myslice.viewutils import topmenu_items, the_user, hard_wired_slice_names @@ -34,7 +35,8 @@ def test_plugin_view (request): plugin_main1 = SimpleList (list=hard_wired_list, header='Hard wired', - foo='the value for foo') + foo='the value for foo', + with_datatables=True) plugin_main2 = SimpleList (hidable=True, list=hard_wired_slice_names, headers='Slices in main content') @@ -49,10 +51,11 @@ def test_plugin_view (request): ########## # lacks a/href to /slice/%s - plugin_related = SimpleList (visible=True, hidable=True, - need_datatables='yes', - list=hard_wired_slice_names, - header='Slices' ) + plugin_related = SliceList (visible=True, + hidable=True, + with_datatables='yes', + list=hard_wired_slice_names, + header='Slices' ) content_related = plugin_related.render (request) # likewise but on the side view template_env [ 'content_related' ] = content_related @@ -65,6 +68,7 @@ def test_plugin_view (request): # request.plugin_prelude holds a summary of the requirements() for all plugins # define {js,css}_{files,chunks} prelude_env = request.plugin_prelude.render_env() + print 'prelude_env',prelude_env template_env.update(prelude_env) return render_to_response ('view-plugin.html',template_env, diff --git a/plugins/simplelist.py b/plugins/simplelist.py index c2ba250e..6e041c61 100644 --- a/plugins/simplelist.py +++ b/plugins/simplelist.py @@ -2,15 +2,30 @@ from engine.plugin import Plugin class SimpleList (Plugin) : + # it would make sense to *not* define any constructor here and let Plugin kick in + # however it feels nicer this way as we document the settings used in our own template + # plus it's less confusing for any subclass if they can be sure which constructor to call + def __init__ (self, list=[], with_datatables=False, **settings): + Plugin.__init__ (self, **settings) + self.list=list + self.add_to_settings ('list') + self.with_datatables = with_datatables + self.add_to_settings ('with_datatables') + # SimpleList is useless per se anyways def title (self) : return "Title for Simple List" def template (self): return "simplelist.html" def requirements (self): - return { 'js_files' : [ "js/simplelist.js" ], + reqs = { 'js_files' : [ "js/simplelist.js" ], 'css_files': [ "css/simplelist.css" ], + } + if self.with_datatables: + reqs['js_files'].append ("datatables/js/dataTables.js") + reqs['js_files'].append ("js/with-datatables.js") + print self.classname(),reqs + return reqs # for tests # 'js_chunks' : "/* a javascript chunk */", # 'css_chunks': "/* a css style */ ", - } diff --git a/plugins/slicelist.py b/plugins/slicelist.py new file mode 100644 index 00000000..ac8fc25f --- /dev/null +++ b/plugins/slicelist.py @@ -0,0 +1,21 @@ +from plugins.simplelist import SimpleList + +class SliceList (SimpleList): + + def __init__ (self, list=[], **settings): + SimpleList.__init__(self, **settings) + self.list = [ "%s"%(x,x) for x in list ] + self.add_to_settings ('list') + + def title (self): + return "Slice list" + +# def requirements (self): +# reqs=SimpleList.requirements(self) +# reqs['js_files'].append('slice.js') +# reqs['js_files'].append('slice2.js') +# reqs['css_files'].append('slice.css') +# reqs['css_files'].append('slice2.css') +# reqs['js_chunks']=['js chunk1','js chunk2'] +# reqs['css_chunks']=['css chunk1','css chunk2'] +# return reqs diff --git a/plugins/templates/simplelist.html b/plugins/templates/simplelist.html index fb5812ef..39c0298a 100644 --- a/plugins/templates/simplelist.html +++ b/plugins/templates/simplelist.html @@ -1,10 +1,10 @@ - +
{% if header %} {% endif %} {% for item in list %} - + {% endfor %}
{{ header }}
{{ item }}
{{ item|safe }}
diff --git a/static/js/need-datatables.js b/static/js/need-datatables.js deleted file mode 100644 index ad1664b0..00000000 --- a/static/js/need-datatables.js +++ /dev/null @@ -1,2 +0,0 @@ -/* elements with class 'need-datatables' are set to use datatables */ -$(document).ready(function() {$('.need-datatables').each(function() { $(this).dataTable() } ) } ) diff --git a/static/js/with-datatables.js b/static/js/with-datatables.js new file mode 100644 index 00000000..6acc7648 --- /dev/null +++ b/static/js/with-datatables.js @@ -0,0 +1,2 @@ +/* elements with class 'with-datatables' are set to use datatables */ +$(document).ready(function() {$('.with-datatables').each(function() { window.console.log('here'); $(this).dataTable() } ) } ) diff --git a/templates/layout-myslice.html b/templates/layout-myslice.html index 855e4aad..f8cdc10b 100644 --- a/templates/layout-myslice.html +++ b/templates/layout-myslice.html @@ -9,13 +9,12 @@ +{{ header_prelude }} {# let's add these ones no matter what #} @@ -25,10 +24,6 @@ {% insert_str prelude "js/plugin.js" %} {% insert_str prelude "css/myslice.css" %} -{# also add the stuff as collected in a Prelude class #} -{% for js_file in js_files %} {% insert_str prelude js_file %} {% endfor %} -{% for css_file in css_files %} {% insert_str prelude css_file %} {% endfor %} - {% block container %} -- 2.43.0