Metadata-Version: 1.0 Name: quintagroup.themetemplate Version: 0.26 Summary: Quintagroup theme template for Plone 3 with nested namespace Home-page: http://svn.quintagroup.com/products/quintagroup.themetemplate Author: Andriy Mylenkyy Author-email: support@quintagroup.com License: GPL Description: qplone3 theme template ====================== quintagroup.themetemplate is an enhanced "Plone 3 Theme" template from Zopeskel, that includes addcontent local command, which allows you to extend base Plone theme by additional elements, such as: skin layers, portlets, viewlets, css and js resources, and objects in zexp files. This package is an analogue of Archetype template in terms of its functionality. quintagroup.themetemplate package is used for development of all Quintagroup themes for Plone 3 at http://skins.quintagroup.com. Contents -------- 1. Overview 2. Creating theme package 3. Extending theme 4. Release notes Overview ======== This theme template allows you to create initial theme package skeleton, i.e. create plone3 theme python package with nested namespace (this is different from deafult plone3_theme template in Zopeskel) After that you can extend theme package by the following elements: - skin-layer(s) - portlet(s) - viewlet(s) - css, js resource(s) - objects in zexp files Creation of a package is performed with *paster create* PasteScript command. Theme extending with other resources can be done with *paster addcontent* local ZopeSkel command (extended in this product). Creating theme package ====================== In the demo below we'll use "--overwrite" option as multiple templates are running one after another, and some same-named files should be overwritten without extra questions. Let's create plone-3 theme python package. Use `paster create` command for that:: >>> paster('create -t qplone3_theme quintagroup.theme.example --overwrite') paster create -t qplone3_theme quintagroup.theme.example ... ... You got standard python package content with - *quintagroup* upper level namespace. - *quintagroup.theme.example-configure.zcml* - zcml file for adding into package-includes directory Check that:: >>> package_dir = 'quintagroup.theme.example' >>> objects = ['setup.py', 'quintagroup', 'quintagroup.theme.example-configure.zcml'] >>> objects.sort() >>> [o for o in objects if o in os.listdir(package_dir)] ['quintagroup', 'quintagroup.theme.example-configure.zcml', 'setup.py'] *qplone3_theme* template - creates theme with nested namespace. By default - theme is placed in *quintagroup.theme.<3rd part of dotted package name> namespace* in our case - quintagroup.theme.example So check namespaces:: >>> theme_namespace = os.path.join(package_dir,'quintagroup','theme','example') >>> os.path.isdir(theme_namespace) True Theme holds 3 subdirectories (browser, profiles, skins):: >>> cd(theme_namespace) >>> dirs = ('skins', 'browser', 'profiles') >>> [True for d in dirs if d in os.listdir('.')] [True, True, True] And initialization files (__init__.py, configure.zcml) :: >>> files = ('__init__.py', 'configure.zcml') >>> [True for d in files if d in os.listdir('.')] [True, True] *browser* directory ------------------- Browser directory contains: - 'templates' resource directory - interfaces.py module with IThemeSpecific marker interface - configure.zcml, with registered theme marker interface:: >>> ls('browser') __init__.py configure.zcml interfaces.py templates >>> cat('browser/interfaces.py') from plone.theme.interfaces import IDefaultPloneLayer class IThemeSpecific(IDefaultPloneLayer): ... >>> cat('browser/configure.zcml') ... As we see, default theme name is 'Custom Theme', but on theme creation you can point out your own name. Check this ... First create configuration file with different skin name:: >>> conf_data = """ ... [pastescript] ... skinname=My Theme Name ... """ >>> file('theme_config.conf','w').write(conf_data) Create the same theme with your own skin name and check this:: >>> paster('create -t qplone3_theme quintagroup.theme.example --overwrite --config=theme_config.conf') paster create ... >>> cd(package_dir) >>> cat('quintagroup/theme/example/browser/configure.zcml') ... *skins* directory ----------------- It contains only README.txt file and NO SKIN LAYERS YET. This is a job for localcommand ;) But check whether I am right ...:: >>> cd('quintagroup/theme/example') >>> ls('skins') README.txt *profiles* directory -------------------- There is 'default' and uninstall profiles inside:: >>> 'default' in os.listdir('profiles') True >>> 'uninstall' in os.listdir('profiles') True There are the following items in default profile: - import_steps.xml - for any reason. - skins.xml - for registering skins directory:: >>> cd('profiles/default') >>> 'import_steps.xml' in os.listdir('.') True >>> 'skins.xml' in os.listdir('.') True *skins.xml* profile makes your theme default on installation and uses layers list from 'Plone Default' for our theme, without any new layers (yet):: >>> cat('skins.xml') ... ... ... *import_steps.xml* - call _setupVarious_ function from _setuphandlers.py_ module for additional installation steps:: >>> cat('import_steps.xml') ... ... Look at setuphandlers.py module:: >>> cd('../..') >>> cat('setuphandlers.py') def setupVarious(context): ... Extending theme =============== One of the best features, which ZopeSkel package brings, is *localcommand*. This part shows how you can extend a theme (generated with qplone3_theme ZopeSkel template) with additional useful stuff: - skin layers - views - viewlets - portlets - css - javascripts - objects in zexp files So, in qplone3_theme generated package you can use *addcontent* ZopeSkel local command. IMPORTANT TO NOTE: localcommand (addcontent in our case) should be called in any subdirectory of the generated theme package. And it won't work outside this package:: >>> paster('addcontent -a') paster addcontent -a ... css_dtml_skin: A DTML file in skin layer with CSS registration css_resource: A Plone 3 CSS resource template ... import_zexps: A template for importing zexp-objects into portal on installation js_resource: A Plone 3 JS resource template N portlet: A Plone 3 portlet ... skin_layer: A Plone 3 Skin Layer ... N view: A browser view skeleton viewlet_hidden: A Plone 3 Hidden Viewlet template viewlet_order: A Plone 3 Order Viewlet template ... We can see a list of extention subtemplates, which can be used for our theme. 'N' character tells us that these subtemplates are registered for other (archetype) template, but it does not matter - they can correctly extend our theme. Adding SKIN LAYER ================= For that case use *skin_layer* subtemplate with *addcontent* local command:: >>> paster('addcontent skin_layer') paster addcontent skin_layer ... Recursing into profiles ... This command adds NEW 'skin_layer' (default name) directory to _skins_ directory, with only CONTENT.txt file inside:: >>> 'skin_layer' in os.listdir('skins') True >>> ls('skins/skin_layer') CONTENT.txt *skins.xml* profile is also updated:: >>> cat('profiles/default/skins.xml') ... ... ... ... ... We can see, that: - skin_layer directory was registered as Filesystem Directory View - skin_layer Filesystem Directory View was added to our theme layers list Adding PORTLET ============== Only initialization files are available in portlets directory before adding new portlet:: >>> ls('portlets') __init__.py configure.zcml Add portlet with *portlet* subtemplate:: >>> paster('addcontent portlet') paster addcontent portlet ... ... Recursing into portlets ... After executing this local command ... configure.zcml file in the theme root directory - includes portlets registry:: >>> cat('configure.zcml') ... exampleportlet.pt template and exampleportlet.py script added to portlets directory:: >>> files = ('exampleportlet.pt', 'exampleportlet.py') >>> [True for d in files if d in os.listdir('portlets')] [True, True] And portlets/configure.zcml - register new portlet:: >>> cat('portlets/configure.zcml') ... Finally, new portlet type is registered in portlets.xml profile:: >>> cat('profiles/default/portlets.xml') ... ... Thanks to ZopeSkel developers for this subtempalte ;) Adding CSS resource =================== Use *css_resource* subtemplate:: >>> paster("addcontent css_resource") paster addcontent css_resource ... Recursing into browser ... Recursing into profiles ... This template adds (if does not exist yet) _stylesheets_ directory in _browser_ directory:: >>> 'stylesheets' in os.listdir('browser') True In _stylesheets_ resource directory empty main.css stylesheet resource added:: >>> 'main.css' in os.listdir('browser/stylesheets') True >>> cat('browser/stylesheets/main.css') New resource directory was registered in configure.zcml:: >>> cat('browser/configure.zcml') ... And cssregistry.xml profile was added into profiles/default directory with registered main.css stylesheet:: >>> 'cssregistry.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/cssregistry.xml') ... Adding CSS resource as dtml-file into skins layer ================================================= This template actually absolutely same to the previouse one, but layer_name variable added to point in which skin layer css dtml-file should be added to. And, of course, css resource added into pointing *skins//.dtml* file. This subtemplate has several benefits before registering css as resource layer: - in dtml file you can use power of dtml language - this resource can be overriden by customer if he needs that IMPORTANT: For add css resource in registered skin layer - you should use this subtemplate in conjunction with *skin_layer* one. Use *css_dtml_skin* subtemplate:: >>> paster("addcontent css_dtml_skin") paster addcontent css_dtml_skin ... Recursing into profiles ... Recursing into skins ... This template adds main.css.dtml file into skins/skin_layer folder:: >>> 'main.css.dtml' in os.listdir('skins/skin_layer') True The main.css.dtml file already prepared to use as dtml-document:: >>> cat('skins/skin_layer/main.css.dtml') /* ... /* (do not remove this :) */ ... /* */ And cssregistry.xml profile was added into profiles/default directory with registered main.css stylesheet:: >>> 'cssregistry.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/cssregistry.xml') ... Adding JAVASCRIPT resource -------------------------- Use *js_resource* subtemplate:: >>> paster('addcontent js_resource') paster addcontent js_resource ... Recursing into browser ... Recursing into profiles ... This template adds (if does not exist yet) _scripts_ directory in _browser_ directory:: >>> 'scripts' in os.listdir('browser') True Empty foo.js javascript file was added to _scripts_ directory:: >>> 'foo.js' in os.listdir('browser/scripts') True >>> cat('browser/scripts/foo.js') New resource directory was registered in configure.zcml, if has not been registered yet:: >>> cat('browser/configure.zcml') ... cssregistry.xml profile was added into profiles/default directory (if does not exist yet), and register new foo.js javascript resource:: >>> 'jsregistry.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/jsregistry.xml') ... ... Test viewlets subtemplates ========================== There are 2 types of viewlet subtemplates: - viewlet_order - viewlet_hidden The first one is used for adding new viewlets and setting viewlets order for the ViewletManager, the second one only hides viewlet in pointed ViewletManager. Ordered NEW viewlet ------------------- Use *viewlet_order* subtemplate:: >>> paster('addcontent viewlet_order') paster addcontent viewlet_order ... Recursing into browser ... Recursing into templates ... Recursing into profiles ... This template adds (if not exist ;)) _viewlets.py_ module in browser directory. With added Example ViewletBase class, which is bound to templates/example_viewlet.pt template:: >>> 'viewlets.py' in os.listdir('browser') True >>> cat('browser/viewlets.py') from Products.CMFCore.utils import getToolByName from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile from plone.app.layout.viewlets import common ... class Example(common.ViewletBase): render = ViewPageTemplateFile('templates/example_viewlet.pt') Check template file in templates directory:: >>> 'example_viewlet.pt' in os.listdir('browser/templates') True >>> cat('browser/templates/example_viewlet.pt') New viewlet is registered in configure.zcml:: >>> cat('browser/configure.zcml') ... viewlets.xml profile is added to profiles/default directory with new viewlet registration, ordered for specified viewlet manager:: >>> 'viewlets.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/viewlets.xml') ... ... Hide EXISTING viewlet --------------------- For that case you can use *viewlet_hidden* subtemplate:: >>> paster('addcontent viewlet_hidden') paster addcontent viewlet_hidden ... Recursing into profiles ... As we see from upper log - there is stuff for adding/updating profiles only. There is viewlet.xml profile in profiles/default directory which hides viewlet for specified viewlet manager:: >>> 'viewlets.xml' in os.listdir('profiles/default') True >>> cat('profiles/default/viewlets.xml') ... ... ... Adding ZEXPs importing ====================== Imagine situation, when you develop a theme, which uses some extra portal objects (documents with text for some potlets) Then customer of your theme can edit these objects according to his need. For this situation *import_zexps* subtemplate exists. *import_zexps* subtemplate extends your theme with mechanism for importing list of zexp formated files into portal root on theme instllation:: >>> paster('addcontent import_zexps') paster addcontent import_zexps ... ... Recursing into import ... Recursing into profiles ... Inserting from profiles.zcml_insert ... ... Inserting from setuphandlers.py_insert into ... ... As we see from the upper log - 'import' directory was added into root of the theme - profiles stuff was updated - profiles.zcml file is updated - some stuff into setuphandlers.py module was inserted 1. There was empty 'import' directory added, where you will put zexp objects for install into portal root.:: >>> ls('import') CONTENT.txt 2. import_steps.xml was added in profiles/import_zexps directory, which contains additional *quintagroup.theme.example.import_zexps* step:: >>> 'import_zexps' in os.listdir('profiles') True >>> 'import_steps.xml' in os.listdir('profiles/import_zexps') True >>> cat('profiles/import_zexps/import_steps.xml') ... Import zexp objects into portal on My Theme Name theme installation ... 3. profiles.zcml configuration updated with new genericsetup profile for zexps importing:: >>> cat('profiles.zcml') ... 4. Check setuphandlers.py module - there must be importZEXPs function defined:: >>> cat('setuphandlers.py') def setupVarious(context): ... def importZEXPs(context): ... Then simply prepare zexp objects and copy them to *import* directory. RELEASE NOTES ! =============== Before releasing theme - I suggest to clean up setup.py script: - remove *theme_vars* argument (its value is useful only for theme development) - remove *entry_points* argument (same reason). It's useless in plone for now. - And remove *paster_plugins* argument too (it has sence in conjunction with entry_points during theme developing) Steps mentioned above prevent possible problems with theme distribution/deployment. Notes: ------ * quintagroup.themetemplate v0.25 compatible with ZopeSkel >= 2.15 Changelog ========= 0.26 (2010-11-22) ----------------- - Updated README: hidden --no-interactive option, added note about reason of --overwrite option usage. [mylan] 0.25 (2010-06-24) ----------------- - Correct version of the pacakge [mylan] - Fix incompatibility wity ZopeSkel>=2.15 [mylan] - Updated tests [mylan] 0.2.2 (unreleased) ------------------ - Updated import_zexps subtemplate - move this step into separate genericsetup profile [mylan] - Updated tests for changed import_zexps subtemplate [mylan] 0.2 (unreleased) ---------------- - Added new css_dtml_skin subtemplate [mylan] - Added tests for css_dtml_skin subtemplate [mylan] 0.14 (unreleased) ----------------- - Refactoring theme vars storage-now storing in separate theme_vars.cfg file, without distutils writers [mylan] - Cleanup code [mylan] 0.11 (2009-04-13) ----------------- - Removed setup.cfg [mylan] 0.10 (2009-04-13) ----------------- - Updated README [olha] 0.9 (2009-04-11) ---------------- - Changed package name/namespace to quintagroup.themetemplate. [mylan] 0.8 (2009-04-10) ---------------- * Update tests, readme [mylan] * Update viewlet-order subtemplate [mylan] * Fix uninstall bug [mylan] 0.7 (unreleased) ---------------- * Add uninstall profile to fix skins tool after theme is uninstalled [piv] 0.1 (unreleased) ---------------- * Initial import Theme template with nested namespace. Support ZopeSkel' "addcommad" local command for extend Theme template, support extending with portlet, view local templates. [mylan] Keywords: ZopeSkel theme template plone3 Quintagroup Platform: UNKNOWN Classifier: Programming Language :: Python Classifier: Topic :: Software Development :: Libraries :: Python Modules