Skip to content

Commit 7bc8cc7

Browse files
committed
Tidy references.md
1 parent f847ec7 commit 7bc8cc7

File tree

1 file changed

+61
-94
lines changed

1 file changed

+61
-94
lines changed
Lines changed: 61 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,75 @@
11
---
22
myst:
33
html_meta:
4-
"description": ""
5-
"property=og:description": ""
6-
"property=og:title": ""
7-
"keywords": ""
4+
"description": "Plone content type references between content objects"
5+
"property=og:description": "Plone content type references between content objects"
6+
"property=og:title": "Plone content type references between content objects"
7+
"keywords": "Plone, content types, references, content objects"
88
---
99

1010
# References
1111

12-
**How to work with references between content objects**
12+
This chapter describes how to work with references between content objects.
1313

14-
References are a way to maintain links between content that remain valid
15-
even if one or both of the linked items are moved or renamed.
14+
References are a way to maintain links between content that remain valid, even if one or both of the linked items are moved or renamed.
1615

17-
Under the hood, Dexterity’s reference system uses [five.intid], a Zope
18-
2 integration layer for [zope.intid], to give each content item a unique
19-
integer id. These are the basis for relationships maintained with the
20-
[zc.relationship] package, which in turn is accessed via an API
21-
provided by [z3c.relationfield], integrated into Zope 2 with
22-
[plone.app.relationfield]. For most purposes, you need only to worry
23-
about the `z3c.relationfield` API, which provides methods for finding
24-
source and target objects for references and searching the relationship
25-
catalog.
16+
Under the hood, Dexterity's reference system uses [`five.intid`](https://pypi.org/project/five.intid/), a Zope 2 integration layer for [`zope.intid`](https://pypi.org/project/zope.intid/), to give each content item a unique integer ID.
17+
These are the bases for relationships maintained with the [`zc.relationship`](https://pypi.org/project/zc.relationship/) package, which in turn is accessed via an API provided by [`z3c.relationfield`](https://pypi.org/project/z3c.relationfield/), integrated into Zope 2 with [`plone.app.relationfield`](https://pypi.org/project/plone.app.relationfield/).
18+
For most purposes, you need only to worry about the `z3c.relationfield` API, which provides methods for finding source and target objects for references and searching the relationship catalog.
2619

27-
References are most commonly used in form fields with a selection or
28-
content browser widget. Dexterity comes with a standard widget in
29-
[plone.formwidget.contenttree] configured for the `RelationList` and
30-
`RelationChoice` fields from `z3c.relationfield`.
20+
References are most commonly used in form fields with a selection or content browser widget.
21+
Dexterity comes with a standard widget in [`plone.formwidget.contenttree`](https://pypi.org/project/plone.formwidget.contenttree/) configured for the `RelationList` and `RelationChoice` fields from `z3c.relationfield`.
3122

32-
To illustrate the use of references, we will allow the user to create a
33-
link between a `Session` and its `Presenter`. Since Dexterity already
34-
ships with and installs `plone.formwidget.contenttree` and
35-
`z3c.relationfield`, we do not need to add any further setup code, and
36-
we can use the field directly in `session.py`:
37-
38-
```
39-
...
23+
To illustrate the use of references, we will allow the user to create a link between a `Session` and its `Presenter`.
24+
Since Dexterity already ships with and installs `plone.formwidget.contenttree` and `z3c.relationfield`, we do not need to add any further setup code, and we can use the field directly in {file}`session.py`:
4025

26+
```python
4127
from z3c.relationfield.schema import RelationChoice
4228
from plone.formwidget.contenttree import ObjPathSourceBinder
43-
...
4429

4530
from example.conference.presenter import IPresenter
4631

4732
class ISession(form.Schema):
4833
"""A conference session. Sessions are managed inside Programs.
4934
"""
50-
...
5135

5236
presenter = RelationChoice(
53-
title=_(u"Presenter"),
37+
title=_("Presenter"),
5438
source=ObjPathSourceBinder(object_provides=IPresenter.__identifier__),
5539
required=False,
5640
)
5741
```
5842

59-
:::{Note}
60-
Remeber that [plone.app.relationfield] needs to be installed to use any
61-
RelationChoice or RelationList field.
62-
:::
43+
```{note}
44+
Remeber that `plone.app.relationfield` needs to be installed to use any `RelationChoice` or `RelationList` field.
45+
```
6346

64-
To allow multiple items to be selected, we could have used a
65-
`RelationList` like:
47+
To allow multiple items to be selected, we could have used a `RelationList` as shown:
6648

67-
```
49+
```python
6850
relatedItems = RelationList(
69-
title=u"Related Items",
51+
title="Related Items",
7052
default=[],
71-
value_type=RelationChoice(title=_(u"Related"),
53+
value_type=RelationChoice(title=_("Related"),
7254
source=ObjPathSourceBinder()),
7355
required=False,
7456
)
7557
```
7658

77-
The `ObjPathSourceBinder` class is an `IContextSourceBinder` that returns
78-
a vocabulary with content objects as values, object titles as term
79-
titles and object paths as tokens.
59+
The `ObjPathSourceBinder` class is an `IContextSourceBinder` that returns a vocabulary with content objects as values, object titles as term titles, and object paths as tokens.
8060

81-
You can pass keyword arguments to the constructor for
82-
`ObjPathSourceBinder()` to restrict the selectable objects. Here, we
83-
demand that the object must provide the `IPresenter` interface. The
84-
syntax is the same as that used in a catalog search, except that only
85-
simple values and lists are allowed (e.g. you can’t use a dict to
86-
specify a range or values for a field index).
61+
You can pass keyword arguments to the constructor for `ObjPathSourceBinder()` to restrict the selectable objects.
62+
Here we demand that the object must provide the `IPresenter` interface.
63+
The syntax is the same as that used in a catalog search, except that only simple values and lists are allowed (in other words, you can't use a dict to specify a range or values for a field index).
8764

88-
If you want to restrict the folders and other content shown in the
89-
content browser, you can pass a dictionary with catalog search
90-
parameters (and here, any valid catalog query will do) as the first
91-
non-keyword argument (`navigation_tree_query`) to the
92-
`ObjPathSourceBinder()` constructor.
65+
If you want to restrict the folders and other content shown in the content browser, you can pass a dictionary with catalog search parameters (and here, any valid catalog query will do) as the first non-keyword argument (`navigation_tree_query`) to the `ObjPathSourceBinder()` constructor.
9366

94-
You can also create the fields in an XML schema, however you have to provide a
95-
pre-baked source instance. If you are happy with not restricting folders shown,
96-
you can use some that `plone.formwidget.contenttree` makes for you. For example:
67+
You can also create the fields in an XML schema.
68+
However you have to provide a pre-baked source instance.
69+
If you are happy with not restricting folders shown, you can use those which `plone.formwidget.contenttree` makes for you.
70+
For example:
9771

98-
```
72+
```xml
9973
<field name="links" type="plone.app.relationfield.RelationList">
10074
<title>Related Items</title>
10175
<value_type type="plone.app.relationfield.Relation">
@@ -105,49 +79,51 @@ you can use some that `plone.formwidget.contenttree` makes for you. For example:
10579
</field>
10680
```
10781

108-
:::{note}
109-
The pre-baked source binders were added in plone.formwidget.contenttree
110-
1.0.7, which ships with Plone 4.3.2+.
111-
:::
82+
```{versionadded} 4.3.2
83+
The pre-baked source binders were added in `plone.formwidget.contenttree` 1.0.7, which ships with Plone 4.3.2+.
84+
```
11285

113-
If you want to use a different widget, you can use the same source (or a
114-
custom source that has content objects as values) with something like
115-
the autocomplete widget. The following line added to the interface will
116-
make the presenter selection similar to the `organizer` selection widget
117-
we showed in the previous section:
86+
If you want to use a different widget, you can use the same source (or a custom source that has content objects as values) with something such as the autocomplete widget.
87+
The following line added to the interface will make the presenter selection similar to the `organizer` selection widget that we showed in the previous section.
11888

11989
```python
12090
from plone.autoform import directives
12191
directives.widget('presenter', AutocompleteFieldWidget)
12292
```
12393

124-
Once the user has created some relationships, the value stored in the
125-
relation field is a `RelationValue` object. This provides various
126-
attributes, including:
94+
Once the user has created some relationships, the value stored in the relation field is a `RelationValue` object.
95+
This provides various attributes, including:
96+
97+
`from_object`
98+
: The object from which the relationship is made.
99+
100+
`to_object`
101+
: The object to which the relationship is made.
102+
103+
`from_id` and `to_id`
104+
: The integer IDs of the source and target.
127105

128-
- `from_object`, the object from which the relationship is made;
129-
- `to_object`, the object to which the relationship is made;
130-
- `from_id` and `to_id`, the integer ids of the source and target;
131-
- `from_path` and `to_path`, the path of the source and target.
106+
`from_path` and `to_path`
107+
: The path of the source and target.
132108

133-
The `isBroken()` method can be used to determine if the relationship is
134-
broken. This normally happens if the target object is deleted.
109+
The `isBroken()` method can be used to determine if the relationship is broken.
110+
This normally happens if the target object is deleted.
135111

136-
To display the relationship on our form, we can either use a display
137-
widget on a *display view*, or use this API to find the object and
138-
display it. We’ll do the latter in `templates/sessionview.pt`:
112+
To display the relationship on our form, we can either use a display widget on a *display view*, or use this API to find the object and display it.
113+
We'll do the latter in {file}`templates/sessionview.pt`.
139114

140-
```html
115+
```xml
141116
<div tal:condition="context/presenter">
142117
<label i18n:translate="presenter">Presenter:</label>
143118
<span tal:content="context/presenter/to_object/Title | nothing" />
144119
</div>
145120
```
146121

122+
147123
## Back references
148124

149-
To retrieve back-reference (all objects pointing to particular object using specified attribute) you can't simply use `from_object` or `from_path`, because source object is stored in the relation without acquisition wrappers.
150-
You should use `from_id` and `helper` method, which search the object in the `IntId` catalog:
125+
To retrieve back references (all objects pointing to a particular object using the specified attribute) you can't simply use `from_object` or `from_path`, because the source object is stored in the relation without acquisition wrappers.
126+
You should use the `from_id` method, which searches the object in the `IntId` catalog:
151127

152128
```python
153129
from Acquisition import aq_inner
@@ -166,20 +142,11 @@ def back_references(source_object, attribute_name):
166142
for rel in catalog.findRelations(
167143
dict(to_id=intids.getId(aq_inner(source_object)),
168144
from_attribute=attribute_name)
169-
):
145+
):
170146
obj = intids.queryObject(rel.from_id)
171147
if obj is not None and checkPermission('zope2.View', obj):
172-
result.append(obj)
148+
result.append(obj)
173149
return result
174150
```
175151

176-
Please note, this method does not check effective and expiration date or content language.
177-
178-
Original issue: [http://code.google.com/p/dexterity/issues/detail?id=234](http://code.google.com/p/dexterity/issues/detail?id=234)
179-
180-
[five.intid]: http://pypi.python.org/pypi/five.intid
181-
[plone.app.relationfield]: http://pypi.python.org/pypi/plone.app.relationfield
182-
[plone.formwidget.contenttree]: http://pypi.python.org/pypi/plone.formwidget.contenttree
183-
[z3c.relationfield]: http://pypi.python.org/pypi/z3c.relationfield
184-
[zc.relationship]: http://pypi.python.org/pypi/zc.relationship
185-
[zope.intid]: http://pypi.python.org/pypi/zope.intid
152+
This method does not check effective and expiration dates or content language.

0 commit comments

Comments
 (0)