source: products/quintagroup.themetemplate/trunk/quintagroup.themetemplate.egg-info/PKG-INFO @ 1364

Last change on this file since 1364 was 1364, checked in by mylan, 12 years ago

Update history, bump version to 0.2.2, updated egg-info data

File size: 26.9 KB
Line 
1Metadata-Version: 1.0
2Name: quintagroup.themetemplate
3Version: 0.2.2
4Summary: Quintagroup theme template for Plone 3 with nested namespace
5Home-page: http://svn.quintagroup.com/products/quintagroup.themetemplate
6Author: Andriy Mylenkyy
7Author-email: support@quintagroup.com
8License: GPL
9Description: qplone3 theme template
10        ======================
11       
12        quintagroup.themetemplate is an enhanced "Plone 3 Theme" template from Zopeskel,
13        that includes addcontent local command, which allows you to extend base Plone theme
14        by additional elements, such as: skin layers, portlets, viewlets, css and js resources,
15        and objects in zexp files. This package is an analogue of Archetype template in terms
16        of its functionality.
17       
18        quintagroup.themetemplate package is used for development of all Quintagroup themes
19        for Plone 3 (http://skins.quintagroup.com).
20       
21        Contents
22        --------
23        1. Overview
24        2. Creating theme package
25        3. Extending theme
26        4. Release notes
27       
28        Overview
29        ========
30       
31        This theme template allows you to create initial theme package skeleton,
32        i.e. create plone3 theme python package with nested namespace (this is different from
33        deafult plone3_theme template in Zopeskel)
34       
35        After that you can extend theme package by the following elements:
36       
37        - skin-layer(s)
38        - portlet(s)
39        - viewlet(s)
40        - css, js resource(s)
41        - objects in zexp files
42       
43        Creation of a package is performed with *paster create* PasteScript command.
44        Theme extending with other resources can be done with *paster addcontent*
45        local ZopeSkel command (extended in this product).
46       
47        Creating theme package
48        ======================
49       
50        Let's create plone-3 theme python package.
51        Use `paster create` command for that::
52       
53        >>> paster('create -t qplone3_theme plone.example --no-interactive --overwrite')
54        paster create -t qplone3_theme plone.example --no-interactive
55        ...
56       
57        You got standard python package content with
58        - *quintagroup* upper level namespace.
59        - *plone.example-configure.zcml* - zcml file
60        for adding into package-includes directory
61       
62        Check that::
63       
64        >>> package_dir = 'plone.example'
65        >>> objects = ('setup.py', 'quintagroup', 'plone.example-configure.zcml')
66        >>> [True for o in objects if o in os.listdir(package_dir)]
67        [True, True, True]
68       
69       
70        *qplone3_theme* template - creates theme with nested namespace.
71       
72        By default - theme is placed in
73       
74        quintagroup.theme.<package name without dot> namespace
75       
76        in our case - quintagroup.theme.ploneexample
77       
78        So check namespaces::
79       
80        >>> theme_namespace = os.path.join(package_dir,'quintagroup','theme','ploneexample')
81        >>> os.path.isdir(theme_namespace)
82        True
83       
84        Theme holds 3 subdirectories (browser, profiles, skins)::
85       
86        >>> cd(theme_namespace)
87        >>> dirs = ('skins', 'browser', 'profiles')
88        >>> [True for d in dirs if d in os.listdir('.')]
89        [True, True, True]
90       
91        And initialization files (__init__.py, configure.zcml) ::
92       
93        >>> files = ('__init__.py', 'configure.zcml')
94        >>> [True for d in files if d in os.listdir('.')]
95        [True, True]
96       
97       
98        *browser* directory
99        -------------------
100       
101        Browser directory contains:
102        - 'templates' resource directory
103        - interfaces.py module with IThemeSpecific marker interface
104        - configure.zcml, with registered theme marker interface
105       
106        >>> ls('browser')
107        __init__.py
108        configure.zcml
109        interfaces.py
110        templates
111       
112        >>> cat('browser/interfaces.py')
113        from plone.theme.interfaces import IDefaultPloneLayer
114        <BLANKLINE>
115        class IThemeSpecific(IDefaultPloneLayer):
116        ...
117       
118        >>> cat('browser/configure.zcml')
119        <configure
120        ...
121        <interface
122        interface=".interfaces.IThemeSpecific"
123        type="zope.publisher.interfaces.browser.IBrowserSkinType"
124        name="Custom Theme"
125        />
126        ...
127       
128        As we see, default theme name is 'Custom Theme', but on theme
129        creation you can point out your own name. Check this ...
130       
131        First create configuration file with different skin name
132        >>> conf_data = """
133        ... [pastescript]
134        ... skinname=My Theme Name
135        ... """
136        >>> file('theme_config.conf','w').write(conf_data)
137       
138        Create the same theme with your own skin name and check this
139        >>> paster('create -t qplone3_theme plone.example --no-interactive --overwrite --config=theme_config.conf')
140        paster create ...
141        >>> cd(package_dir)
142        >>> cat('quintagroup/theme/ploneexample/browser/configure.zcml')
143        <configure
144        ...
145        <interface
146        interface=".interfaces.IThemeSpecific"
147        type="zope.publisher.interfaces.browser.IBrowserSkinType"
148        name="My Theme Name"
149        />
150        ...
151       
152       
153        *skins* directory
154        ------------------------
155       
156        It contains only README.txt file and NO SKIN LAYERS YET.
157        This is a job for localcommand ;)
158       
159        But check whether I am right ...
160        >>> cd('quintagroup/theme/ploneexample')
161        >>> ls('skins')
162        README.txt
163       
164       
165        *profiles* directory.
166        --------------------------------
167        There is 'default' and uninstall profiles inside
168        >>> 'default' in os.listdir('profiles')
169        True
170        >>> 'uninstall' in os.listdir('profiles')
171        True
172       
173        There are the following items in default profile:
174        - import_steps.xml - for any reason.
175        - skins.xml - for registering skins directory
176       
177        >>> cd('profiles/default')
178        >>> 'import_steps.xml' in os.listdir('.')
179        True
180        >>> 'skins.xml' in os.listdir('.')
181        True
182       
183        *skins.xml* profile makes your theme default on installation
184        and uses layers list from 'Plone Default' for our theme,
185        without any new layers (yet).
186       
187        >>> cat('skins.xml')
188        <?xml version="1.0"?>
189        <object name="portal_skins" ...
190        default_skin="My Theme Name">
191        ...
192        <skin-path name="My Theme Name" based-on="Plone Default">
193        <!-- -*- extra layer stuff goes here -*- -->
194        <BLANKLINE>
195        </skin-path>
196        ...
197       
198        *import_steps.xml* - call _setupVarious_ function from
199        _setuphandlers.py_ module for additional installation steps.
200       
201        >>> cat('import_steps.xml')
202        <?xml version="1.0"?>
203        ...
204        <import-step id="quintagroup.theme.ploneexample.various"
205        ...
206        handler="quintagroup.theme.ploneexample.setuphandlers.setupVarious"
207        ...
208        </import-step>
209        ...
210       
211        Look at setuphandlers.py module
212        >>> cd('../..')
213        >>> cat('setuphandlers.py')
214        def setupVarious(context):
215        ...
216       
217       
218        Extending theme
219        ===============
220       
221        One of the best features, which ZopeSkel package brings, is *localcommand*.
222       
223        This part shows how you can extend a theme (generated with qplone3_theme
224        ZopeSkel template) with additional useful stuff:
225       
226        - skin layers
227        - views
228        - viewlets
229        - portlets
230        - css
231        - javascripts
232        - objects in zexp files
233       
234        So, in qplone3_theme generated package you can use *addcontent* ZopeSkel
235        local command.
236       
237        IMPORTANT TO NOTE: localcommand (addcontent in our case) should be
238        called in any subdirectory of the generated theme package. And it won't
239        work outside this package..
240       
241        >>> paster('addcontent -a')
242        paster addcontent -a
243        ...
244        css_dtml_skin:   A DTML file in skin layer with CSS registration
245        css_resource:    A Plone 3 CSS resource template
246        ...
247        import_zexps:    A template for importing zexp-objects into portal on installation
248        js_resource:     A Plone 3 JS resource template
249        N portlet:         A Plone 3 portlet
250        ...
251        skin_layer:      A Plone 3 Skin Layer
252        ...
253        N view:            A browser view skeleton
254        viewlet_hidden:  A Plone 3 Hidden Viewlet template
255        viewlet_order:   A Plone 3 Order Viewlet template
256        ...
257       
258       
259        We can see a list of extention subtemplates, which can be used for our theme.
260        'N' character tells us that these subtemplates are registered for other (archetype)
261        template, but it does not matter - they can correctly extend our theme.
262       
263       
264        Adding SKIN LAYER
265        =================
266       
267        For that case use *skin_layer* subtemplate with *addcontent* local command
268       
269        >>> paster('addcontent --no-interactive skin_layer')
270        paster addcontent --no-interactive skin_layer
271        Recursing into profiles
272        ...
273       
274        This command adds NEW 'skin_layer' (default name) directory to _skins_ directory,
275        with only CONTENT.txt file inside.
276       
277        >>> 'skin_layer' in os.listdir('skins')
278        True
279        >>> ls('skins/skin_layer')
280        CONTENT.txt
281       
282        *skins.xml* profile is also updated:
283       
284        >>> cat('profiles/default/skins.xml')
285        <?xml version="1.0"?>
286        <object name="portal_skins" allow_any="False" cookie_persistence="False"
287        default_skin="My Theme Name">
288        ...
289        <object name="skin_layer"
290        meta_type="Filesystem Directory View"
291        directory="quintagroup.theme.ploneexample:skins/skin_layer"/>
292        <BLANKLINE>
293        <skin-path name="My Theme Name" based-on="Plone Default">
294        ...
295        <layer name="skin_layer"
296        insert-after="custom"/>
297        <BLANKLINE>
298        </skin-path>
299        ...
300       
301        We can see, that:
302        - skin_layer directory was registered as Filesystem Directory View
303        - skin_layer Filesystem Directory View was added to our theme layers list
304       
305       
306        Adding PORTLET
307        ==========================
308       
309        Only initialization files are available in portlets directory before adding new portlet.
310       
311        >>> ls('portlets')
312        __init__.py
313        configure.zcml
314       
315        Add portlet with *portlet* subtemplate.
316       
317        >>> paster('addcontent --no-interactive portlet')
318        paster addcontent --no-interactive portlet
319        Recursing into portlets
320        ...
321       
322        After executing this local command ...
323       
324        configure.zcml file in the theme root directory - includes portlets registry:
325       
326        >>> cat('configure.zcml')
327        <configure
328        ...
329        <include package=".portlets" />
330        ...
331       
332        exampleportlet.pt template and exampleportlet.py script added to portlets directory.
333        >>> files = ('exampleportlet.pt', 'exampleportlet.py')
334        >>> [True for d in files if d in os.listdir('portlets')]
335        [True, True]
336       
337        And portlets/configure.zcml - register new portlet
338        >>> cat('portlets/configure.zcml')
339        <configure
340        ...
341        <plone:portlet
342        name="quintagroup.theme.ploneexample.portlets.ExamplePortlet"
343        interface=".exampleportlet.IExamplePortlet"
344        assignment=".exampleportlet.Assignment"
345        view_permission="zope2.View"
346        edit_permission="cmf.ManagePortal"
347        renderer=".exampleportlet.Renderer"
348        addview=".exampleportlet.AddForm"
349        editview=".exampleportlet.EditForm"
350        />
351        ...
352       
353        Finally, new portlet type is registered in portlets.xml profile
354       
355        >>> cat('profiles/default/portlets.xml')
356        <?xml version="1.0"?>
357        ...
358        <portlet
359        addview="quintagroup.theme.ploneexample.portlets.ExamplePortlet"
360        title="Example portlet"
361        description=""
362        />
363        ...
364       
365        Thanks to ZopeSkel developers for this subtempalte ;)
366       
367       
368       
369        Adding CSS resource
370        ===================
371       
372        Use *css_resource* subtemplate.
373       
374        >>> paster("addcontent --no-interactive css_resource")
375        paster addcontent --no-interactive css_resource
376        Recursing into browser
377        ...
378        Recursing into profiles
379        ...
380       
381        This template adds (if does not exist yet) _stylesheets_ directory in _browser_
382        directory
383       
384        >>> 'stylesheets' in os.listdir('browser')
385        True
386       
387        In _stylesheets_ resource directory empty main.css stylesheet
388        resource added
389       
390        >>> 'main.css' in os.listdir('browser/stylesheets')
391        True
392        >>> cat('browser/stylesheets/main.css')
393        <BLANKLINE>
394       
395       
396        New resource directory was registered in configure.zcml
397       
398        >>> cat('browser/configure.zcml')
399        <configure
400        ...
401        <browser:resourceDirectory
402        name="quintagroup.theme.ploneexample.stylesheets"
403        directory="stylesheets"
404        layer=".interfaces.IThemeSpecific"
405        />
406        ...
407       
408       
409        And cssregistry.xml profile was added into profiles/default directory with
410        registered main.css stylesheet
411       
412        >>> 'cssregistry.xml' in os.listdir('profiles/default')
413        True
414        >>> cat('profiles/default/cssregistry.xml')
415        <?xml version="1.0"?>
416        <object name="portal_css">
417        <BLANKLINE>
418        <stylesheet title=""
419        id="++resource++quintagroup.theme.ploneexample.stylesheets/main.css"
420        media="screen" rel="stylesheet" rendering="inline"
421        cacheable="True" compression="safe" cookable="True"
422        enabled="1" expression=""/>
423        ...
424       
425       
426       
427        Adding CSS resource as dtml-file into skins layer
428        =================================================
429       
430        This template actually absolutely same to the previouse one, but layer_name
431        variable added to point in which skin layer css dtml-file should be added to.
432        And, of course, css resource added into pointing *skins/<layer_name>/<css_reseource_name>.dtml* file.
433       
434        This subtemplate has several benefits before registering css as resource layer:
435        - in dtml file you can use power of dtml language
436        - this resource can be overriden by customer if he needs that
437       
438        IMPORTANT:
439        For add css resource in registered skin layer - you should use this subtemplate
440        in conjunction with *skin_layer* one.
441       
442       
443        Use *css_dtml_skin* subtemplate.
444       
445        >>> paster("addcontent --no-interactive css_dtml_skin")
446        paster addcontent --no-interactive css_dtml_skin
447        Recursing into profiles
448        ...
449        Recursing into skins
450        ...
451       
452        This template adds main.css.dtml file into skins/skin_layer folder
453       
454        >>> 'main.css.dtml' in os.listdir('skins/skin_layer')
455        True
456       
457        The main.css.dtml file already prepared to use as dtml-document
458        >>> cat('skins/skin_layer/main.css.dtml')
459        /*
460        ...
461        /* <dtml-with base_properties> (do not remove this :) */
462        ...
463        /* </dtml-with> */
464        <BLANKLINE>
465       
466       
467        And cssregistry.xml profile was added into profiles/default directory with
468        registered main.css stylesheet
469       
470        >>> 'cssregistry.xml' in os.listdir('profiles/default')
471        True
472        >>> cat('profiles/default/cssregistry.xml')
473        <?xml version="1.0"?>
474        <object name="portal_css">
475        <BLANKLINE>
476        <stylesheet title=""
477        id="++resource++quintagroup.theme.ploneexample.stylesheets/main.css"
478        media="screen" rel="stylesheet" rendering="inline"
479        cacheable="True" compression="safe" cookable="True"
480        enabled="1" expression=""/>
481        ...
482       
483       
484        Adding JAVASCRIPT resource
485        --------------------------
486       
487        Use *js_resource* subtemplate.
488       
489        >>> paster('addcontent --no-interactive js_resource')
490        paster addcontent --no-interactive js_resource
491        Recursing into browser
492        ...
493        Recursing into profiles
494        ...
495       
496        This template adds (if does not exist yet) _scripts_ directory in _browser_
497        directory
498       
499        >>> 'scripts' in os.listdir('browser')
500        True
501       
502       
503        Empty foo.js javascript file was added to _scripts_ directory
504       
505        >>> 'foo.js' in os.listdir('browser/scripts')
506        True
507        >>> cat('browser/scripts/foo.js')
508        <BLANKLINE>
509       
510       
511        New resource directory was registered in configure.zcml, if has not been registered yet.
512       
513        >>> cat('browser/configure.zcml')
514        <configure
515        ...
516        <browser:resourceDirectory
517        name="quintagroup.theme.ploneexample.scripts"
518        directory="scripts"
519        layer=".interfaces.IThemeSpecific"
520        />
521        ...
522       
523       
524        cssregistry.xml profile was added into profiles/default directory (if does not exist yet),
525        and register new foo.js javascript resource.
526       
527        >>> 'jsregistry.xml' in os.listdir('profiles/default')
528        True
529        >>> cat('profiles/default/jsregistry.xml')
530        <?xml version="1.0"?>
531        <object name="portal_javascripts">
532        ...
533        <javascript
534        id="++resource++quintagroup.theme.ploneexample.scripts/foo.js"
535        inline="False" cacheable="True" compression="safe"
536        cookable="True" enabled="1"
537        expression=""
538        />
539        ...
540       
541       
542       
543        Test viewlets subtemplates
544        ==========================
545       
546        There are 2 types of viewlet subtemplates:
547        - viewlet_order
548        - viewlet_hidden
549       
550        The first one is used for adding new viewlets and setting
551        viewlets order for the ViewletManager, the second one only hides
552        viewlet in pointed ViewletManager.
553       
554        Ordered NEW viewlet
555        -------------------
556       
557        Use *viewlet_order* subtemplate
558       
559        >>> paster('addcontent --no-interactive viewlet_order')
560        paster addcontent --no-interactive viewlet_order
561        Recursing into browser
562        ...
563        Recursing into templates
564        ...
565        Recursing into profiles
566        ...
567       
568        This template adds (if not exist ;)) _viewlets.py_ module in browser directory.
569        With added Example ViewletBase class, which is bound to templates/example_viewlet.pt
570        template
571       
572        >>> 'viewlets.py' in os.listdir('browser')
573        True
574       
575        >>> cat('browser/viewlets.py')
576        from Products.CMFCore.utils import getToolByName
577        from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
578        from plone.app.layout.viewlets import common
579        ...
580        class Example(common.ViewletBase):
581        render = ViewPageTemplateFile('templates/example_viewlet.pt')
582        <BLANKLINE>
583       
584        Check template file in templates directory.
585       
586        >>> 'example_viewlet.pt' in os.listdir('browser/templates')
587        True
588        >>> cat('browser/templates/example_viewlet.pt')
589        <BLANKLINE>
590       
591        New viewlet is registered in configure.zcml
592       
593        >>> cat('browser/configure.zcml')
594        <configure
595        ...
596        <browser:viewlet
597        name="quintagroup.theme.ploneexample.example"
598        manager="plone.app.layout.viewlets.interfaces.IPortalHeader"
599        class=".viewlets.Example"
600        layer=".interfaces.IThemeSpecific"
601        permission="zope2.View"
602        />
603        ...
604       
605       
606        viewlets.xml profile is added to profiles/default directory with new viewlet
607        registration, ordered for specified viewlet manager.
608       
609        >>> 'viewlets.xml' in os.listdir('profiles/default')
610        True
611        >>> cat('profiles/default/viewlets.xml')
612        <?xml version="1.0"?>
613        <object>
614        ...
615        <order manager="plone.portalheader"
616        based-on="Plone Default"
617        skinname="My Theme Name" >
618        ...
619        <viewlet name="quintagroup.theme.ploneexample.example" insert-after="*" />
620        <BLANKLINE>
621        </order>
622        <BLANKLINE>
623        </object>
624       
625       
626       
627        Hide EXISTING viewlet
628        ---------------------
629       
630        For that case you can use *viewlet_hidden* subtemplate
631       
632        >>> paster('addcontent --no-interactive viewlet_hidden')
633        paster addcontent --no-interactive viewlet_hidden
634        Recursing into profiles
635        ...
636       
637        As we see from upper log - there is stuff for adding/updating profiles only.
638       
639       
640        There is viewlet.xml profile in profiles/default directory
641        which hides viewlet for specified viewlet manager
642       
643        >>> 'viewlets.xml' in os.listdir('profiles/default')
644        True
645        >>> cat('profiles/default/viewlets.xml')
646        <?xml version="1.0"?>
647        <object>
648        ...
649        <hidden manager="plone.portalheader" skinname="My Theme Name">
650        ...
651        <viewlet name="example" />
652        <BLANKLINE>
653        </hidden>
654        ...
655        </object>
656       
657       
658        Adding ZEXPs importing
659        ======================
660       
661        Imagine situation, when you develop a theme, which uses some
662        extra portal objects (documents with text for some potlets)
663        Then customer of your theme can edit these objects according
664        to his need.
665       
666        For this situation *import_zexps* subtemplate exists.
667       
668        *import_zexps* subtemplate extends your theme with
669        mechanism for importing list of zexp formated files
670        into portal root on theme instllation.
671       
672        >>> paster('addcontent --no-interactive import_zexps')
673        paster addcontent --no-interactive import_zexps
674        ...
675        Recursing into import
676        ...
677        Recursing into profiles
678        ...
679        Inserting from profiles.zcml_insert ...
680        ...
681        Inserting from setuphandlers.py_insert into ...
682        ...
683       
684        As we see from the upper log:
685        - 'import' directory was added into root of the theme
686        - profiles stuff was updated
687        - profiles.zcml file is updated
688        - some stuff into setuphandlers.py module was inserted
689       
690        1. There was empty 'import' directory added, where you
691        will put zexp objects for install into portal root.
692       
693        >>> ls('import')
694        CONTENT.txt
695       
696       
697        2. import_steps.xml was added in profiles/import_zexps directory,
698        which contains additional *quintagroup.theme.ploneexample.import_zexps* step.
699       
700        >>> 'import_zexps' in os.listdir('profiles')
701        True
702        >>> 'import_steps.xml' in os.listdir('profiles/import_zexps')
703        True
704       
705        >>> cat('profiles/import_zexps/import_steps.xml')
706        <?xml version="1.0"?>
707        ...
708        <import-step id="quintagroup.theme.ploneexample.import_zexps"
709        version="..."
710        handler="quintagroup.theme.ploneexample.setuphandlers.importZEXPs"
711        title="My Theme Name: Import zexps objects">
712        Import zexp objects into portal on My Theme Name theme installation
713        </import-step>
714        <BLANKLINE>
715        ...
716       
717        3. profiles.zcml configuration updated with new genericsetup profile for zexps
718        importing.
719       
720        >>> cat('profiles.zcml')
721        <configure
722        ...
723        <genericsetup:registerProfile
724        name="import_zexps"
725        title="My Theme Name: Import ZEXPs"
726        directory="profiles/import_zexps"
727        description='Extension profile for importing objects of the "My Theme Name" Plone theme.'
728        provides="Products.GenericSetup.interfaces.EXTENSION"
729        />
730        <BLANKLINE>
731        ...
732       
733        4. Check setuphandlers.py module - there must be importZEXPs function defined
734       
735        >>> cat('setuphandlers.py')
736        def setupVarious(context):
737        ...
738        def importZEXPs(context):
739        ...
740       
741        Then simply prepare zexp objects and copy them to *import* directory.
742       
743       
744        RELEASE NOTES !
745        ===============
746       
747        Before releasing theme - I suggest to clean up setup.py script:
748       
749        - remove *theme_vars* argument (its value is useful only for
750        theme development)
751       
752        - remove *entry_points* argument (same reason).
753        It's useless in plone for now.
754       
755        - And remove *paster_plugins* argument too (it has sence
756        in conjunction with entry_points during theme developing)
757       
758        Steps mentioned above prevent possible problems with
759        theme distribution/deployment.
760       
761        Changelog
762        =========
763       
764        0.2.2 (unreleased)
765        ------------------
766       
767        - Updated import_zexps subtemplate - move this step into
768        separate genericsetup profile
769        [mylan]
770        - Updated tests for changed import_zexps subtemplate
771        [mylan]
772       
773        0.2 (unreleased)
774        ----------------
775       
776        - Added new css_dtml_skin subtemplate
777        [mylan]
778        - Added tests for css_dtml_skin subtemplate
779        [mylan]
780       
781        0.14 (unreleased)
782        -----------------
783       
784        - Refactoring theme vars storage-now storing in separate
785        theme_vars.cfg file, without distutils writers [mylan]
786        - Cleanup code [mylan]
787       
788       
789        0.11 (2009-04-13)
790        -----------------
791       
792        - Removed setup.cfg
793        [mylan]
794       
795       
796        0.10 (2009-04-13)
797        -----------------
798       
799        - Updated README
800        [olha]
801       
802       
803        0.9 (2009-04-11)
804        ----------------
805       
806        - Changed package name/namespace to
807        quintagroup.themetemplate.
808        [mylan]
809       
810       
811        0.8 (2009-04-10)
812        ----------------
813       
814        * Update tests, readme
815        [mylan]
816       
817        * Update viewlet-order subtemplate
818        [mylan]
819       
820        * Fix uninstall bug
821        [mylan]
822       
823       
824        Version 0.7
825        -----------
826       
827        * Add uninstall profile to fix skins tool after theme is uninstalled
828        [piv]
829       
830       
831        Version 0.1
832        -----------
833       
834        * Initial import Theme template with nested namespace.
835        Support ZopeSkel' "addcommad" local command for extend
836        Theme template, support extending with portlet, view local
837        templates.
838        [mylan]
839       
840Keywords: ZopeSkel theme template plone3 Quintagroup
841Platform: UNKNOWN
842Classifier: Programming Language :: Python
843Classifier: Topic :: Software Development :: Libraries :: Python Modules
Note: See TracBrowser for help on using the repository browser.