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

Last change on this file since 1005 was 1005, checked in by mylan, 15 years ago

Import package: Copied http://svn.quintagroup.com/products/qtheme.template/trunk@2041 + modifications concerning changed package name, namespace

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