##// END OF EJS Templates
Mention that values has been renamed to options...
Patrick Snape -
Show More
@@ -1,319 +1,321
1 1 Migrating Widgets to IPython 3
2 2 ==============================
3 3
4 4 Upgrading Notebooks
5 5 -------------------
6 6
7 7 1. The first thing you'll notice when upgrading an IPython 2.0 widget
8 8 notebook to IPython 3.0 is the "Notebook converted" dialog. Click
9 9 "ok".
10 10 2. All of the widgets distributed with IPython have been renamed. The
11 11 "Widget" suffix was removed from the end of the class name. i.e.
12 12 ``ButtonWidget`` is now ``Button``.
13 13 3. ``ContainerWidget`` was renamed to ``Box``.
14 14 4. ``PopupWidget`` was removed from IPython. If you use the
15 15 ``PopupWidget``, try using a ``Box`` widget instead. If your notebook
16 16 can't live without the popup functionality, subclass the ``Box``
17 17 widget (both in Python and JS) and use JQuery UI's ``draggable()``
18 18 and ``resizable()`` methods to mimic the behavior.
19 19 5. ``add_class`` and ``remove_class`` were removed. More often than not
20 20 a new attribute exists on the widget that allows you to achieve the
21 21 same explicitly. i.e. the ``Button`` widget now has a
22 22 ``button_style`` attribute which you can set to 'primary', 'success',
23 23 'info', 'warning', 'danger', or '' instead of using ``add_class`` to
24 24 add the bootstrap class. ``VBox`` and ``HBox`` classes (flexible
25 25 ``Box`` subclasses) were added that allow you to avoid using
26 26 ``add_class`` and ``remove_class`` to make flexible box model
27 27 layouts. As a last resort, if you can't find a built in attribute for
28 28 the class you want to use, a new ``_dom_classes`` list trait was
29 29 added, which combines ``add_class`` and ``remove_class`` into one
30 30 stateful list.
31 31 6. ``set_css`` and ``get_css`` were removed in favor of explicit style
32 32 attributes - ``visible``, ``width``, ``height``, ``padding``,
33 33 ``margin``, ``color``, ``background_color``, ``border_color``,
34 34 ``border_width``, ``border_radius``, ``border_style``,
35 35 ``font_style``, ``font_weight``, ``font_size``, and ``font_family``
36 36 are a few. If you can't find a trait to see the css attribute you
37 37 need, you can, in order of preference, (A) subclass to create your
38 38 own custom widget, (B) use CSS and the ``_dom_classes`` trait to set
39 39 ``_dom_classes``, or (C) use the ``_css`` dictionary to set CSS
40 40 styling like ``set_css`` and ``get_css``.
41 7. For selection widgets, such as ``Dropdown``, the ``values`` argument
42 has been renamed to ``options``.
41 43
42 44 Upgrading Custom Widgets
43 45 ------------------------
44 46
45 47 Javascript
46 48 ~~~~~~~~~~
47 49
48 50 1. If you are distributing your widget and decide to use the deferred
49 51 loading technique (preferred), you can remove all references to the
50 52 WidgetManager and the register model/view calls (see the Python
51 53 section below for more information).
52 54 2. In 2.0 require.js was used incorrectly, that has been fixed and now
53 55 loading works more like Python's import. Requiring
54 56 ``widgets/js/widget`` doesn't import the ``WidgetManager`` class,
55 57 instead it imports a dictionary that exposes the classes within that
56 58 module:
57 59
58 60 .. code:: javascript
59 61
60 62 {
61 63 'WidgetModel': WidgetModel,
62 64 'WidgetView': WidgetView,
63 65 'DOMWidgetView': DOMWidgetView,
64 66 'ViewList': ViewList,
65 67 }
66 68
67 69 If you decide to continue to use the widget registry (by registering
68 70 your widgets with the manager), you can import a dictionary with a
69 71 handle to the WidgetManager class by requiring
70 72 ``widgets/js/manager``. Doing so will import:
71 73
72 74 .. code:: javascript
73 75
74 76 {'WidgetManager': WidgetManager}
75 77
76 78 3. Don't rely on the ``IPython`` namespace for anything. To inherit from
77 79 the DOMWidgetView, WidgetView, or WidgetModel, require
78 80 ``widgets/js/widget`` as ``widget``. If you were inheriting from
79 81 DOMWidgetView, and the code looked like this:
80 82
81 83 .. code:: javascript
82 84
83 85 IPython.DOMWidgetView.extend({...})
84 86
85 87 It would become this:
86 88
87 89 .. code:: javascript
88 90
89 91 widget.DOMWidgetView.extend({...})
90 92
91 93 4. Custom models are encouraged. When possible, it's recommended to move
92 94 your code into a custom model, so actions are performed 1 time,
93 95 instead of N times where N is the number of displayed views.
94 96
95 97 Python
96 98 ~~~~~~
97 99
98 100 Generally, custom widget Python code can remain unchanged. If you
99 101 distribute your custom widget, you may be using ``display`` and
100 102 ``Javascript`` to publish the widget's Javascript to the front-end. That
101 103 is no longer the recommended way of distributing widget Javascript.
102 104 Instead have the user install the Javascript to his/her nbextension
103 105 directory or their profile's static directory. Then use the new
104 106 ``_view_module`` and ``_model_module`` traitlets in combination with
105 107 ``_view_name`` and ``_model_name`` to instruct require.js on how to load
106 108 the widget's Javascript. The Javascript is then loaded when the widget
107 109 is used for the first time.
108 110
109 111 Details
110 112 -------
111 113
112 114 Asynchronous
113 115 ~~~~~~~~~~~~
114 116
115 117 In the IPython 2.x series the only way to register custom widget views
116 118 and models was to use the registry in the widget manager. Unfortunately,
117 119 using this method made distributing and running custom widgets difficult. The widget
118 120 maintainer had to either use the rich display framework to push the
119 121 widget's Javascript to the notebook or instruct the users to install the
120 122 Javascript by hand in a custom profile. With the first method, the
121 123 maintainer would have to be careful about when the Javascript was pushed
122 124 to the front-end. If the Javascript was pushed on Python widget
123 125 ``import``, the widgets wouldn't work after page refresh. This is
124 126 because refreshing the page does not restart the kernel, and the Python
125 127 ``import`` statement only runs once in a given kernel instance (unless
126 128 you reload the Python modules, which isn't straight forward). This meant
127 129 the maintainer would have to have a separate ``push_js()`` method that
128 130 the user would have to call after importing the widget's Python code.
129 131
130 132 Our solution was to add support for loading widget views and models
131 133 using require.js paths. Thus the comm and widget frameworks now support
132 134 lazy loading. To do so, everything had to be converted to asynchronous
133 135 code. HTML5 promises are used to accomplish that
134 136 (`#6818 <https://github.com/ipython/ipython/pull/6818>`__,
135 137 `#6914 <https://github.com/ipython/ipython/pull/6914>`__).
136 138
137 139 Symmetry
138 140 ~~~~~~~~
139 141
140 142 In IPython 3.0, widgets can be instantiated from the front-end
141 143 (`#6664 <https://github.com/ipython/ipython/pull/6664>`__). On top of
142 144 this, a widget persistence API was added
143 145 (`#7163 <https://github.com/ipython/ipython/pull/7163>`__,
144 146 `#7227 <https://github.com/ipython/ipython/pull/7227>`__). With the
145 147 widget persistence API, you can persist your widget instances using
146 148 Javascript. This makes it easy to persist your widgets to your notebook
147 149 document (with a small amount of custom JS). By default, the widgets are
148 150 persisted to your web browsers local storage which makes them reappear
149 151 when your refresh the page.
150 152
151 153 Smaller Changes
152 154 ~~~~~~~~~~~~~~~
153 155
154 156 - Latex math is supported in widget ``description``\ s
155 157 (`#5937 <https://github.com/ipython/ipython/pull/5937>`__).
156 158 - Widgets can be display more than once within a single container
157 159 widget (`#5963 <https://github.com/ipython/ipython/pull/5963>`__,
158 160 `#6990 <https://github.com/ipython/ipython/pull/6990>`__).
159 161 - ``FloatRangeSlider`` and ``IntRangeSlider`` were added
160 162 (`#6050 <https://github.com/ipython/ipython/pull/6050>`__).
161 163 - "Widget" was removed from the ends of all of the widget class names
162 164 (`#6125 <https://github.com/ipython/ipython/pull/6125>`__).
163 165 - ``ContainerWidget`` was renamed to ``Box``
164 166 (`#6125 <https://github.com/ipython/ipython/pull/6125>`__).
165 167 - ``HBox`` and ``VBox`` widgets were added
166 168 (`#6125 <https://github.com/ipython/ipython/pull/6125>`__).
167 169 - ``add\_class`` and ``remove\_class`` were removed in favor of a
168 170 ``_dom_classes`` list
169 171 (`#6235 <https://github.com/ipython/ipython/pull/6235>`__).
170 172 - ``get\_css`` and ``set\_css`` were removed in favor of explicit
171 173 traits for widget styling
172 174 (`#6235 <https://github.com/ipython/ipython/pull/6235>`__).
173 175 - ``jslink`` and ``jsdlink`` were added
174 176 (`#6454 <https://github.com/ipython/ipython/pull/6454>`__,
175 177 `#7468 <https://github.com/ipython/ipython/pull/7468>`__).
176 178 - An ``Output`` widget was added, which allows you to ``print`` and
177 179 ``display`` within widgets
178 180 (`#6670 <https://github.com/ipython/ipython/pull/6670>`__).
179 181 - ``PopupWidget`` was removed
180 182 (`#7341 <https://github.com/ipython/ipython/pull/7341>`__).
181 183 - A visual cue was added for widgets with 'dead' comms
182 184 (`#7227 <https://github.com/ipython/ipython/pull/7227>`__).
183 185 - A ``SelectMultiple`` widget was added (a ``Select`` widget that
184 186 allows multiple things to be selected at once)
185 187 (`#6890 <https://github.com/ipython/ipython/pull/6890>`__).
186 188 - A class was added to help manage children views
187 189 (`#6990 <https://github.com/ipython/ipython/pull/6990>`__).
188 190 - A warning was added that shows on widget import because it's expected
189 191 that the API will change again by IPython 4.0. This warning can be
190 192 supressed (`#7107 <https://github.com/ipython/ipython/pull/7107>`__,
191 193 `#7200 <https://github.com/ipython/ipython/pull/7200>`__,
192 194 `#7201 <https://github.com/ipython/ipython/pull/7201>`__,
193 195 `#7204 <https://github.com/ipython/ipython/pull/7204>`__).
194 196
195 197 Comm and Widget PR Index
196 198 ------------------------
197 199
198 200 Here is a chronological list of PRs affecting the widget and comm frameworks for IPython 3.0. Note that later PRs may revert changes
199 201 made in earlier PRs:
200 202
201 203 - Add placeholder attribute to text widgets
202 204 `#5652 <https://github.com/ipython/ipython/pull/5652>`__
203 205 - Add latex support in widget labels,
204 206 `#5937 <https://github.com/ipython/ipython/pull/5937>`__
205 207 - Allow widgets to display more than once within container widgets.
206 208 `#5963 <https://github.com/ipython/ipython/pull/5963>`__
207 209 - use require.js,
208 210 `#5980 <https://github.com/ipython/ipython/pull/5980>`__
209 211 - Range widgets
210 212 `#6050 <https://github.com/ipython/ipython/pull/6050>`__
211 213 - Interact on\_demand option
212 214 `#6051 <https://github.com/ipython/ipython/pull/6051>`__
213 215 - Allow text input on slider widgets
214 216 `#6106 <https://github.com/ipython/ipython/pull/6106>`__
215 217 - support binary buffers in comm messages
216 218 `#6110 <https://github.com/ipython/ipython/pull/6110>`__
217 219 - Embrace the flexible box model in the widgets
218 220 `#6125 <https://github.com/ipython/ipython/pull/6125>`__
219 221 - Widget trait serialization
220 222 `#6128 <https://github.com/ipython/ipython/pull/6128>`__
221 223 - Make Container widgets take children as the first positional
222 224 argument `#6153 <https://github.com/ipython/ipython/pull/6153>`__
223 225 - once-displayed
224 226 `#6168 <https://github.com/ipython/ipython/pull/6168>`__
225 227 - Validate slider value, when limits change
226 228 `#6171 <https://github.com/ipython/ipython/pull/6171>`__
227 229 - Unregistering comms in Comm Manager
228 230 `#6216 <https://github.com/ipython/ipython/pull/6216>`__
229 231 - Add EventfulList and EventfulDict trait types.
230 232 `#6228 <https://github.com/ipython/ipython/pull/6228>`__
231 233 - Remove add/remove\_class and set/get\_css.
232 234 `#6235 <https://github.com/ipython/ipython/pull/6235>`__
233 235 - avoid unregistering widget model twice
234 236 `#6250 <https://github.com/ipython/ipython/pull/6250>`__
235 237 - Widget property lock should compare json states, not python states
236 238 `#6332 <https://github.com/ipython/ipython/pull/6332>`__
237 239 - Strip the IPY\_MODEL\_ prefix from widget IDs before referencing
238 240 them. `#6377 <https://github.com/ipython/ipython/pull/6377>`__
239 241 - "event" is not defined error in Firefox
240 242 `#6437 <https://github.com/ipython/ipython/pull/6437>`__
241 243 - Javascript link
242 244 `#6454 <https://github.com/ipython/ipython/pull/6454>`__
243 245 - Bulk update of widget attributes
244 246 `#6463 <https://github.com/ipython/ipython/pull/6463>`__
245 247 - Creating a widget registry on the Python side.
246 248 `#6493 <https://github.com/ipython/ipython/pull/6493>`__
247 249 - Allow widget views to be loaded from require modules
248 250 `#6494 <https://github.com/ipython/ipython/pull/6494>`__
249 251 - Fix Issue #6530
250 252 `#6532 <https://github.com/ipython/ipython/pull/6532>`__
251 253 - Make comm manager (mostly) independent of InteractiveShell
252 254 `#6540 <https://github.com/ipython/ipython/pull/6540>`__
253 255 - Add semantic classes to top-level containers for single widgets
254 256 `#6609 <https://github.com/ipython/ipython/pull/6609>`__
255 257 - Selection Widgets: forcing 'value' to be in 'values'
256 258 `#6617 <https://github.com/ipython/ipython/pull/6617>`__
257 259 - Allow widgets to be constructed from Javascript
258 260 `#6664 <https://github.com/ipython/ipython/pull/6664>`__
259 261 - Output widget
260 262 `#6670 <https://github.com/ipython/ipython/pull/6670>`__
261 263 - Minor change in widgets.less to fix alignment issue
262 264 `#6681 <https://github.com/ipython/ipython/pull/6681>`__
263 265 - Make Selection widgets respect values order.
264 266 `#6747 <https://github.com/ipython/ipython/pull/6747>`__
265 267 - Widget persistence API
266 268 `#6789 <https://github.com/ipython/ipython/pull/6789>`__
267 269 - Add promises to the widget framework.
268 270 `#6818 <https://github.com/ipython/ipython/pull/6818>`__
269 271 - SelectMultiple widget
270 272 `#6890 <https://github.com/ipython/ipython/pull/6890>`__
271 273 - Tooltip on toggle button
272 274 `#6923 <https://github.com/ipython/ipython/pull/6923>`__
273 275 - Allow empty text box \*while typing\* for numeric widgets
274 276 `#6943 <https://github.com/ipython/ipython/pull/6943>`__
275 277 - Ignore failure of widget MathJax typesetting
276 278 `#6948 <https://github.com/ipython/ipython/pull/6948>`__
277 279 - Refactor the do\_diff and manual child view lists into a separate
278 280 ViewList object
279 281 `#6990 <https://github.com/ipython/ipython/pull/6990>`__
280 282 - Add warning to widget namespace import.
281 283 `#7107 <https://github.com/ipython/ipython/pull/7107>`__
282 284 - lazy load widgets
283 285 `#7120 <https://github.com/ipython/ipython/pull/7120>`__
284 286 - Fix padding of widgets.
285 287 `#7139 <https://github.com/ipython/ipython/pull/7139>`__
286 288 - Persist widgets across page refresh
287 289 `#7163 <https://github.com/ipython/ipython/pull/7163>`__
288 290 - Make the widget experimental error a real python warning
289 291 `#7200 <https://github.com/ipython/ipython/pull/7200>`__
290 292 - Make the widget error message shorter and more understandable.
291 293 `#7201 <https://github.com/ipython/ipython/pull/7201>`__
292 294 - Make the widget warning brief and easy to filter
293 295 `#7204 <https://github.com/ipython/ipython/pull/7204>`__
294 296 - Add visual cue for widgets with dead comms
295 297 `#7227 <https://github.com/ipython/ipython/pull/7227>`__
296 298 - Widget values as positional arguments
297 299 `#7260 <https://github.com/ipython/ipython/pull/7260>`__
298 300 - Remove the popup widget
299 301 `#7341 <https://github.com/ipython/ipython/pull/7341>`__
300 302 - document and validate link, dlink
301 303 `#7468 <https://github.com/ipython/ipython/pull/7468>`__
302 304 - Document interact 5637
303 305 `#7525 <https://github.com/ipython/ipython/pull/7525>`__
304 306 - Update some broken examples of using widgets
305 307 `#7547 <https://github.com/ipython/ipython/pull/7547>`__
306 308 - Use Output widget with Interact
307 309 `#7554 <https://github.com/ipython/ipython/pull/7554>`__
308 310 - don't send empty execute\_result messages
309 311 `#7560 <https://github.com/ipython/ipython/pull/7560>`__
310 312 - Validation on the python side
311 313 `#7602 <https://github.com/ipython/ipython/pull/7602>`__
312 314 - only show prompt overlay if there's a prompt
313 315 `#7661 <https://github.com/ipython/ipython/pull/7661>`__
314 316 - Allow predictate to be used for comparison in selection widgets
315 317 `#7674 <https://github.com/ipython/ipython/pull/7674>`__
316 318 - Fix widget view persistence.
317 319 `#7680 <https://github.com/ipython/ipython/pull/7680>`__
318 320 - Revert "Use Output widget with Interact"
319 321 `#7703 <https://github.com/ipython/ipython/pull/7703>`__
General Comments 0
You need to be logged in to leave comments. Login now