source: products/qtheme.template/trunk/qthemetemplate/README.txt @ 458

Last change on this file since 458 was 369, checked in by chervol, 18 years ago

added geolocation edit tab for content types

  • Property svn:eol-style set to native
File size: 16.7 KB
Line 
1======================
2qplone3 theme template
3======================
4
5Overview
6-------------------------
7
8This theme template allow you to create plone3 theme python package
9with nested namespace. Initial package is theme package skeleton.
10Than this package could be extended with:
11 - skin-layer(s),
12 - portlet(s),
13 - viewlet(s),
14 - css, js resource(s).
15
16Creation package performed with `paster create` PasteScript command.
17Extending theme with other resources doing with `paster addcontent`
18local ZopeSkel command (extended in this product).
19
20Let's create theme package
21---------------------------
22
23For create such theme use `paster create` command::
24
25    >>> paster('create -t qplone3_theme plone.example --no-interactive --overwrite')
26    paster create -t qplone3_theme plone.example --no-interactive
27    ...
28
29Let's check the content of created plone.example package::
30
31    >>> package_dir = 'plone.example'
32    >>> ls(package_dir)
33    MANIFEST.in
34    README.txt
35    ...
36    plone.example-configure.zcml
37    ...
38    quintagroup
39    ...
40
41So you have python package with *quintagroup* upper level namespace.
42Also there are *README.txt* with information about your theme,
43*plone.example-configure.zcml* - zcml file for adding into package-includes
44directory
45
46
47With qplone3_theme template - creates theme with nested namespace.
48By default - theme placed in
49
50    quintagroup.theme.<package name without dot> namespace
51
52in our case - quintagroup.theme.ploneexample
53
54
55So check namespaces::
56    >>> 'quintagroup' in os.listdir(package_dir)
57    True
58
59    >>> cd(package_dir)
60    >>> 'theme' in os.listdir('quintagroup')
61    True
62
63    >>> path = os.path.join('quintagroup','theme')
64    >>> 'ploneexample' in os.listdir(path)
65    True
66   
67
68
69Package holds 3 subdirectory (browser, profiles, skins) and
70initialization files::
71    >>> cd('quintagroup/theme')
72    >>> ls('ploneexample')
73    __init__.py
74    browser
75    configure.zcml
76    portlets
77    profiles
78    profiles.zcml
79    setuphandlers.py
80    skins
81    skins.zcml
82    tests.py
83    version.txt
84
85
86Review browser directory
87------------------------
88
89In browser directory created 'templates' resource directory
90for views, viewlets, ...; interfaces.py module with IThemeSpecific
91marker interface. In configure.zcml register theme marker interface.
92
93
94    >>> cd('ploneexample')
95    >>> ls('browser')
96    __init__.py
97    configure.zcml
98    interfaces.py
99    templates
100
101    >>> cat('browser/interfaces.py')
102    from plone.theme.interfaces import IDefaultPloneLayer
103    <BLANKLINE>
104    class IThemeSpecific(IDefaultPloneLayer):
105    ...
106
107    >>> cat('browser/configure.zcml')
108    <configure
109    ...
110        <interface
111            interface=".interfaces.IThemeSpecific"
112            type="zope.publisher.interfaces.browser.IBrowserSkinType"
113            name="Custom Theme"
114            />
115    ...
116
117As we saw by default name of the theme is 'Custom Theme', but on theme
118creation you can point own name. Check it ...
119
120First create configuration file with other skin name
121    >>> conf_data = """
122    ... [pastescript]
123    ... skinname=My Theme Name
124    ... """
125    >>> file('theme_config.conf','w').write(conf_data)
126
127Create same theme with own skin name and check this
128    >>> paster('create -t qplone3_theme plone.example --no-interactive --overwrite --config=theme_config.conf')
129    paster create ...
130    >>> cd(package_dir)
131    >>> cat('quintagroup/theme/ploneexample/browser/configure.zcml')
132    <configure
133    ...
134        <interface
135            interface=".interfaces.IThemeSpecific"
136            type="zope.publisher.interfaces.browser.IBrowserSkinType"
137            name="My Theme Name"
138            />
139    ...
140
141
142Now lets vew to skins directory of generated theme - it's contain only
143README.txt file and no skin layers yet. This job for localcommand ;)
144But check am I right ...
145    >>> cd('quintagroup/theme/ploneexample')
146    >>> ls('skins')
147    README.txt
148
149
150Now check profiles directory.
151--------------------------------
152There is 'default' profile in it
153    >>> ls('profiles')
154    default
155
156In default profile there is:
157 - import_steps.xml - for any reason.
158 - skins.xml - register skins directory
159
160    >>> cd('profiles/default')
161    >>> ls('.')
162    import_steps.xml
163    ...
164    skins.xml
165
166Skins profile make your theme default on installation
167and base layers list on 'Plone Default' theme, without
168any new layers.
169    >>> cat('skins.xml')
170    <?xml version="1.0"?>
171    <object name="portal_skins" ...
172            default_skin="My Theme Name">
173    ...
174    <skin-path name="My Theme Name" based-on="Plone Default">
175      <!-- -*- extra layer stuff goes here -*- -->
176    <BLANKLINE>
177    </skin-path>
178    ...
179
180import_steps.xml - connect setupVarious function from
181setuphandlers module for additional installation steps.
182    >>> cat('import_steps.xml')
183    <?xml version="1.0"?>
184    ...
185    <import-step id="quintagroup.theme.ploneexample.various"
186    ...
187                 handler="quintagroup.theme.ploneexample.setuphandlers.setupVarious"
188    ...
189    </import-step>
190    ...
191
192View for setuphandlers.py module
193    >>> cd('../..')
194    >>> cat('setuphandlers.py')
195        def setupVarious(context):
196    ...
197
198
199
200=========================
201Test localcommnands
202=========================
203
204One of the best features, which bring us ZopeSkel package - is localcommand.
205
206Now review localcommands = possibility to extend your theme with additional
207staff - skin layers, views, viewlets, portlets, css and javascript resources
208
209
210qplone3_theme generated package theme support ZopeSkel local command 'addcontent'.
211
212    >>> paster('addcontent -a')
213    paster addcontent -a
214      ...
215        css_resource:    A Plone 3 CSS resource template
216      ...
217        import_zexps:    A template for importing zexp-objects into portal on installation
218        js_resource:     A Plone 3 JS resource template
219      N portlet:         A Plone 3 portlet
220      ...
221        skin_layer:      A Plone 3 Skin Layer
222      ...
223      N view:            A browser view skeleton
224        viewlet_hidden:  A Plone 3 Hidden Viewlet template
225        viewlet_order:   A Plone 3 Order Viewlet template
226      ...
227
228
229So you can extend your theme with following subtemplates:
230  - portlet
231  - skin layer
232  - css resource
233  - js resource
234  - viewlet (order/hidden)
235  - view
236'N' character tell us that this subtemplates are registered for other (archetype)
237template, but no metter - it can correctly extend our theme.
238
239Skin layer
240------------
241Review what changes when adding skin_layer to the theme
242
243    >>> paster('addcontent --no-interactive skin_layer')
244    paster addcontent --no-interactive skin_layer
245    Recursing into profiles
246    ...
247
248Now check skins directory - new 'skin_layer' (default name) directory must be added,
249which contain only CONTENT.txt file
250    >>> 'skin_layer' in os.listdir('skins')
251    True
252    >>> ls('skins/skin_layer')
253    CONTENT.txt
254
255There is also skins.xml profile must be updated:
256    >>> cat('profiles/default/skins.xml')
257    <?xml version="1.0"?>
258    <object name="portal_skins" allow_any="False" cookie_persistence="False"
259       default_skin="My Theme Name">
260    ...
261     <object name="skin_layer"
262        meta_type="Filesystem Directory View"
263        directory="quintagroup.theme.ploneexample:skins/skin_layer"/>
264    <BLANKLINE>
265     <skin-path name="My Theme Name" based-on="Plone Default">
266    ...
267      <layer name="skin_layer"
268         insert-after="custom"/>
269    <BLANKLINE>
270     </skin-path>
271    ...
272
273We see, that:
274  - skin_layer directory registered as Filesystem Directory View
275  - skin_layer Filesystem Directory View added to our theme layers list
276
277
278
279
280
281Test of portlet adding
282------------------------------
283
284Review portlets directory before adding new portlet
285
286    >>> ls('portlets')
287    __init__.py
288    configure.zcml
289
290Add portlet
291    >>> paster('addcontent --no-interactive portlet')
292    paster addcontent --no-interactive portlet
293    Recursing into portlets
294    ...
295
296In configure.zcml included registries from portlets:
297    >>> cat('configure.zcml')
298    <configure
299    ...
300    <include package=".portlets" />
301    ...
302
303Check changes in portlets directory
304    >>> ls('portlets')
305    __init__.py
306    configure.zcml
307    exampleportlet.pt
308    exampleportlet.py
309
310In portlets/configure.zcml - should register new portlet
311    >>> cat('portlets/configure.zcml')
312    <configure
313    ...
314         <plone:portlet
315             name="quintagroup.theme.ploneexample.portlets.ExamplePortlet"
316             interface=".exampleportlet.IExamplePortlet"
317             assignment=".exampleportlet.Assignment"
318             view_permission="zope2.View"
319             edit_permission="cmf.ManagePortal"
320             renderer=".exampleportlet.Renderer"
321             addview=".exampleportlet.AddForm"
322             editview=".exampleportlet.EditForm"
323             />
324    ...
325
326And now review configure.zcml profile
327    >>> cat('profiles/default/portlets.xml')
328    <?xml version="1.0"?>
329    ...
330       <portlet
331         addview="quintagroup.theme.ploneexample.portlets.ExamplePortlet"
332         title="Example portlet"
333         description=""
334       />
335    ...
336
337So new portlet registered.
338
339
340
341Test of css_resource
342------------------------------
343
344    >>> paster("addcontent --no-interactive css_resource")
345    paster addcontent --no-interactive css_resource
346    Recursing into browser
347    ...
348    Recursing into profiles
349    ...
350
351From upper log - we see that there is adding/updating some staff
352in browser and profiles directories
353
354    >>> ls('browser')
355    __init__.py
356    ...
357    stylesheets
358    ...
359
360There is added styles resource directory with empty main.css stylesheet
361resource
362
363    >>> ls('browser/stylesheets')
364    README.txt
365    main.css
366    >>> cat('browser/stylesheets/main.css')
367    <BLANKLINE>
368
369By default it is added empty main.css file
370
371
372But this new resource directory also should be registered in configure.zcml
373
374    >>> cat('browser/configure.zcml')
375    <configure
376    ...
377        <browser:resourceDirectory
378            name="quintagroup.theme.ploneexample.stylesheets"
379            directory="stylesheets"
380            layer=".interfaces.IThemeSpecific"
381            />
382    ...
383   
384
385Now look into profiles/default directory
386
387    >>> ls('profiles/default')
388    cssregistry.xml
389    ...
390    >>> cat('profiles/default/cssregistry.xml')
391    <?xml version="1.0"?>
392    <object name="portal_css">
393    <BLANKLINE>
394     <stylesheet title=""
395        id="++resource++quintagroup.theme.ploneexample.stylesheets/main.css"
396        media="screen" rel="stylesheet" rendering="inline"
397        cacheable="True" compression="safe" cookable="True"
398        enabled="1" expression=""/>
399    ...
400
401We see, that in cssregistry.xml, registries new main.css stylesheet resource.
402
403
404
405Test of js_resource
406------------------------------
407
408    >>> paster('addcontent --no-interactive js_resource')
409    paster addcontent --no-interactive js_resource
410    Recursing into browser
411    ...
412    Recursing into profiles
413    ...
414
415From upper log - we see that there is adding/updating some staff
416in browser and profiles directories
417
418    >>> ls('browser')
419    __init__.py
420    ...
421    scripts
422    ...
423
424There is added scripts resource directory with empty foo.js javascript
425
426    >>> ls('browser/scripts')
427    README.txt
428    foo.js
429    >>> cat('browser/scripts/foo.js')
430    <BLANKLINE>
431
432By default it is added empty foo.js file
433
434
435But this new resource directory also should be registered in configure.zcml
436
437    >>> cat('browser/configure.zcml')
438    <configure
439    ...
440        <browser:resourceDirectory
441            name="quintagroup.theme.ploneexample.scripts"
442            directory="scripts"
443            layer=".interfaces.IThemeSpecific"
444            />
445    ...
446   
447
448Now look into profiles/default directory
449
450    >>> ls('profiles/default')
451    cssregistry.xml
452    ...
453    jsregistry.xml
454    ...
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
467We see, that in jsregistry.xml, registries new foo.js javascript resource.
468
469
470Test viewlets subtemplates:
471==============================
472
473There is 2 types of viewlet subtemplate:
474 - viewlet_order
475 - viewlet_hidden
476
477Of the two subtemplates, the former is for adding new viewlet and
478set order for it in ViewletManager, other one only hide viewlet in
479pointed ViewletManager
480
481
482Ordered NEW viewlet
483------------------------------
484For that case you can use viewlet_order subtemplate
485
486    >>> paster('addcontent --no-interactive viewlet_order')
487    paster addcontent --no-interactive viewlet_order
488    Recursing into browser
489    ...
490    Recursing into templates
491    ...
492    Recursing into profiles
493    ...
494
495From upper log - we see that there is adding/updating some staff
496in browser and profiles directories
497
498    >>> ls('browser')
499    __init__.py
500    ...
501    viewlets.py
502
503Added viewlets.py python module
504
505    >>> cat('browser/viewlets.py')
506    from Products.CMFCore.utils import getToolByName
507    from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
508    from plone.app.layout.viewlets import common
509    ...
510    class Example(common.PersonalBarViewlet):
511        render = ViewPageTemplateFile('templates/example_viewlet.pt')
512    <BLANKLINE>
513
514We see that added viewlet class with example_viewlet.pt template.
515Check if exist this template in templates directory
516
517    >>> ls('browser/templates')
518    README.txt
519    example_viewlet.pt
520
521There is also empty example_viewlet.pt template.
522
523    >>> cat('browser/templates/example_viewlet.pt')
524    <BLANKLINE>
525
526This new viewlet must be registered in configure.zcml
527
528    >>> cat('browser/configure.zcml')
529    <configure
530    ...
531       <browser:viewlet
532            name="quintagroup.theme.ploneexample.example"
533            manager="plone.app.layout.viewlets.interfaces.IPortalHeader"
534            class=".viewlets.Example"
535            permission="zope2.View"
536            />
537    ...
538   
539
540Now look into profiles/default directory
541
542    >>> ls('profiles/default')
543    cssregistry.xml
544    ...
545    viewlets.xml
546
547    >>> cat('profiles/default/viewlets.xml')
548    <?xml version="1.0"?>
549    <object>
550    ...
551     <order manager="plone.portalheader"
552             based-on="Plone Default"
553             skinname="My Theme Name" >
554    ...
555        <viewlet name="quintagroup.theme.ploneexample.example" insert-after="*" />
556    <BLANKLINE>
557      </order>
558    <BLANKLINE>
559    </object>
560
561We see, that in viewlets.xml, ordered new viewlet for plone.portalheader viewlet manager.
562
563
564Hide EXISTANT viewlet
565------------------------------
566For that case you can use viewlet_hidden subtemplate
567
568    >>> paster('addcontent --no-interactive viewlet_hidden')
569    paster addcontent --no-interactive viewlet_hidden
570    Recursing into profiles
571    ...
572
573As we see from upper log - there is adding/updating only profiles staff.
574   
575
576So look into profiles/default directory
577
578    >>> ls('profiles/default')
579    cssregistry.xml
580    ...
581    viewlets.xml
582
583    >>> cat('profiles/default/viewlets.xml')
584    <?xml version="1.0"?>
585    <object>
586    ...
587      <hidden manager="plone.portalheader" skinname="My Theme Name">
588    ...
589        <viewlet name="example" />
590    <BLANKLINE>
591      </hidden>
592    ...
593    </object>
594
595We see, that in viewlets.xml, hide example viewlet for plone.portalheader viewlet manager.
596
597
598Import ZEXPs
599------------------------------
600This subtemplate allow you to add to your theme ZEXP objects, which will be exporting
601into portal root on theme installation
602
603    >>> paster('addcontent --no-interactive import_zexps')
604    paster addcontent --no-interactive import_zexps
605    ...
606    Recursing into import
607    ...
608    Recursing into profiles
609    ...
610    Inserting from setuphandlers.py_insert into ...
611    ...
612
613As we see from upper log - there is:
614   - adding 'import' directory into theme directory;
615   - update profiles staff.
616   - insert some staff into setuphandlers.py module
617   
6181. Look into 'import' directory:
619    >>> ls('import')
620    CONTENT.txt
621
622It's empty - here you can put any zexp objects for install into portal root.
623
624
6252. Look into profiles/default directory
626
627    >>> ls('profiles/default')
628    cssregistry.xml
629    import_steps.xml
630    ...
631
632
633    >>> cat('profiles/default/import_steps.xml')
634    <?xml version="1.0"?>
635    <import-steps>
636    ...
637      <import-step id="quintagroup.theme.ploneexample.import_zexps"
638                   version="20081104-02"
639                   handler="quintagroup.theme.ploneexample.setuphandlers.importZEXPs"
640                   title="My Theme Name: Import zexps objects">
641        <dependency step="skins" />
642        Import zexp objects into portal on My Theme Name theme installation
643      </import-step>
644    <BLANKLINE>
645    </import-steps>
646
647We see, that in import_steps.xml, added 'Import zexp' step.
648
6493. Check setuphandlers.py module - there is must be importZEXPs function defined
650
651    >>> cat('setuphandlers.py')
652    def setupVarious(context):
653    ...
654    def importZEXPs(context):
655    ...
656
657So everything fine with setuphandlers too ;)
658
659
Note: See TracBrowser for help on using the repository browser.