| 1 |
|
|---|
| 2 |
=========== |
|---|
| 3 |
NEGOTIATION |
|---|
| 4 |
=========== |
|---|
| 5 |
|
|---|
| 6 |
The negotiation process takes place between the client (browser) and the server |
|---|
| 7 |
to determine the parameters required for delivering a rendered page to the |
|---|
| 8 |
user. |
|---|
| 9 |
|
|---|
| 10 |
The negotiation strategy is fixed and is deterministic, which means that under |
|---|
| 11 |
the same premises the outcome of the negotiation will always be the same. |
|---|
| 12 |
|
|---|
| 13 |
In particular, the renderer needs to know: |
|---|
| 14 |
|
|---|
| 15 |
- what *theme* to use |
|---|
| 16 |
|
|---|
| 17 |
- what *page* to render |
|---|
| 18 |
|
|---|
| 19 |
- which rendering *engine* to use |
|---|
| 20 |
|
|---|
| 21 |
- from which *perspective* to render the page |
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
Hence the entire negotiation process is split into 4 phases: |
|---|
| 25 |
|
|---|
| 26 |
1) the 'theme negotiation' phase |
|---|
| 27 |
|
|---|
| 28 |
2) the 'page negotiation' phase |
|---|
| 29 |
|
|---|
| 30 |
3) the 'engine negotiation' phase |
|---|
| 31 |
|
|---|
| 32 |
4) the 'perspective negotiation' phase |
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
By design, the phases are independent of one another. To each phase |
|---|
| 36 |
corresponds a *negotiation chain*. |
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
Negotiation chains |
|---|
| 40 |
------------------ |
|---|
| 41 |
|
|---|
| 42 |
A negotiation *chain* is a series of steps under which the client requests an |
|---|
| 43 |
object from the server using various schemes (passing a URL parameter, |
|---|
| 44 |
looking for a cookie variable, looking for a session or request variable, ...). |
|---|
| 45 |
|
|---|
| 46 |
For each step, the server either responds with the requested object if it |
|---|
| 47 |
is available or with nothing. |
|---|
| 48 |
|
|---|
| 49 |
The first available object will be the result of the negotiation for that |
|---|
| 50 |
particular chain. |
|---|
| 51 |
|
|---|
| 52 |
|
|---|
| 53 |
Negotiation strategy |
|---|
| 54 |
-------------------- |
|---|
| 55 |
|
|---|
| 56 |
A negotiation *strategy* is a set of negotiation chains. |
|---|
| 57 |
|
|---|
| 58 |
Each *theme management folder* can have its own negotiation strategy. |
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
Test setup: |
|---|
| 62 |
|
|---|
| 63 |
>>> from zope.publisher.browser import TestRequest |
|---|
| 64 |
>>> request = TestRequest() |
|---|
| 65 |
|
|---|
| 66 |
>>> root = getRootFolder() |
|---|
| 67 |
>>> from cpsskins.tests.setup import addThemeSkeleton, addThemeManager |
|---|
| 68 |
>>> manager = addThemeManager(root) |
|---|
| 69 |
>>> theme1 = addThemeSkeleton(manager, u'Theme 1') |
|---|
| 70 |
>>> theme2 = addThemeSkeleton(manager, u'Theme 2') |
|---|
| 71 |
>>> theme3 = addThemeSkeleton(manager, u'Theme 3') |
|---|
| 72 |
|
|---|
| 73 |
>>> from zope.app import zapi |
|---|
| 74 |
>>> from cpsskins.browser.negotiation.interfaces import INegotiation |
|---|
| 75 |
>>> negotiation = zapi.getMultiAdapter((root, request), INegotiation, |
|---|
| 76 |
... 'negotiation') |
|---|
| 77 |
|
|---|
| 78 |
Themes |
|---|
| 79 |
------ |
|---|
| 80 |
|
|---|
| 81 |
To obtain the theme as a result of the negotiation the 'getTheme' method is |
|---|
| 82 |
used. |
|---|
| 83 |
|
|---|
| 84 |
If nothing is specified, the default theme is returned: |
|---|
| 85 |
|
|---|
| 86 |
>>> theme = negotiation.getTheme() |
|---|
| 87 |
>>> theme.name |
|---|
| 88 |
'Theme' |
|---|
| 89 |
|
|---|
| 90 |
>>> manager.isDefault(theme) |
|---|
| 91 |
True |
|---|
| 92 |
|
|---|
| 93 |
|
|---|
| 94 |
The theme's name can be specified in the URL, by writing ...?theme=Theme-2 |
|---|
| 95 |
|
|---|
| 96 |
>>> request.form[u'theme'] = u'Theme-2' |
|---|
| 97 |
>>> theme = negotiation.getTheme() |
|---|
| 98 |
>>> theme.name |
|---|
| 99 |
u'Theme-2' |
|---|
| 100 |
|
|---|
| 101 |
>>> del request.form[u'theme'] |
|---|
| 102 |
|
|---|
| 103 |
|
|---|
| 104 |
The theme's name can also be specified in a cookie: |
|---|
| 105 |
|
|---|
| 106 |
>>> request.response.setCookie('cpsskins_theme', u'Theme-3') |
|---|
| 107 |
>>> theme = negotiation.getTheme() |
|---|
| 108 |
|
|---|
| 109 |
TODO |
|---|
| 110 |
|
|---|
| 111 |
>>> request.response.expireCookie('cpsskins_theme') |
|---|
| 112 |
|
|---|
| 113 |
|
|---|
| 114 |
|
|---|