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> | |
| ``` | |