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