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

Last change on this file since 2569 was 2569, checked in by mylan, 14 years ago

218: added new subetmplates marker into core init module of the generated theme

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