Skip to content

Commit dfef613

Browse files
committed
simplify HTML with IDOM section
1 parent e2b538e commit dfef613

File tree

4 files changed

+141
-41
lines changed

4 files changed

+141
-41
lines changed

docs/source/creating-interfaces/html-with-idom.rst

Lines changed: 63 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ with its backing data and logic are distributed between a client and server
66
respectively. With IDOM, both these tasks are centralized in a single place. This is
77
done by allowing HTML interfaces to be constructed in Python. Take a look at the two
88
code examples below. The one on the left shows how to make a basic title and todo list
9-
using standard HTML while the one of the right uses IDOM in Python:
9+
using standard HTML, the one of the right uses IDOM in Python, and below is a view of
10+
what the HTML would look like if displayed:
1011

1112
.. grid:: 2
1213
:margin: 0
1314
:padding: 0
1415

1516
.. grid-item::
17+
:columns: 6
1618

1719
.. code-block:: html
1820

@@ -23,6 +25,7 @@ using standard HTML while the one of the right uses IDOM in Python:
2325
</ul>
2426

2527
.. grid-item::
28+
:columns: 6
2629

2730
.. testcode::
2831

@@ -34,12 +37,25 @@ using standard HTML while the one of the right uses IDOM in Python:
3437
html.li("Share it with the world!"),
3538
)
3639

40+
.. grid-item-card::
41+
:columns: 12
42+
43+
.. raw:: html
44+
45+
<div style="width: 50%; margin: auto;">
46+
<h2 style="margin-top: 0px !important;">My Todo List</h2>
47+
<ul>
48+
<li>Build a cool new app</li>
49+
<li>Share it with the world!</li>
50+
</ul>
51+
</div>
52+
3753
What this shows is that you can recreate the same HTML layouts with IDOM using functions
3854
from the :mod:`idom.html` module. These function share the same names as their
3955
corresponding HTML tags. For example, the ``<h1/>`` element above has a similarly named
4056
:func:`~idom.html.h1` function. With that said, while the code above looks similar, it's
4157
not very useful because we haven't captured the results from these function calls in a
42-
variable. To do this we need to wraps up layout above into a single
58+
variable. To do this we need to wrap up the layout above into a single
4359
:func:`~idom.html.div` and assign it to a variable:
4460

4561
.. testcode::
@@ -52,44 +68,51 @@ variable. To do this we need to wraps up layout above into a single
5268
),
5369
)
5470

55-
Having done this we can inspect what is contained in our new ``layout`` variable. As it
56-
turns out, it holds a dictionary. Printing it produces the following output:
71+
72+
Adding HTML Attributes
73+
----------------------
74+
75+
That's all well and good, but there's more to HTML than just text. What if we wanted to
76+
display an image? In HTMl we'd use the `<img/>` element and add attributes to it order
77+
to specify a URL to its ``src`` and use some ``style`` to modify and position it:
78+
79+
.. code-block:: html
80+
81+
<img
82+
src="https://picsum.photos/500/300"
83+
style="width: 70%; margin-left: 15%;"
84+
/>
85+
86+
In IDOM we add these attributes to elements using dictionaries. There are some notable
87+
differences though. The biggest being the fact that all names in IDOM use ``camelCase``
88+
instead of dash-sepearted words. For example, ``margin-left`` becomes ``marginLeft``.
89+
Additionally, instead of specifying ``style`` using a string, we use a dictionary:
5790

5891
.. testcode::
5992

