summaryrefslogtreecommitdiffstats
path: root/docs/content/guide/index.md
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--docs/content/guide/index.md196
1 files changed, 196 insertions, 0 deletions
diff --git a/docs/content/guide/index.md b/docs/content/guide/index.md
new file mode 100644
index 0000000..0c092ea
--- /dev/null
+++ b/docs/content/guide/index.md
@@ -0,0 +1,196 @@
+---
+title: Introduction
+---
+
+<Header title="Introduction">
+JinjaX is a Python library for creating reusable "components": encapsulated template snippets that can take arguments and render to HTML. They are similar to React or Vue components, but they render on the server side, not in the browser.
+</Header>
+
+Unlike Jinja's `{% include "..." %}` or macros, JinjaX components integrate naturally with the rest of your template code.
+
+```html+jinja
+<div>
+ <Card class="bg-gray">
+ <h1>Products</h1>
+ {% for product in products %}
+ <Product product={{ product }} />
+ {% endfor %}
+ </Card>
+</div>
+```
+
+## Features
+
+### Simple
+
+JinjaX components are simple Jinja templates. You use them as if they were HTML tags without having to import them: easy to use and easy to read.
+
+### Encapsulated
+
+They are independent of each other and can link to their own CSS and JS, so you can freely copy and paste components between applications.
+
+### Testable
+
+All components can be unit tested independently of the pages where they are used.
+
+### Composable
+
+A JinjaX component can wrap HTML code or other components with a natural syntax, as if they were another tag.
+
+### Modern
+
+They are a great complement to technologies like [TailwindCSS](https://tailwindcss.com/), [htmx](https://htmx.org/), or [Hotwire](https://hotwired.dev/).
+
+## Usage
+
+#### Install
+
+Install the library using `pip`.
+
+```bash
+pip install jinjax
+```
+
+#### Components folder
+
+Then, create a folder that will contain your components, for example:
+
+```
+└ myapp/
+ ├── app.py
+ ├── components/ 🆕
+ │ └── Card.jinja 🆕
+ ├── static/
+ ├── templates/
+ └── views/
+└─ requirements.txt
+```
+
+#### Catalog
+
+Finally, you must create a "catalog" of components in your app. This is the object that manages the components and their global settings. You then add the path of the folder with your components to the catalog:
+
+```python
+from jinjax import Catalog
+
+catalog = Catalog()
+catalog.add_folder("myapp/components")
+```
+
+#### Render
+
+You will use the catalog to render components from your views.
+
+```python
+def myview():
+ ...
+ return catalog.render(
+ "Page",
+ title="Lorem ipsum",
+ message="Hello",
+ )
+```
+
+In this example, it is a component for the whole page, but you can also render smaller components, even from inside a regular Jinja template if you add the catalog as a global:
+
+```python
+app.jinja_env.globals["catalog"] = catalog
+```
+
+```html+jinja
+{% block content %}
+<div>
+ {{ catalog.irender("LikeButton", title="Like and subscribe!", post=post) }}
+</div>
+<p>Lorem ipsum</p>
+{{ catalog.irender("CommentForm", post=post) }}
+{% endblock %}
+```
+
+## How It Works
+
+JinjaX uses Jinja to render the component templates. In fact, it currently works as a pre-processor, replacing all:
+
+```html
+<Component attr="value">content</Component>
+```
+
+with function calls like:
+
+```html+jinja
+{% call catalog.irender("Component", attr="value") %}content{% endcall %}
+```
+
+These calls are evaluated at render time. Each call loads the source of the component file, parses it to extract the names of CSS/JS files, required and/or optional attributes, pre-processes the template (replacing components with function calls, as before), and finally renders the new template.
+
+### Reusing Jinja's Globals, Filters, and Tests
+
+You can add your own global variables and functions, filters, tests, and Jinja extensions when creating the catalog:
+
+```python
+from jinjax import Catalog
+
+catalog = Catalog(
+ globals={ ... },
+ filters={ ... },
+ tests={ ... },
+ extensions=[ ... ],
+)
+```
+
+or afterward.
+
+```python
+catalog.jinja_env.globals.update({ ... })
+catalog.jinja_env.filters.update({ ... })
+catalog.jinja_env.tests.update({ ... })
+catalog.jinja_env.extensions.extend([ ... ])
+```
+
+The ["do" extension](https://jinja.palletsprojects.com/en/3.0.x/extensions/#expression-statement) is enabled by default, so you can write things like:
+
+```html+jinja
+{% do attrs.set(class="btn", disabled=True) %}
+```
+
+### Reusing an Existing Jinja Environment
+
+You can also reuse an existing Jinja Environment, for example:
+
+#### Flask:
+
+```python
+app = Flask(__name__)
+
+# Here we add the Flask Jinja globals, filters, etc., like `url_for()`
+catalog = jinjax.Catalog(jinja_env=app.jinja_env)
+```
+
+#### Django:
+
+First, configure Jinja in `settings.py` and [jinja_env.py](https://docs.djangoproject.com/en/5.0/topics/templates/#django.template.backends.jinja2.Jinja2).
+
+To have a separate "components" folder for shared components and also have "components" subfolders at each Django app level:
+
+```python
+import jinjax
+from jinja2.loaders import FileSystemLoader
+
+def environment(loader: FileSystemLoader, **options):
+ env = Environment(loader=loader, **options)
+
+ ...
+
+ env.add_extension(jinjax.JinjaX)
+ catalog = jinjax.Catalog(jinja_env=env)
+
+ catalog.add_folder("components")
+ for dir in loader.searchpath:
+ catalog.add_folder(os.path.join(dir, "components"))
+
+ return env
+```
+
+#### FastAPI:
+
+TBD \ No newline at end of file