This repository has been archived by the owner on Mar 22, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
README.txt
181 lines (124 loc) · 4.78 KB
/
README.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
Relations
=========
The relation support is there to answer the question by which objects an object
is referenced by, i.e. to resolve back references. The backreferences are
extrinsic, the referenced object doesn't know about them. The actual
references are usually intrinsic, i.e. the referencing object knows it
references the other object.
Low level support
+++++++++++++++++
The `IRelations`-Utility handles all the magic of resolving
references[#functional]_:
>>> import zeit.cms.relation.interfaces
>>> relations = zope.component.getUtility(
... zeit.cms.relation.interfaces.IRelations)
>>> relations
<zeit.cms.relation.relation.Relations object at 0x...>
[#interface]_
Get a testcontent[#createtestcontent]_:
>>> a = repository['a']
The content doesn't have any relateds currently, nor is it related anywhere:
>>> sorted(relations.get_relations(a))
[]
Relate b and c to a via IRelatedContent
>>> from zeit.cms.checkout.helper import checked_out
>>> import zeit.cms.related.interfaces
>>> with checked_out(repository['a']) as co:
... related = zeit.cms.related.interfaces.IRelatedContent(co)
... related.related = (repository['b'], repository['c'])
We could ask for b's relations:
>>> res = sorted(relations.get_relations(repository['b']))
>>> len(res)
1
>>> res
[<zeit.cms.testcontenttype.testcontenttype.ExampleContentType...>]
>>> res[0].uniqueId
u'http://xml.zeit.de/a'
The same accounts for c:
>>> res = sorted(relations.get_relations(repository['c']))
>>> res[0].uniqueId
u'http://xml.zeit.de/a'
Note that `get_relations` is not transitive. So if d references a, asking for
c's references will still just yield a:
>>> d = repository['d']
>>> related = zeit.cms.related.interfaces.IRelatedContent(d)
>>> related.related = (repository['a'],)
>>> repository['d'] = d
>>> res = sorted(relations.get_relations(repository['c']))
>>> len(res)
1
>>> res[0].uniqueId
u'http://xml.zeit.de/a'
[#none-unique-id-yields-nothing]_
When we remove a from the repository, but do not update the index, c will no
longer reference a anyway (because we cannot find a anymore)
>>> del repository['a']
>>> sorted(relations.get_relations(repository['c']))
[]
.. [#none-unique-id-yields-nothing] When an object with a unique id of "None"
is queried, nothing will be returned:
>>> no_uid = ExampleContentType()
>>> sorted(relations.get_relations(no_uid))
[]
Event handlers
++++++++++++++
The event handlers listen on various events from `zeit.cms` and keep the
relations uptodate.
Checkin
-------
Objects are indexed before checkin. We will check a out and back in and verify
it is indexed[#cleancatalog]_. Let a relate checkout and relate c:
>>> import zeit.cms.checkout.interfaces
>>> checked_out = zeit.cms.checkout.interfaces.ICheckoutManager(
... repository['d']).checkout()
>>> related = zeit.cms.related.interfaces.IRelatedContent(checked_out)
>>> related.related = (repository['c'],)
Nothing has been indexed so far:
>>> sorted(relations.get_relations(repository['c']))
[]
Check in:
>>> b = zeit.cms.checkout.interfaces.ICheckinManager(checked_out).checkin()
The relation can be queried now:
>>> res = sorted(relations.get_relations(repository['c']))
>>> len(res)
1
>>> res[0].uniqueId
u'http://xml.zeit.de/d'
Adding
------
Objects are index when they are first added to the repository. (Most content
types are checked out immediately after create, but that's rather accidental,
so we probably shouldn't rely on it here).
>>> new = ExampleContentType()
>>> related = zeit.cms.related.interfaces.IRelatedContent(new)
>>> related.related = (repository['e'],)
>>> repository['new'] = new
>>> res = sorted(relations.get_relations(repository['e']))
>>> len(res)
1
>>> res[0].uniqueId
u'http://xml.zeit.de/new'
.. [#functional] Setup functional test and get some common utilities
>>> import zeit.cms.testing
>>> zeit.cms.testing.set_site()
>>> principal = zeit.cms.testing.create_interaction()
>>> import zope.component
>>> import zeit.cms.repository.interfaces
>>> repository = zope.component.getUtility(
... zeit.cms.repository.interfaces.IRepository)
.. [#interface] Verify the interface:
>>> import zope.interface.verify
>>> zope.interface.verify.verifyObject(
... zeit.cms.relation.interfaces.IRelations, relations)
True
.. [#createtestcontent] Create some testcontent:
>>> from zeit.cms.testcontenttype.testcontenttype import ExampleContentType
>>> repository['a'] = ExampleContentType()
>>> repository['b'] = ExampleContentType()
>>> repository['c'] = ExampleContentType()
>>> repository['d'] = ExampleContentType()
>>> repository['e'] = ExampleContentType()
.. [#cleancatalog] Clean the catalog:
>>> for name in ('a', 'b', 'c', 'd'):
... relations._catalog.unindex_doc(
... 'http://xml.zeit.de/%s' % name)