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