60-
print(layout)
61-
62-
.. testoutput::
63-
:options: +NORMALIZE_WHITESPACE
64-
65-
{
66-
'tagName': 'div',
67-
'children': [
68-
{
69-
'tagName': 'h1',
70-
'children': ['My Todo List']
71-
},
72-
{
73-
'tagName': 'ul',
74-
'children': [
75-
{'tagName': 'li', 'children': ['Build a cool new app']},
76-
{'tagName': 'li', 'children': ['Share it with the world!']}
77-
]
78-
}
79-
]
80-
}
81-
82-
This may look complicated, but let's take a moment to consider what's going on here. We
83-
have a series of nested dictionaries that, in some way, represents the HTML structure
84-
given above. If we look at their contents we should see a common form. Each has a
85-
``tagName`` key which contains, as the name would suggest, the tag name of an HTML
86-
element. Then within the ``children`` key is a list that either contains strings or
87-
other dictionaries that represent HTML elements.
88-
89-
What we're seeing here is called a "virtual document object model" or :ref:`VDOM`. This
90-
is just a fancy way of saying we have a representation of the document object model or
91-
`DOM
92-
<https://en.wikipedia.org/wiki/Document_Object_Model#:~:text=The%20Document%20Object%20Model%20(DOM,document%20with%20a%20logical%20tree.&text=Nodes%20can%20have%20event%20handlers%20attached%20to%20them.>`__
93-
that is not the actual DOM. We'll talk more about this concept :ref:`in the future
94-
<Communication Scheme>`, but for now, just understand that in IDOM, we represent the
95-
HTML document object model using dictionaries that we call VDOM.
93+
html.img(
94+
{
95+
"src": "https://picsum.photos/500/300",
96+
"style": {"width": "70%", "marginLeft": "15%"},
97+
}
98+
)
99+
100+
.. raw:: html
101+
102+
<img
103+
src="https://picsum.photos/500/300"
104+
style="width: 70%; margin-left: 15%;"
105+
/>
106+
107+
108+
----------
109+
110+
111+
.. card::
112+
:link: /understanding-idom/representing-html
113+
:link-type: doc
114+
115+
:octicon:`book` Read More
116+
^^^^^^^^^^^^^^^^^^^^^^^^^
117+
118+
Dive into the data structures IDOM uses to represent HTML

docs/source/understanding-idom/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ Understanding IDOM
55
:hidden:
66

77
why-idom
8+
representing-html
89
core-abstractions
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
How IDOM Represents HTML
2+
========================
3+
4+
We've already discussed how to contruct HTML with IDOM in a :ref:`previous section <HTML
5+
with IDOM>`, but we skimmed over the question of the data structure we use to represent
6+
it. Let's reconsider the examples from before - on the top is some HTML and on the
7+
bottom is the corresponding code to create it in IDOM:
8+
9+
.. code-block:: html
10+
11+
<div>
12+
<h1>My Todo List</h1>
13+
<ul>
14+
<li>Build a cool new app</li>
15+
<li>Share it with the world!</li>
16+
</ul>
17+
</div>
18+
19+
.. testcode::
20+
21+
from idom import html
22+
23+
layout = html.div(
24+
html.h1("My Todo List")
25+
html.ul(
26+
html.li("Build a cool new app"),
27+
html.li("Share it with the world!"),
28+
)
29+
)
30+
31+
Since we've captured our HTML into out the ``layout`` variable, we can inspect what it
32+
contains. And, as it turns out, it holds a dictionary. Printing it produces the
33+
following output:
34+
35+
.. testcode::
36+
37+
print(layout)
38+
39+
.. testoutput::
40+
:options: +NORMALIZE_WHITESPACE
41+
42+
{
43+
'tagName': 'div',
44+
'children': [
45+
{
46+
'tagName': 'h1',
47+
'children': ['My Todo List']
48+
},
49+
{
50+
'tagName': 'ul',
51+
'children': [
52+
{'tagName': 'li', 'children': ['Build a cool new app']},
53+
{'tagName': 'li', 'children': ['Share it with the world!']}
54+
]
55+
}
56+
]
57+
}
58+
59+
This may look complicated, but let's take a moment to consider what's going on here. We
60+
have a series of nested dictionaries that, in some way, represents the HTML structure
61+
given above. If we look at their contents we should see a common form. Each has a
62+
``tagName`` key which contains, as the name would suggest, the tag name of an HTML
63+
element. Then within the ``children`` key is a list that either contains strings or
64+
other dictionaries that represent HTML elements.
65+
66+
What we're seeing here is called a "virtual document object model" or :ref:`VDOM`. This
67+
is just a fancy way of saying we have a representation of the document object model or
68+
`DOM
69+
<https://en.wikipedia.org/wiki/Document_Object_Model#:~:text=The%20Document%20Object%20Model%20(DOM,document%20with%20a%20logical%20tree.&text=Nodes%20can%20have%20event%20handlers%20attached%20to%20them.>`__
70+
that is not the actual DOM.
71+
72+
Under construction :)

src/idom/core/vdom.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,11 @@ def constructor(
222222

223223
# replicate common function attributes
224224
constructor.__name__ = tag
225-
constructor.__doc__ = f"Return a new ``<{tag}/>`` :class:`VdomDict` element"
225+
constructor.__doc__ = (
226+
"Return a new "
227+
f"`<{tag}> <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/{tag}>`__ "
228+
"element represented by a :class:`VdomDict`."
229+
)
226230

227231
frame = inspect.currentframe()
228232
if frame is not None and frame.f_back is not None and frame.f_back is not None:

0 commit comments

Comments
 (0)