Spaces:
Sleeping
Sleeping
# Custom Components | |
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! --> | |
The majority of the time the default [ft | |
components](../explains/explaining_xt_components.html) are all you need | |
(for example `Div`, `P`, `H1`, etc.). | |
<div> | |
> **Pre-requisite Knowledge** | |
> | |
> If you don’t know what an ft component is, you should read [the | |
> explaining ft components explainer | |
> first](../explains/explaining_xt_components.html). | |
</div> | |
However, there are many situations where you need a custom ft component | |
that creates a unique HTML tag (for example `<zero-md></zero-md>`). | |
There are many options in FastHTML to do this, and this section will | |
walk through them. Generally you want to use the highest level option | |
that fits your needs. | |
<div> | |
> **Real-world example** | |
> | |
> [This external | |
> tutorial](https://isaac-flath.github.io/website/posts/boots/FasthtmlTutorial.html) | |
> walks through a practical situation where you may want to create a | |
> custom HTML tag using a custom ft component. Seeing a real-world | |
> example is a good way to understand why the contents of this guide is | |
> useful. | |
</div> | |
## NotStr | |
The first way is to use the `NotStr` class to use an HTML tag as a | |
string. It works as a one-off but quickly becomes harder to work with as | |
complexity grows. However we can see that you can genenrate the same xml | |
using `NotStr` as the out-of-the-box components. | |
``` python | |
from fasthtml.common import NotStr,Div, to_xml | |
``` | |
``` python | |
div_NotStr = NotStr('<div></div>') | |
print(div_NotStr) | |
``` | |
<div></div> | |
## Automatic Creation | |
The next (and better) approach is to let FastHTML generate the component | |
function for you. As you can see in our `assert` this creates a function | |
that creates the HTML just as we wanted. This works even though there is | |
not a `Some_never_before_used_tag` function in the `fasthtml.components` | |
source code (you can verify this yourself by looking at the source | |
code). | |
<div> | |
> **Tip** | |
> | |
> Typically these tags are needed because a CSS or Javascript library | |
> created a new XML tag that isn’t default HTML. For example the | |
> `zero-md` javascript library looks for a `<zero-md></zero-md>` tag to | |
> know what to run its javascript code on. Most CSS libraries work by | |
> creating styling based on the `class` attribute, but they can also | |
> apply styling to an arbitrary HTML tag that they made up. | |
</div> | |
``` python | |
from fasthtml.components import Some_never_before_used_tag | |
Some_never_before_used_tag() | |
``` | |
``` html | |
<some-never-before-used-tag></some-never-before-used-tag> | |
``` | |
## Manual Creation | |
The automatic creation isn’t magic. It’s just calling a python function | |
[`__getattr__`](https://www.fastht.ml/docs/api/components.html#__getattr__) | |
and you can call it yourself to get the same result. | |
``` python | |
import fasthtml | |
auto_called = fasthtml.components.Some_never_before_used_tag() | |
manual_called = fasthtml.components.__getattr__('Some_never_before_used_tag')() | |
# Proving they generate the same xml | |
assert to_xml(auto_called) == to_xml(manual_called) | |
``` | |
Knowing that, we know that it’s possible to create a different function | |
that has different behavior than FastHTMLs default behavior by modifying | |
how the `___getattr__` function creates the components! It’s only a few | |
lines of code and reading that what it does is a great way to understand | |
components more deeply. | |
<div> | |
> **Tip** | |
> | |
> Dunder methods and functions are special functions that have double | |
> underscores at the beginning and end of their name. They are called at | |
> specific times in python so you can use them to cause customized | |
> behavior that makes sense for your specific use case. They can appear | |
> magical if you don’t know how python works, but they are extremely | |
> commonly used to modify python’s default behavior (`__init__` is | |
> probably the most common one). | |
> | |
> In a module | |
> [`__getattr__`](https://www.fastht.ml/docs/api/components.html#__getattr__) | |
> is called to get an attribute. In `fasthtml.components`, this is | |
> defined to create components automatically for you. | |
</div> | |
For example if you want a component that creates `<path></path>` that | |
doesn’t conflict names with | |
[`pathlib.Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path) | |
you can do that. FastHTML automatically creates new components with a | |
1:1 mapping and a consistent name, which is almost always what you want. | |
But in some cases you may want to customize that and you can use the | |
[`ft_hx`](https://www.fastht.ml/docs/api/components.html#ft_hx) function | |
to do that differently than the default. | |
``` python | |
from fasthtml.common import ft_hx | |
def ft_path(*c, target_id=None, **kwargs): | |
return ft_hx('path', *c, target_id=target_id, **kwargs) | |
ft_path() | |
``` | |
``` html | |
<path></path> | |
``` | |
We can add any behavior in that function that we need to, so let’s go | |
through some progressively complex examples that you may need in some of | |
your projects. | |
### Underscores in tags | |
Now that we understand how FastHTML generates components, we can create | |
our own in all kinds of ways. For example, maybe we need a weird HTML | |
tag that uses underscores. FastHTML replaces `_` with `-` in tags | |
because underscores in tags are highly unusual and rarely what you want, | |
though it does come up rarely. | |
``` python | |
def tag_with_underscores(*c, target_id=None, **kwargs): | |
return ft_hx('tag_with_underscores', *c, target_id=target_id, **kwargs) | |
tag_with_underscores() | |
``` | |
``` html | |
<tag_with_underscores></tag_with_underscores> | |
``` | |
### Symbols (ie @) in tags | |
Sometimes you may need to use a tag that uses characters that are not | |
allowed in function names in python (again, very unusual). | |
``` python | |
def tag_with_AtSymbol(*c, target_id=None, **kwargs): | |
return ft_hx('tag-with-@symbol', *c, target_id=target_id, **kwargs) | |
tag_with_AtSymbol() | |
``` | |
``` html | |
<tag-with-@symbol></tag-with-@symbol> | |
``` | |
### Symbols (ie @) in tag attributes | |
It also may be that an argument in an HTML tag uses characters that | |
can’t be used in python arguments. To handle these you can define those | |
args using a dictionary. | |
``` python | |
Div(normal_arg='normal stuff',**{'notNormal:arg:with_varing@symbols!':'123'}) | |
``` | |
``` html | |
<div normal-arg="normal stuff" notnormal:arg:with_varing@symbols!="123"></div> | |
``` | |