Skip to content

Commit f7457be

Browse files
authored
Merge pull request #132 from pyscript/2024-7-1
Update docs for release 2024-7-1
2 parents 109138d + ad42cc0 commit f7457be

File tree

10 files changed

+694
-429
lines changed

10 files changed

+694
-429
lines changed

docs/user-guide/builtins.md renamed to docs/api.md

Lines changed: 500 additions & 260 deletions
Large diffs are not rendered by default.

docs/beginning-pyscript.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,8 @@ module in the document's `<head>` tag:
112112
<meta charset="utf-8" />
113113
<meta name="viewport" content="width=device-width,initial-scale=1" />
114114
<title>🦜 Polyglot - Piratical PyScript</title>
115-
<link rel="stylesheet" href="https://pyscript.net/releases/2024.6.2/core.css">
116-
<script type="module" src="https://pyscript.net/releases/2024.6.2/core.js"></script>
115+
<link rel="stylesheet" href="https://pyscript.net/releases/2024.7.1/core.css">
116+
<script type="module" src="https://pyscript.net/releases/2024.7.1/core.js"></script>
117117
</head>
118118
<body>
119119

@@ -147,7 +147,7 @@ application's output.
147147
There's something strange about the `<button>` tag: it has a `py-click`
148148
attribute with the value `translate_english`. This is, in fact, the name of a
149149
Python function we'll run whenever the button is clicked. Such `py-*` style
150-
attributes are [built into PyScript](user-guide/builtins.md#html-attributes).
150+
attributes are [built into PyScript](api.md#html-attributes).
151151

152152
We put all this together in the `script` tag at the end of the `<body>`. This
153153
tells the browser we're using PyScript (`type="py"`), and where PyScript
@@ -163,8 +163,8 @@ In the end, our HTML should look like this:
163163
<meta charset="utf-8" />
164164
<meta name="viewport" content="width=device-width,initial-scale=1" />
165165
<title>🦜 Polyglot - Piratical PyScript</title>
166-
<link rel="stylesheet" href="https://pyscript.net/releases/2024.6.2/core.css">
167-
<script type="module" src="https://pyscript.net/releases/2024.6.2/core.js"></script>
166+
<link rel="stylesheet" href="https://pyscript.net/releases/2024.7.1/core.css">
167+
<script type="module" src="https://pyscript.net/releases/2024.7.1/core.js"></script>
168168
</head>
169169
<body>
170170
<h1>Polyglot 🦜 💬 🇬🇧 ➡️ 🏴‍☠️</h1>

docs/faq.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ hence the error message.
200200
If you encounter this problem you have two possible solutions:
201201

202202
1. Manually wrap such functions with a call to
203-
[`pyscript.ffi.create_proxy`](../builtins/#pyscriptfficreate_proxy).
203+
[`pyscript.ffi.create_proxy`](../../api/#pyscriptfficreate_proxy).
204204
2. Set the
205205
[`experimental_create_proxy = "auto"`](../configuration/#experimental_create_proxy)
206206
flag in your application's settings. This flag intercepts Python objects
@@ -922,7 +922,7 @@ def download_file(path, mime_type):
922922
### create_proxy
923923

924924
The `create_proxy` function is described in great detail
925-
[on the FFI page](../ffi/), but it's also useful to explain _when_
925+
[on the FFI page](../user-guide/ffi/), but it's also useful to explain _when_
926926
`create_proxy` is needed and the subtle differences between Pyodide and
927927
MicroPython.
928928

docs/user-guide/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Here's how PyScript unfolds through time:
181181
[plugins](configuration.md/#plugins), [packages](configuration.md/#packages), [files](configuration.md/#files) or [JavaScript modules](configuration.md/#javascript-modules)
182182
that need to be loaded.
183183
5. Make available various
184-
[builtin helper objects and functions](builtins.md) to the
184+
[builtin helper objects and functions](../../api) to the
185185
interpreter's environment (accessed via the `pyscript` module).
186186
6. Only then use the interpreter in the correctly configured environment to
187187
evaluate the detected Python code.

docs/user-guide/dom.md

Lines changed: 127 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -73,204 +73,188 @@ equivalent values: `["hello", 1, 2, 3]`.
7373

7474
Should you require lower level API access to FFI features, you can find such
7575
builtin functions under the `pyscript.ffi` namespace in both Pyodide and
76-
MicroPython. The available functions are described in our section on
77-
[builtin helpers](../builtins).
76+
MicroPython. The available functions are described in our section on the
77+
[builtin API](../../api).
7878

7979
Advanced users may wish to explore the
8080
[technical details of the FFI](../ffi).
8181

82-
## PyDom
83-
84-
The Standard Web APIs are massive and not always very user-friendly. `PyDom` is
85-
a Python module that exposes the power of the web with an easy and idiomatic
86-
Pythonic interface on top.
87-
88-
While the [FFI](#ffi) interface described above focuses on giving full access
89-
to the entire Standard Web APIs, `pydom` focuses on providing a small,
90-
intuitive and yet powerful API that prioritises common use cases fist. For this
91-
reason, its first layer is simple (but limited to the most common use cases),
92-
but `pydom` also provides a secondary layer to directly use full FFI interface
93-
of a specific element.
94-
95-
PyDom does not aim to replace the regular web (Javascript) API nor to be as
96-
wide and offer feature parity. On the contrary, it is intentionally small and
97-
focused on the most popular use cases while still providing (backdoor) access
98-
to the full JavaScript API.
99-
100-
`Pydom` draws inspiration from popular Python APIs/Libraries known to be
101-
friendly and easy to learn, and other successful projects related the web as
102-
well (for instance, `JQuery` was a source of inspiration).
82+
## `pyscript.web`
10383

10484
!!! warning
10585

106-
PyDom is currently a work in progress.
86+
The `pyscript.web` module is currently a work in progress.
10787

10888
We welcome feedback and suggestions.
10989

90+
The `pyscript.web` module is an idiomatically Pythonic API for interacting with
91+
the DOM. It wraps the FFI in a way that is more familiar to Python developers
92+
and works natively with the Python language. Technical documentation for this
93+
module can be found in [the API](../../api/#pyscriptweb) section.
11094

111-
### Core Concepts
95+
There are three core concepts to remember:
11296

113-
`Pydom` builds on topic of very few and simple core concepts:
114-
115-
* __`Element`:__ any component that is part of a web page. This is a rough
116-
abstraction of an
117-
[HTMLElement](https://developer.mozilla.org/en-US/docs/Glossary/Element).
118-
In general, `pydom` elements always map to an underlying `HTML` `Element` in
119-
a web page
120-
* __`ElementCollection`:__ a collection of one or more `Elements`. It is a
121-
rough abstraction of an
122-
[HTMLCollection](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCollection).
123-
* __Querying:__ a method to query elements on a page based on a
124-
[selector](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors).
125-
Pydom supports standard HTML DOM query selectors to
126-
[locate DOM elements](https://developer.mozilla.org/en-US/docs/Web/API/Document_object_model/Locating_DOM_elements_using_selectors)
127-
as other native `JavaScript` methods like `querySelector` or
97+
* Find elements on the page via
98+
[CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors).
99+
The `find` API uses exactly the [same queries](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Locating_DOM_elements_using_selectors)
100+
as those used by native browser methods like `qurerySelector` or
128101
`querySelectorAll`.
102+
* Use classes in the `pyscript.web.elements` namespace to create and organise
103+
new elements on the web page.
104+
* Collections of elements allow you to access and change attributes en-mass.
105+
Such collections are returned from `find` queries and are also used for the
106+
[children](https://developer.mozilla.org/en-US/docs/Web/API/Element/children)
107+
of an element.
108+
109+
You have several options for accessing the content of the page (i.e. the DOM),
110+
and these can be found in the `pyscript.web.dom` object. The `head` and `body`
111+
attributes reference the page's head and body. Furthermore, the `find` method
112+
can be used to return collections of elements matching your CSS query. Finally,
113+
all elements have a `find` method that searches within their children for
114+
elements matching your CSS query.
129115

130-
Let's look into each of these aspects in more in detail.
131-
132-
### Element
116+
```python
117+
from pyscript.web import dom
133118

134-
A PyDom `Element` is simply an abstraction of a tranditional `Element` in a web
135-
page. Every PyDom `Element` maps to an underlying JavaScript `Element` in a
136-
web page. These two elements are always in sync and any change of state in one
137-
is reflected in the other.
138119

139-
#### Creating a new element
120+
# Print all the child elements of the document's head.
121+
print(dom.head.children)
122+
# Find all the paragraphs in the DOM.
123+
paragraphs = dom.find("p")
124+
```
140125

141-
New elements are created using the `pydom.create` method and passing the type
142-
of element being created. Here's an example of what it looks like:
126+
The object returned from a query, or used as a reference to an element's
127+
children is iterable:
143128

144129
```python
145-
from pyweb import pydom
130+
from pyscript.web import dom
146131

147-
# Creating an element directly from pydom creates an unbounded element.
148-
new_div = pydom.create("div")
149132

150-
# Creating an element from another element automatically creates that element
151-
# as a child of the original element
152-
new_p = new_div.create(
153-
"p",
154-
classes=["code-description"],
155-
html="Ciao PyScripters!"
156-
)
133+
# Get all the paragraphs in the DOM.
134+
paragraphs = dom.find("p")
157135

158-
# elements can be appended to any other element on the page
159-
pydom['#element-creation-example'][0].append(new_div)
136+
# Print the inner html of each paragraph.
137+
for p in paragraphs:
138+
print(p.html)
160139
```
161140

162-
#### Setting an element's content
163-
164-
The `Element` interface offers two ways to set an element's content: the `html`
165-
and the `content` attributes:
166-
167-
* `html`: directly sets the `innerHTML` field of the underlying element without
168-
attemnpting any conversion.
169-
* `content`: sets the `innerHTML` field via the PyScript `display` function.
170-
This takes care of properly rendering the object being passed based on the
171-
object mimetype. So, for instance, if the objects is an image, it'll be
172-
properly rendered within the element
141+
Alternatively, it is also indexable / sliceable:
173142

174-
In general, we suggest using `content` directly as it'll take care of most use
175-
cases without requiring any extra work from the user.
143+
```python
144+
from pyscript.web import dom
176145

177-
#### Changing an element's style
178146

179-
Elements have a `style` attribute to change the element style rules. The
180-
`style` attribute is a dictionary and, to set a style rule for the element,
181-
simply set the correct key on the `.style` attribute. For instance, the
182-
following code changes the background color (of the element created in the
183-
example above):
147+
# Get an ElementCollection of all the paragraphs in the DOM
148+
paragraphs = dom.find("p")
184149

185-
```python
186-
new_p.style["background-color"] = "yellow"
150+
# Only the final two paragraphs.
151+
for p in paragraphs[-2:]:
152+
print(p.html)
187153
```
188154

189-
To remove a style key, simply use the `pop` method as you'd to to remove
190-
a key from a dictionary:
155+
It also makes available the following read and writable attributes related to
156+
all contained elements:
191157

192-
```python
193-
new_p.style.pop("background-color")
194-
```
158+
* `classes` - the list of classes associated with the elements.
159+
* `innerHTML` - the innerHTML of each element.
160+
* `style` - a dictionary like object for interacting with CSS style rules.
161+
* `value` - the `value` attribute associated with each element.
162+
163+
For example, to continue the example above, `paragraphs.innerHTML` will return
164+
a list of all the values of the `innerHTML` attribute on each contained
165+
element. Alternatively, set an attribute for all elements contained in the
166+
collection like this: `paragraphs.style["background-color"] = "blue"`.
195167

196-
In addition to the dictionary interface to explicitly set CSS rules, the
197-
`style` attribute also offers a convenient `visible` property that can be use
198-
show/hide an element.
168+
It's possible to create new elements to add to the DOM:
199169

200170
```python
201-
new_p.style.visible = False
171+
from pyscript.web import dom
172+
from pyscript.web.elements import *
173+
174+
175+
dom.body.append(
176+
div(
177+
div("Hello!", classes="a-css-class", id="hello"),
178+
select(
179+
option("apple", value=1),
180+
option("pear", value=2),
181+
option("orange", value=3),
182+
),
183+
div(
184+
button(span("Hello! "), span("World!"), id="my-button"),
185+
br(),
186+
button("Click me!"),
187+
classes=["css-class1", "css-class2"],
188+
style={"background-color": "red"}
189+
),
190+
div(
191+
children=[
192+
button(
193+
children=[
194+
span("Hello! "),
195+
span("Again!")
196+
],
197+
id="another-button"
198+
),
199+
br(),
200+
button("b"),
201+
],
202+
classes=["css-class1", "css-class2"]
203+
)
204+
)
205+
)
202206
```
203207

204-
#### Other useful aspects of the Element API
208+
This example demonstrates a declaritive way to add elements to the body of the
209+
DOM. Notice how the first (unnamed) arguments to an element are its children.
210+
The named arguments (such as `id`, `classes` and `style`) refer to attributes
211+
of the underlying HTML element. If you'd rather be explicit about the children
212+
of an element, you can always pass in a list of such elements as the named
213+
`children` argument (you see this in the final `div` in the example above).
205214

206-
* `append`: a method to append a new child to the element.
207-
* `children`: list of the children of the element.
208-
* `value`: allows to set the `value` attribute of an element.
209-
* `clone`: a method that creates a clone of the element. NOTE: The cloned
210-
elements will not be attached to any other element.
211-
* `show_me`: a method to scroll the page to where the element is placed.
215+
Of course, you can achieve similar results in an imperative style of
216+
programming:
212217

213-
### Element collections
218+
```python
219+
from pyscript.web import dom
220+
from pyscript.web.elements import *
214221

215-
Element collections represent a collection of elements typically returned from
216-
a query. For instance:
217222

218-
```python
219-
paragraphs = pydom['p']
220-
```
221223

222-
In the example above, `paragraphs` is an `ElementCollection` that maps to all
223-
`p` elements in the page.
224+
my_div = div()
225+
my_div.style["background-color"] = "red"
226+
my_div.classes.append("a-css-class")
224227

225-
An `ElementCollection` can be used to iterate over a collection of elements or
226-
to pick specific elements or slices of elements in the collection. For
227-
instance:
228+
my_p = p()
229+
my_p.content = "This is a paragraph."
228230

229-
```python
230-
for element in paragraphs:
231-
display(element.html)
231+
my_div.append(my_p)
232232

233-
# let's now display only the last 2 elements
234-
for element in paragraphs[-2:]:
235-
display(element.html)
233+
# etc...
236234
```
237235

238-
#### Interacting with an ElementCollection
239-
240-
Besides allowing operations as an iterable object, `ElementCollection` objects
241-
also offer a few convenience methods to directly interact with the elements
242-
within the collection. For instance, it's possible to ask for specific
243-
attributes of the elements in the collection directly:
236+
It's also important to note that the `pyscript.when` decorator understands
237+
element references from `pyscript.web`:
244238

245239
```python
246-
display(paragraphs.html)
247-
```
248-
249-
This displays a list with the values of the `html` attribute for all the
250-
elements in the `paragraphs` collection.
240+
from pyscript import when
241+
from pyscript.web import dom
251242

252-
In the same way we can read attributes, we can also set an attribute directly
253-
in the collection. For instance, you can directly set the html content of all
254-
the elements in the collection:
255243

256-
```python
257-
# This will change the text of all H1 elements in the page
258-
pydom['h1'].html = "That's cool :)"
259-
```
244+
btn = dom.find("#my-button")
260245

261-
Or perhaps change their style:
262246

263-
```
264-
paragraphs.style['background-color'] = 'lightyellow'
247+
@when("click", btn)
248+
def my_button_click_handler(event):
249+
print("The button has been clicked!")
265250
```
266251

267-
The `ElementCollection` class currently supports the following attributes:
252+
Should you wish direct access to the proxy object representing the underlying
253+
HTML element, each Python element has a `_dom_element` property for this
254+
purpose.
268255

269-
* `style`: just like in `Element`, this proxy attribute can be used to change
270-
the style of the elements in a collection by setting the proper CSS rules,
271-
using `style` with the same API as a dictionary.
272-
* `html`: changes the `html` attribute on all the elements of a collection.
273-
* `value`: changes the `value` attribute on all the elements of a collection.
256+
Once again, the technical details of these classes are described in the
257+
[built-in API documentation](../../api/#pyscriptweb).
274258

275259
## Working with JavaScript
276260

0 commit comments

Comments
 (0)